Compare commits

...

8 Commits

Author SHA1 Message Date
hans 399a4f2ca8 Fixed link in changelog
Release / release (push) Successful in 52s
Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
2026-08-13 19:23:15 +02:00
hans 63f557b74e Updated changelog and bumped version to 1.8.3
Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
2026-08-13 19:19:42 +02:00
MrPingu07 80933ad1e3 feat(VoxelGrid): add BTL-OFF rung to V-GRID setting
V-GRID now cycles OFF / ON / BTL-OFF.
BTL-OFF keeps the wireframe off during battles while leaving it
available in the overworld. ON preserves the original behaviour
(wireframe forced on in battles regardless of the row).
2026-08-13 19:15:52 +02:00
hans 1fa3f4f855 Convert release action to Gitea
Release / release (push) Successful in 2m8s
Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
2026-08-13 19:05:22 +02:00
DramaticShape a7cbfc8b70 Merge pull request #149 from DramaticShape/1.8.1
1.8.1
2026-08-09 00:08:10 -04:00
DramaticShape 0a48f764f6 Merge pull request #145 from luisgonzaleznf/fix/scene-shader-precision-love12
fix: scene shader under LÖVE 12 — qualify fireflyNight's precision
2026-08-08 21:54:13 -04:00
DramaticShape bed08c6c44 Merge pull request #146 from DramaticShape/1.8.1
1.8.1
2026-08-08 19:58:33 -04:00
luisgonzaleznf 2a924ea8a3 fix scene shader under LOVE 12: qualify fireflyNight's precision
An unqualified float uniform takes each stage's default precision, and
those differ -- highp in the vertex stage, mediump in the fragment one.
LOVE 11 linked the pair regardless; LOVE 12 requires both declarations to
carry the same qualifier and refuses the shader:

  Cannot compile shader: ERROR: Linking fragment stage: Precision
  qualifiers must match: vertex stage: fireflyNight "" fragment stage:
  fireflyNight ""

Voxel3D.available() is 'the scene shader compiled', so the refusal takes
the whole 3D pass with it and the overworld silently falls back to flat
2D.  That is the current state on iOS, whose shell ships LOVE 12, and it
is latent for every other platform that moves to 12.

