Rework the UI on Crusenho's pack; credit it in the game, not just the repo
ci / verify (push) Successful in 48s
ci / verify (push) Successful in 48s
Crusenho's Complete UI Essential Pack is CC BY 4.0 -- redistributable and
commercial-friendly, confirmed from the License.txt the pack itself ships --
so unlike the two bdragon packs a subset is committed: twelve PNGs, 48 KB,
under assets/sprites/ui/. Only what is used, because each committed PNG costs
a Godot .import sidecar and a directory nothing references is one nobody
prunes.
UiTheme builds a Theme in code from it -- button states, panels, line edits --
and every screen roots itself through UiTheme.themed_root(). The HUD's bars are
the pack's frame with a tinted fill, drawn as three horizontal slices because
Godot's nine-patch lives on nodes and the HUD is drawn rather than built from
controls. Inventory slots use the pack's slot art at exactly twice the source
size; a non-integer scale on a 1px border reads as a wobble along every edge.
The credits screen is the other half of the request and it is a licence
obligation, not a nicety: two packs are now CC BY, which asks for attribution
"in any reasonable manner", and a markdown file in a source repo is not
reasonable for someone who downloaded a build. Settings -> Credits shows every
source with its terms and a link to the licence text. test_credits.gd asserts
CREDITS.md and docs/ASSETS.md name every entry, so the three cannot drift.
Two things found by actually looking at the screen, which is the point:
- The FIRST version of this styled nothing. A Control inherits its theme from
Control ANCESTORS only, and the chain breaks at the first plain Node or
CanvasLayer -- which is every screen here. get_window().theme set the
property, changed nothing, and read as correct. check.sh, 458 tests and a
clean smoke run all passed with the entire interface unstyled. The theme
test now instantiates every screen and asks what its buttons resolve.
- The settings screen showed Fire bound to the right mouse button, because
the test suite was writing the player's real user://settings.cfg --
rebinding calls save() and nothing had redirected the path. Settings.path
is now redirectable, the fixture points it at a scratch file, and a test
asserts the default is still the player's own.
tools/screenshot.tscn is what found both. It boots the client windowed and
saves the menus, the HUD, settings and credits. Manual, needs a display, and
the only thing in the project that can tell you the interface rendered.
check.sh clean, 460 tests, SMOKE PASS, all four diagnostics green.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+29
-9
@@ -12,22 +12,24 @@ can be referenced from a scene or script. Files are copied into `res://assets/`
|
||||
in game-ready form, and only then imported. The tree is 3.9 GB and
|
||||
`tools/check.sh` runs `--import`, which would otherwise walk all of it every run.
|
||||
|
||||
What is in the game today totals **548 KB** across seven files: three sprite
|
||||
sheets and four sounds. Sprite rects and sound paths are all declared in one
|
||||
What is in the game today is three sprite sheets, four sounds and twelve small
|
||||
UI sprites. Sprite rects and sound paths are all declared in one
|
||||
place, [src/view/art.gd](../src/view/art.gd), and
|
||||
`tests/unit/test_art.gd` asserts every rect lands inside its texture — a wrong
|
||||
atlas coordinate does not error, it silently draws the wrong pixels.
|
||||
|
||||
## Licence findings
|
||||
|
||||
Checked against each pack's itch.io page. **Two of the four forbid
|
||||
redistribution**, which is what publishing a repository containing them would
|
||||
be — so they are not in the repository.
|
||||
Checked against each pack's itch.io page, and against the licence file the pack
|
||||
itself ships where there is one. **Two of the five forbid redistribution**,
|
||||
which is what publishing a repository containing them would be — so they are not
|
||||
in the repository.
|
||||
|
||||
| Pack | Licence | Commercial | Credit | In this repo? |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| [0x72 DungeonTileset II](https://0x72.itch.io/dungeontileset-ii) | **CC0 1.0** (public domain) | Yes | Not required | **Yes** — `assets/sprites/dungeon_tileset.png` |
|
||||
| [Helton Yan Pixel Combat](https://heltonyan.itch.io/pixelcombat) | **CC BY 4.0** | Yes | **Required** | **Yes** — `assets/audio/sfx/` |
|
||||
| [Complete UI Essential Pack](https://crusenho.itch.io/complete-ui-essential-pack) | **CC BY 4.0** | Yes | **Required** | **Yes** — `assets/sprites/ui/` |
|
||||
| [Fire Pixel Bullet 16x16](https://bdragon1727.itch.io/fire-pixel-bullet-16x16) | Custom | Free tier non-commercial; **paid tier allows commercial** | Encouraged | **No, at any tier** — local only |
|
||||
| [750+ Effect and FX Pixel All](https://bdragon1727.itch.io/750-effect-and-fx-pixel-all) | Custom | Free tier non-commercial; **paid tier allows commercial** | Encouraged | **No, at any tier** — local only |
|
||||
|
||||
@@ -56,12 +58,30 @@ passes 156/156 and the game runs.
|
||||
This is also why nothing there may be `preload()`ed — `preload` resolves at
|
||||
compile time and would fail the build on every machine that lacks the files.
|
||||
|
||||
### The UI pack is the easy case
|
||||
|
||||
Crusenho's *Complete UI Essential Pack* ships its own `License.txt` naming
|
||||
CC BY 4.0 outright, with the licensor and store link spelled out. That permits
|
||||
redistribution and commercial use, so unlike the bullet and FX packs a subset of
|
||||
it is committed — twelve PNGs, 48 KB, under `assets/sprites/ui/`, listed in
|
||||
`UiTheme.TEXTURES`.
|
||||
|
||||
Only what the game uses was copied rather than all 98 sprites: each committed
|
||||
PNG costs a Godot `.import` sidecar, and a directory of files nothing references
|
||||
is a directory nobody prunes. The rest stays in the untracked pack.
|
||||
|
||||
The obligation it creates is the same one the audio creates — see below.
|
||||
|
||||
### Two obligations this creates
|
||||
|
||||
1. **Helton Yan's CC BY 4.0 requires attribution**, and it is not satisfied by
|
||||
a file in the source tree once the game ships. Players need to be able to
|
||||
see it. [CREDITS.md](../CREDITS.md) records it for now; an in-game credits
|
||||
screen is a todo.
|
||||
1. **Two packs are CC BY 4.0 and require attribution** — Helton Yan's audio and
|
||||
Crusenho's UI art. A file in the source tree does not satisfy that once the
|
||||
game ships, because a player who downloaded a build never sees it. **Done:**
|
||||
Settings → Credits shows the same list, built from
|
||||
[src/core/credits.gd](../src/core/credits.gd), including a link to the
|
||||
licence text as CC BY asks. `tests/unit/test_credits.gd` asserts every source
|
||||
there also appears in [CREDITS.md](../CREDITS.md) and in this file, so the
|
||||
three cannot drift apart.
|
||||
2. **Both bdragon packs are non-commercial in their free tier.** Buying the
|
||||
full tier *does* fix that — confirmed verbatim from the FX pack's paid
|
||||
licence: "You may use these assets in personal, commercial or
|
||||
|
||||
+8
-2
@@ -20,13 +20,17 @@ What "everything passes" currently means. Numbers move; the shape does not.
|
||||
| Gate | Covers | Runtime |
|
||||
| --- | --- | --- |
|
||||
| `tools/check.sh` | every script parses and type-checks | ~5s |
|
||||
| `tools/test.sh` | 439 GUT tests, no SceneTree | ~4s |
|
||||
| `tools/test.sh` | 460 GUT tests, no SceneTree | ~4s |
|
||||
| `tools/smoke.sh` | 23 assertions over a real ENet socket: handshake, auth, character creation and persistence, both dungeon kinds, escape, hard kill, polite disconnect | ~40s |
|
||||
| `diag_prediction.tscn` | client-prediction gap, with injected clock drift | ~10s |
|
||||
| `diag_progression.tscn` | kill → xp → level → health, death → retire → roster, swap guards | ~10s |
|
||||
| `diag_loot.tscn` | drop → snapshot → pick up → persist → use → drop, and both loot visibilities on the wire | ~10s |
|
||||
| `diag_upgrades.tscn` | level → banked choice → refused in a dungeon and away from the NPC → taken → new stats → persisted → **survives every zone change** | ~10s |
|
||||
|
||||
`tools/screenshot.tscn` is a **manual** check, not a gate: it needs a display,
|
||||
and it is the only thing in the project that can tell you the interface
|
||||
actually rendered. Run it after touching `src/ui/`.
|
||||
|
||||
The four diagnostics exist because the smoke test structurally cannot reach
|
||||
what they cover: bots are poor shots (so they neither level up, produce drops,
|
||||
nor walk to the quartermaster), and a listen server cannot drift its own clock
|
||||
@@ -129,8 +133,10 @@ play off server events. Enough to prove the pipeline, not a finished look.
|
||||
| Impact/death VFX animation | todo | `Art.IMPACT` is loaded and validated but nothing plays it yet |
|
||||
| Directional sprites, hit flashes, screen shake | todo | |
|
||||
| Rebindable controls | done | [src/ui/settings_screen.gd](../src/ui/settings_screen.gd), [src/core/settings.gd](../src/core/settings.gd) |
|
||||
| Themed controls from a UI pack | done | [src/view/ui_theme.gd](../src/view/ui_theme.gd), art in `assets/sprites/ui/` |
|
||||
| Textured HUD bars and inventory slots | done | `HUD._bar`, `HUD._draw_inventory` |
|
||||
| Audio buses and a volume setting | done | `Settings`, an SFX bus created at runtime, sliders in the settings screen |
|
||||
| **In-game credits screen** | **todo** | Not cosmetic: the SFX are CC BY 4.0 and attribution is a licence *requirement*. [CREDITS.md](../CREDITS.md) is not reachable by a player. |
|
||||
| **In-game credits screen** | **done** | Settings → Credits, from [src/core/credits.gd](../src/core/credits.gd). Two packs are CC BY 4.0 and attribution is a licence *requirement* — [CREDITS.md](../CREDITS.md) is not reachable by a player. |
|
||||
| Replace the two non-redistributable packs | todo | Bullet and FX art is local-only and non-commercial. CC0 replacements would let them into the repo and unblock a commercial release. See [ASSETS.md](ASSETS.md). |
|
||||
|
||||
## Stage 2 — Characters, persistence, levels · *done*
|
||||
|
||||
@@ -251,3 +251,24 @@ the output, which is worth doing after any change to startup.
|
||||
`smoke.sh` now asserts no plain engine errors either, excluding by name the one
|
||||
line Godot prints on every clean exit — naming it means anything else that turns
|
||||
up is a real finding rather than noise to be squinted past.
|
||||
|
||||
### Nothing automated can see the screen
|
||||
|
||||
Every gate passed — 458 tests, a clean smoke run, no engine errors — while the
|
||||
entire interface rendered in Godot's default style and none of the UI pack was
|
||||
visible. A Control inherits its theme from Control *ancestors only*, and the
|
||||
chain breaks at the first plain `Node` or `CanvasLayer`; every screen in this
|
||||
game hangs off one. `get_window().theme = ...` set the property, changed
|
||||
nothing, and looked correct in the code.
|
||||
|
||||
It took `tools/screenshot.tscn` — boot the client, save a PNG, open it — to
|
||||
find. The same run then showed **Fire bound to the right mouse button**, which
|
||||
was the test suite writing the player's real `user://settings.cfg`, because
|
||||
rebinding calls `save()` and nothing had redirected the path.
|
||||
|
||||
Two lessons, and the second is the general one:
|
||||
|
||||
- After touching `src/ui/`, look at it. There is no substitute.
|
||||
- A test that exercises a code path which writes to user state **will write to
|
||||
user state**. Redirect the path in the fixture, and assert the default is
|
||||
still the real one so the redirect cannot escape.
|
||||
|
||||
Reference in New Issue
Block a user