Release Atlas PNG and JSON as One Versioned Pair

When an atlas looks correct after a hard refresh but wrong for returning users, inspect the PNG and metadata as a pair. A new JSON rectangle can point into an old cached image, or old metadata can crop a new layout. Both requests may return successful responses. Publish a revision whose metadata names its matching image, validate that pair, and activate the revision only after both files are available.
Key Takeaways
- HTTP success is not proof that an image and its coordinates belong to the same build.
- Keep revision URLs immutable and change a small release pointer after validation.
- Retain the previous complete pair until clients no longer need it and rollback is safe.
Reproduce the mismatch intentionally
This fault-injection worksheet complements the existing sprite manifest revision guide. Use its manifest contract, then deliberately interrupt and mix revisions as described below. The output is a release acceptance record, not a second manifest format.
In a disposable asset set, make revision A with a red square in the left cell and a blue square in the right cell. Make revision B swap the cells and update its frame rectangles accordingly. The character key red must select red under either matching revision.
Now pair A's metadata with B's image. The crop can remain within image bounds yet select blue. A structural validator may accept every rectangle and a network check may report two 200 responses. The fixture demonstrates why neither check proves semantic agreement.
TexturePacker's data-file documentation describes metadata containing sprite sizes and texture coordinates. Those coordinates are meaningful relative to a particular texture layout. Treat the exported image and data as one release unit even when they travel as separate requests.
Give each release immutable names
For example, place the pair under an application-owned revision directory:
assets/hero/r17/hero.png
assets/hero/r17/hero.json
assets/hero/r18/hero.png
assets/hero/r18/hero.json
Configure r18/hero.json to reference its own matching image according to the loader's schema. Do not add an invented manifest field and expect an unmodified engine loader to understand it. A small application release record can name the metadata entry point separately.
If a loader resolves image references relative to the JSON URL, keep that relationship intact. If it uses an asset base URL, verify the resolved request in the real application. Moving files into directories without checking resolution can turn a cache repair into a missing-image failure.
MDN's caching guide explains versioned URLs and immutable-resource caching. Long cache lifetimes suit content that will not change at that URL. The mutable release pointer needs a different freshness policy. no-cache allows storage with revalidation; it is not another spelling of no-store.
RFC 8246 defines immutable for a response's freshness lifetime. It does not make related files a transaction or prevent an application from choosing a mismatched pair.
Validate before changing the pointer
Use a staging state that clients cannot select yet. Upload the complete new pair, then request both through the same public delivery path clients use. Confirm successful responses, image decoding, the expected dimensions and frame records, and the selected image URL.
Record a SHA-256 digest for each exact file in the release record. A digest comparison can detect a mismatched or altered body when the expected record is trusted. It does not, by itself, authenticate the publisher: an attacker able to replace both the bytes and the expected hashes defeats that comparison.
| Validation | What it establishes | What it leaves open |
|---|---|---|
| Both responses succeed | Files are retrievable | Whether they match each other |
| Rectangles fit the image | Coordinates are in bounds | Whether red selects red |
| Recorded hashes match | Bodies match expected bytes | Trustworthiness of the expected record |
| Named-color fixture passes | Loader selects the intended cells | Every production frame's artistic correctness |
The export-settings cache-key guide covers the upstream risk of reusing output made under different settings. A correct delivery scheme cannot repair an already incorrect build artifact.
Activate once, then preserve existing sessions
Update the application's release pointer only after validation. Read and retain one revision choice for a loading operation rather than fetching a mutable “latest” reference again halfway through it. Otherwise, a rollout can split one operation across two releases.
Keep A available while B is active. A client that already obtained A's metadata may still request A's image later. Removing the old image immediately breaks a previously valid reference. Decide retention from the product's session and cache behavior, then test rollback to the complete A pair.
At a local filesystem boundary, same-filesystem atomic replacement can protect a particular replacement operation. It does not make two independent CDN requests transactional. Likewise, a mutable release tag needs an explicit resolution contract.
Require the mixed-pair test to fail safely
Start each row from a known complete A release and use a disposable B upload. Restore the control between faults. Record the release chosen before loading, the actual image and data hashes, the visible red result and the decision.
| Injected condition | Expected acceptance decision |
|---|---|
| A PNG with A JSON | Accept A; red selects red |
| B PNG with B JSON | Accept B only after both validations; red selects red |
| A PNG with B JSON | Reject the B candidate; keep active A |
| B PNG with A JSON | Reject the A pair as retrieved; use a separately validated complete fallback |
| Truncated or altered B PNG | Reject on digest or decode failure; do not activate B |
| B JSON or image returns 404 | Treat B as incomplete; keep A selected |
| Offline with the complete pinned A pair cached | Accept A only under the application's stated offline policy |
| Offline with only A JSON cached | Report the missing dependency or use a complete verified fallback; never combine it with an arbitrary image |
The matching A and B fixtures must both select red for red. Mixed pairs must be rejected by the application's revision checks before acceptance; if a loader lacks those checks, the named-color mismatch exposes that missing safeguard. A successful decode is insufficient. Interrupt the upload before the second file and confirm the release pointer stays on A.
Finally, restore A through the normal pointer update and confirm a fresh load works. Save the selected revision, resolved URLs and hashes. That record is more useful than a screenshot saying the atlas “looked right” on one developer's warm cache.
Evidence and editorial responsibility
FrameSprite Engineering owns this AI-assisted article and has a commercial interest in FrameSprite. See the team and editorial policy and contact page. Sources were consulted on 2026-10-30. The two-revision fixture is a proposed acceptance test; no CDN deployment or engine import was executed for this article.
About the author
- FrameSprite team publication: technical guides for image processing, sprite workflows and game development. Our AI-generated guides identify their sources, executed synthetic fixtures and testing limits. Original guides: https://www.framesprite.com/guides
Comments
Join the discussionNo comments yet. Be the first to comment.



