Pack the unit sprites into sheets instead of 2,816 files - #229
Draft
Giszmo wants to merge 4 commits into
Draft
Conversation
Sprite::load probed <name><i>.png and <name><i>r.png until both were missing, so the 32-pose set had to ship one file per pose and layer. It now reads an optional <name>.sheet index first — one line per sheet giving the layer, first frame, frame count and tile size — and cuts the tiles out of the packed PNGs itself. Sprites without an index still load frame by frame, so every other sprite and any modded data directory is unaffected. render.py install packs the staged frames into eleven sheets and writes the index. The tiles are byte-identical to the frames they replace: 3,230,920 bytes in 2,816 files become 2,599,736 in 11, and 11.0 MiB of allocated ext4 blocks become 2.5 MiB, because a single deflate window covers a whole animation and the frames stop rounding up to a block each. Decoded surfaces and the composite cache are unchanged. data/gfx/SConscript packed and installed only names containing ".png", which would have dropped the index from dist tarballs and scons install. Opus 5 helped authoring this commit.
genixpro
force-pushed
the
codex/unit-animation-32-frames
branch
2 times, most recently
from
September 9, 2026 22:48
271a316 to
22534a7
Compare
Giszmo
marked this pull request as draft
September 10, 2026 19:10
Contributor
Author
|
This is a chore we can do at some point. It's worth it but the target is moving, so ... draft for now. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Builds on #201. Base branch is
codex/unit-animation-32-frames, so the diff below is only this change.#201 ships the 32-pose animation set as 2,816 PNGs because
Sprite::loadhad no other option: it probed<name><i>.png/<name><i>r.pnguntil both were missing, so one file per pose and layer was the only layout the loader understood. This teaches the loader to read sheets and packs the set into eleven of them.Format
data/gfx/unit.sheetsits next to the sheets and names them:Sprite::loadreads<name>.sheetwhen it exists and cuts the tiles itself; otherwise it falls back to the per-frame loop unchanged. Terrain, buildings, GUI sprites and any modded data directory keep working exactly as before. Eleven sheets rather than seven because the sets have three different tile sizes (explorer 32, worker 38, warrior 40) and the shadow pass is a separate layer.Cost
The byte saving is one deflate window covering a whole 256-pose animation instead of 256 separate streams. The allocation saving is the median 1.1 KB frame no longer rounding up to a 4 KB block.
Decoded surfaces are unchanged — still 15.9 MiB of source surfaces plus the per-team-colour recolor clones — and the composite cache is untouched. This is a disk-and-startup change, not a memory one.
Validation
UnitCompositeCacheTestreports identical numbers loading from sheets and from the per-frame files:mean=5.37923 max=10,bytes=76099904 entries=13172. Same forUnitMotionBlurTest.test/UnitSpriteSheetCheck.cpp(scons unit-blur-tests): cuts synthetic sheets of known pixels and checks each pixel, checks mixed tile sizes and layer offsets, checks the per-frame fallback still loads when no index exists, checks a sheet too small for its index is rejected rather than half-loaded, and checks the shipped set's 1,792 frames, layers and tile sizes. Inverting the row/column term in the loader makes it fail.test_render.pygains a pack round-trip over the full frame set; inverting the row/column term in the packer makes it fail. All 5 pass.test/TestsRunner: OK (172 tests).glob2 -test-gamesunder Xvfb for 90 s: units render, recolor and cast shadows as before.One fix outside the loader
data/gfx/SConscriptpacked and installed only filenames containing.png, sounit.sheetwould have been silently dropped from dist tarballs andscons install— and an installed game would then have found neither an index nor per-frame files. Verified withscons INSTALLDIR=… install.🤖 Generated with Claude Code