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>
The packs total 3.9GB, almost all of it Helton Yan's SFX shipped as 24-bit /
96kHz studio masters -- ~2MB for a single gunshot. Two guards, because they
solve different problems:
- .gitignore excludes the contents. The directory and its guard files stay
tracked, so a fresh clone has the .gdignore in place before anyone drops
packs back in.
- assetpacks/.gdignore stops Godot descending into the tree at all. This is the
urgent half: tools/check.sh runs --import, which walks all of res://, so the
next check would have imported several thousand PNGs and 2,100 of those WAVs,
and every run after it. Verified by controlled test rather than assumed -- an
unguarded PNG under res:// imports and gets a .import file beside it; with
.gdignore neither happens. check.sh stays at 3.3s and .godot/imported at
1.2MB.
The trade the .gdignore buys is that nothing in assetpacks/ can be referenced
from a scene or script. That is the intended shape: raw source on one side,
game-ready files copied into res://assets/ on the other, so adding a huge pack
costs the repo and the import step nothing.
docs/ASSETS.md records attribution, because gitignoring the packs also
gitignores their licence files. Worth flagging: four of the six packs shipped
with no licence text at all, and two of the undecided ones are demo versions,
which are often more restricted than the paid packs. Only RF Catacombs has
explicit terms (public domain, no resale). Those rows need a source URL before
anything ships.
Also removed __MACOSX and .DS_Store extraction artefacts, and left
considering_dont_use_yet/ untouched as the user's own "not chosen" marker.