Uses LOVE_HIGHP_OR_MEDIUMP, the same macro vWorld and vGrid already carry.
2026-08-09 01:48:05 +02:00
8 changed files with 119 additions and 44 deletions
@@ -1,6 +1,6 @@
name: Release name: Release
# Packs the mod into an installable .zip and publishes it as a GitHub Release, # Packs the mod into an installable .zip and publishes it as a Gitea Release,
# once per push to main. # once per push to main.
# #
# Archive layout: every mod file at the archive root, manifest.json included. # Archive layout: every mod file at the archive root, manifest.json included.
@@ -24,10 +24,10 @@ name: Release
on: on:
push: push:
branches: [master] branches: [master, dev]
paths-ignore: paths-ignore:
- '.github/**' - ".gitea/**"
- '**.md' - "**.md"
workflow_dispatch: workflow_dispatch:
inputs: inputs:
version: version:
@@ -113,7 +113,7 @@ jobs:
- name: Refuse to clobber an existing release - name: Refuse to clobber an existing release
env: env:
GH_TOKEN: ${{ github.token }} GITEA_TOKEN: ${{ github.token }}
TAG: ${{ steps.ver.outputs.tag }} TAG: ${{ steps.ver.outputs.tag }}
run: | run: |
set -euo pipefail set -euo pipefail
@@ -121,7 +121,13 @@ jobs:
echo "::error::Tag $TAG already exists. Pick a different version." echo "::error::Tag $TAG already exists. Pick a different version."
exit 1 exit 1
fi fi
if gh release view "$TAG" >/dev/null 2>&1; then
# Replaced `gh release view` with a direct HTTP check to the Gitea API
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
-H "Authorization: token $GITEA_TOKEN" \
"$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/releases/tags/$TAG")
if [ "$HTTP_STATUS" -eq 200 ]; then
echo "::error::Release $TAG already exists. Pick a different version." echo "::error::Release $TAG already exists. Pick a different version."
exit 1 exit 1
fi fi
@@ -164,16 +170,16 @@ jobs:
with open(path, encoding="utf-8") as fh: with open(path, encoding="utf-8") as fh:
version = json.load(fh)["version"] version = json.load(fh)["version"]
if version != expected: if version != expected:
raise SystemExit(f"::error::packed manifest says {version}, expected {expected}") raise SystemExit(f":error::packed manifest says {version}, expected {expected}")
print(f"manifest.json is at the archive root and reports {version}") print(f"manifest.json is at the archive root and reports {version}")
PY PY
(cd "$out" && sha256sum "${MOD_ID}"-*.zip > sha256sums.txt) (cd "$out" && sha256sum "${MOD_ID}"-*.zip > sha256sums.txt)
cat "$out/sha256sums.txt" cat "$out/sha256sums.txt"
- name: Publish GitHub Release - name: Publish Gitea Release
env: env:
GH_TOKEN: ${{ github.token }} GITEA_TOKEN: ${{ github.token }}
VERSION: ${{ steps.ver.outputs.version }} VERSION: ${{ steps.ver.outputs.version }}
TAG: ${{ steps.ver.outputs.tag }} TAG: ${{ steps.ver.outputs.tag }}
MOD_ID: "DRAMATIC_SHAPE" MOD_ID: "DRAMATIC_SHAPE"
@@ -190,11 +196,34 @@ jobs:
fi fi
printf 'Release notes:\n%s\n' "$notes" printf 'Release notes:\n%s\n' "$notes"
gh release create "$TAG" \ # Create the release via Gitea's REST API
--target "$GITHUB_SHA" \ RESPONSE=$(curl -s -X POST "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/releases" \
--title "$VERSION" \ -H "Authorization: token $GITEA_TOKEN" \
--notes "$notes" \ -H "Content-Type: application/json" \
"dist/${MOD_ID}-${VERSION}.zip" \ -d "$(jq -n \
"dist/sha256sums.txt" --arg tag "$TAG" \
--arg target "$GITHUB_SHA" \
--arg name "$VERSION" \
--arg body "$notes" \
'{tag_name: $tag, target_commitish: $target, name: $name, body: $body}')"
)
# Extract the numeric release ID needed to upload assets
RELEASE_ID=$(echo "$RESPONSE" | jq -r '.id')
if [ "$RELEASE_ID" = "null" ] || [ -z "$RELEASE_ID" ]; then
echo "::error::Failed to create release. Gitea responded with: $RESPONSE"
exit 1
fi
# Upload the Mod .zip asset to the newly created release
curl -s -f -X POST "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/releases/$RELEASE_ID/assets" \
-H "Authorization: token $GITEA_TOKEN" \
-F "attachment=@dist/${MOD_ID}-${VERSION}.zip"
# Upload the sha256sums.txt file
curl -s -f -X POST "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/releases/$RELEASE_ID/assets" \
-H "Authorization: token $GITEA_TOKEN" \
-F "attachment=@dist/sha256sums.txt"
echo "Published release $TAG" echo "Published release $TAG"
+31 -5
View File
@@ -1,6 +1,33 @@
# Changelog # Changelog
## Unreleased ## 1.8.3
### Merged PRs
- Merged [feat(VoxelGrid): add BTL-OFF rung to V-GRID setting](https://github.com/TeJota1337/DramaticShapeVoxelMod/pull/1)
```md
V-GRID now cycles OFF / ON / BTL-OFF.
ON preserves the original behaviour: the wireframe is forced on during
battles regardless of what the row is set to, because the seams are what
make the arena read as constructed rather than photographed.
BTL-OFF is an opt-out for players who prefer a cleaner battle scene:
the wireframe stays available in the overworld but is not forced during
battles. The override mechanism is unchanged -- the player's stored
setting is never written to during a fight.
Changes:
lib/VoxelGrid.lua: third rung added to the ladder; enabled()
handles "btloff" explicitly; battleForced() added; sync()
no longer coerces to boolean.
lib/BattleScene.lua: override is only set when battleForced()
returns true.
main.lua: help text updated.
README.md: controls table updated.
```
### Added ### Added
@@ -624,7 +651,7 @@
as one ladder -- WHAT is standing there, and WHERE: as one ladder -- WHAT is standing there, and WHERE:
| | on the MAP | on two DISCS | | | on the MAP | on two DISCS |
| ---------- | ----------- | ------------ | | ---------- | ---------- | ------------ |
| **pics** | 2D-3D A | 2D-3D B | | **pics** | 2D-3D A | 2D-3D B |
| **models** | STADIUM A | STADIUM B | | **models** | STADIUM A | STADIUM B |
@@ -811,7 +838,7 @@
What it found, and what happened to each: What it found, and what happened to each:
| finding | count | outcome | | finding | count | outcome |
| --- | --- | --- | | -------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| pack cache evicted a model still on the field | 2 | **fixed** -- see above | | pack cache evicted a model still on the field | 2 | **fixed** -- see above |
| animation walks the Pokemon off its tile | 65 entrances, 36 hits, 35 faints | **fixed** -- see above | | animation walks the Pokemon off its tile | 65 entrances, 36 hits, 35 faints | **fixed** -- see above |
| part has no texture | 104,728 | **not a defect.** 39 primitives across 37 species, 1.6% of the set's vertices, every one with all-zero UVs: they are flat-shaded geometry in the original. The pack stores texture indices one-based, so the packer's `0xFFFF` "untextured" sentinel arrives as 65,536 and resolves to nothing, which is correct. Counted rather than reported now | | part has no texture | 104,728 | **not a defect.** 39 primitives across 37 species, 1.6% of the set's vertices, every one with all-zero UVs: they are flat-shaded geometry in the original. The pack stores texture indices one-based, so the packer's `0xFFFF` "untextured" sentinel arrives as 65,536 and resolves to nothing, which is correct. Counted rather than reported now |
@@ -1999,7 +2026,6 @@
and only the player knows what their machine can carry. No hotkey, for the and only the player knows what their machine can carry. No hotkey, for the
same reason: it is set once, not flicked while walking. same reason: it is set once, not flicked while walking.
### Changed ### Changed
- **The water surface is its own mesh, and its own pass.** A mirror cannot be - **The water surface is its own mesh, and its own pass.** A mirror cannot be
@@ -3402,7 +3428,7 @@ long as the thing throwing them is tall.
one now have a hotkey at all: one now have a hotkey at all:
| key | control | | key | control |
| --- | --- | | --- | ------------------------- |
| 3 | VOXEL, the camera ladder | | 3 | VOXEL, the camera ladder |
| 5 | V-GRID, the wireframe | | 5 | V-GRID, the wireframe |
| 6 | T-SHIFT, the blur ladder | | 6 | T-SHIFT, the blur ladder |
+1 -1
View File
@@ -15,7 +15,7 @@ menu.
| --- | --- | | --- | --- |
| `3`, or the **VOXEL** options row | OFF → 15 → 35 → 50 → 75 → 1ST → 3RD → OFF (camera pitch) | | `3`, or the **VOXEL** options row | OFF → 15 → 35 → 50 → 75 → 1ST → 3RD → OFF (camera pitch) |
| `SELECT` (pad / touch) | the same step as `3` — for the machines with no number row | | `SELECT` (pad / touch) | the same step as `3` — for the machines with no number row |
| `5`, or the **V-GRID** options row | OFF / ON — a one-pixel wireframe on every voxel | | `5`, or the **V-GRID** options row | OFF / ON / BTL-OFF — a one-pixel wireframe on every voxel; BTL-OFF disables it during battles |
| `6`, or the **T-SHIFT** options row | OFF → 1 → 2 → 3 → OFF (miniature blur) | | `6`, or the **T-SHIFT** options row | OFF → 1 → 2 → 3 → OFF (miniature blur) |
| `7`, or the **V-CURVE** options row | OFF → 1 → 2 → 3 → 4 → 5 — bend the world over the horizon; 5 is a half sphere | | `7`, or the **V-CURVE** options row | OFF → 1 → 2 → 3 → 4 → 5 — bend the world over the horizon; 5 is a half sphere |
| the **RENDER DIST** options row | FIT / WIDE / WIDER / WIDEST / OFF — how much of the map the camera bothers to draw. **FIT** is exactly the ground on screen and no more: the trapezoid a tilted camera really frames, which reaches well north of you and flares wide out there — not the square the flat game shows. A connected map falling entirely outside it is skipped before it is drawn, terrain, water, grass and shadows together, which is most of the frame's geometry at the high rungs. Below about 63° that is all the row does and the picture is untouched; at **75** the camera sees to the horizon, so something has to name a distance — FIT is the closest, the wider rungs push the world's edge out, **OFF** stops cutting. Not on **1ST** or **3RD**: you are standing in the world there, and the box opens out and away as the camera dives in. **FULL** sets it to FIT | | the **RENDER DIST** options row | FIT / WIDE / WIDER / WIDEST / OFF — how much of the map the camera bothers to draw. **FIT** is exactly the ground on screen and no more: the trapezoid a tilted camera really frames, which reaches well north of you and flares wide out there — not the square the flat game shows. A connected map falling entirely outside it is skipped before it is drawn, terrain, water, grass and shadows together, which is most of the frame's geometry at the high rungs. Below about 63° that is all the row does and the picture is untouched; at **75** the camera sees to the horizon, so something has to name a distance — FIT is the closest, the wider rungs push the world's edge out, **OFF** stops cutting. Not on **1ST** or **3RD**: you are standing in the world there, and the box opens out and away as the camera dives in. **FULL** sets it to FIT |
+4
View File
@@ -643,6 +643,10 @@ function BattleScene.render(state, arena, textures, token)
-- the world (see VoxelGrid): the arena is drawn a unit per voxel like -- the world (see VoxelGrid): the arena is drawn a unit per voxel like
-- everything else, so the seams follow the one toggle and a player who -- everything else, so the seams follow the one toggle and a player who
-- turned them off does not get them back for the length of a fight. -- turned them off does not get them back for the length of a fight.
local gridWas = VoxelGrid.override
if VoxelGrid.battleForced() then
VoxelGrid.override = true
end
local out = nil local out = nil
local ok, err = pcall(function() local ok, err = pcall(function()
-- its own canvas slot: this renders at the window's pixel size and the -- its own canvas slot: this renders at the window's pixel size and the
+8 -1
View File
@@ -89,7 +89,14 @@ local SHADER = [[
varying vec3 vSun; // this fragment's place in the sun's view varying vec3 vSun; // this fragment's place in the sun's view
varying float vFog; // how deep into the map's haze it stands varying float vFog; // how deep into the map's haze it stands
varying float vFirefly; // zero normally, night glow on firefly cards varying float vFirefly; // zero normally, night glow on firefly cards
uniform float fireflyNight; // shared safely by vertex and pixel stages // Explicitly qualified, and it has to be: an unqualified float takes each
// STAGE's default precision, and those do not agree -- highp in the vertex
// stage, mediump in the fragment one. LOVE 11 linked the pair anyway;
// LOVE 12 holds both declarations to the same qualifier and refuses the
// whole shader over it, which costs the entire 3D pass -- Voxel3D.available()
// is a shader that compiled, and the overworld falls back to flat 2D with
// nothing said anywhere. Same macro the varyings below already use.
uniform LOVE_HIGHP_OR_MEDIUMP float fireflyNight;
#ifdef VOXEL_CULL #ifdef VOXEL_CULL
// where this fragment stands in the FLAT world, for the diorama's // where this fragment stands in the FLAT world, for the diorama's
// viewport to measure. Same precision reasoning as vGrid below: a // viewport to measure. Same precision reasoning as vGrid below: a
+10 -3
View File
@@ -59,7 +59,7 @@ end
-- where it persists and the rows that cycle it (see ModSetting) -- where it persists and the rows that cycle it (see ModSetting)
VoxelGrid.setting = ModSetting.new(VoxelGrid.KEY, VoxelGrid.LABEL, VoxelGrid.setting = ModSetting.new(VoxelGrid.KEY, VoxelGrid.LABEL,
{ false, true }, { "OFF", "ON" }) { false, true, "btloff" }, { "OFF", "ON", "BTL-OFF" })
-- The row is the whole answer, everywhere: free-roam and the battle arena -- The row is the whole answer, everywhere: free-roam and the battle arena
-- alike. The battle used to force the seams on regardless -- a fight is a -- alike. The battle used to force the seams on regardless -- a fight is a
@@ -68,7 +68,14 @@ VoxelGrid.setting = ModSetting.new(VoxelGrid.KEY, VoxelGrid.LABEL,
-- whole mod, and a mode that came back for every fight read as the row not -- whole mod, and a mode that came back for every fight read as the row not
-- working rather than as a deliberate framing. -- working rather than as a deliberate framing.
function VoxelGrid.enabled() function VoxelGrid.enabled()
return VoxelGrid.setting:get() and true or false if VoxelGrid.override ~= nil then return VoxelGrid.override end
local v = VoxelGrid.setting:get()
if v == "btloff" then return false end
return v and true or false
end
function VoxelGrid.battleForced()
return VoxelGrid.setting:get() ~= "btloff"
end end
function VoxelGrid.set(enabled, game) function VoxelGrid.set(enabled, game)
@@ -80,7 +87,7 @@ function VoxelGrid.toggle(game)
end end
function VoxelGrid.sync(value) function VoxelGrid.sync(value)
VoxelGrid.setting:sync(value and true or false) VoxelGrid.setting:sync(value)
end end
function VoxelGrid.row() function VoxelGrid.row()
+1 -1
View File
@@ -490,7 +490,7 @@ local SETTINGS = {
cat = SettingsMenu.ROOT, full = true }, cat = SettingsMenu.ROOT, full = true },
-- ------- 3D WORLD -- the diorama's own knobs, every one of them FULL's -- ------- 3D WORLD -- the diorama's own knobs, every one of them FULL's
{ VoxelGrid.setting, "One-pixel wireframe along every voxel edge.", { VoxelGrid.setting, "One-pixel wireframe along every voxel edge. BTL-OFF disables it during battles.",
cat = "world" }, cat = "world" },
{ WorldCurve.setting, { WorldCurve.setting,
"Bends the world down over the horizon, until a town sits on top of its " "Bends the world down over the horizon, until a town sits on top of its "
+4 -2
View File
@@ -1,7 +1,7 @@
{ {
"id": "DRAMATIC_SHAPE", "id": "DRAMATIC_SHAPE",
"name": "Dramatic Shape Voxel Mod", "name": "Dramatic Shape Voxel Mod",
"version": "1.8.2", "version": "1.8.3",
"api": 2, "api": 2,
"entry": "main.lua", "entry": "main.lua",
"profile": "content", "profile": "content",
@@ -10,7 +10,9 @@
"priority": 100, "priority": 100,
"dependencies": [], "dependencies": [],
"optional_dependencies": [], "optional_dependencies": [],
"conflicts": ["ds_fp_ceiling"], "conflicts": [
"ds_fp_ceiling"
],
"permissions": [ "permissions": [
"engine_internals" "engine_internals"
], ],