Skip to content

feat(examples): fantasy-dungeon reference asset plugin (Asset-Plugins P2) - #587

Merged
apotema merged 1 commit into
mainfrom
feat/728-fantasy-dungeon-demo
Jul 10, 2026
Merged

feat(examples): fantasy-dungeon reference asset plugin (Asset-Plugins P2)#587
apotema merged 1 commit into
mainfrom
feat/728-fantasy-dungeon-demo

Conversation

@apotema

@apotema apotema commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

The reference asset plugin + Phase-2 acceptance fixture for the Asset-Plugins epic (design labelle-engine#725, RFC #726 rev 4). Lands alongside the existing plugin-controllers reference example under examples/.

P1 (pack.labelle .resources) and P2 (plugin.labelle .resources + nested .packs) are already merged in the assembler; this PR is the demo that exercises the mechanism end to end.

What it is

examples/fantasy-dungeon/ — a consuming game (project.labelle, headless .null backend) that attaches one vendor-style plugin (local:./plugin) and gets a whole dungeon content kit with zero manual .resources edits. That emptiness is the Phase-2 acceptance criterion.

The fantasy_dungeon plugin bundles:

  • two packs at plugin/packs/{tiles,props}/ — each with its own pack.labelle .resources atlas + prefabs; tiles also ships a generator script (an ordinary dir-scanned pack script).
  • a plugin-level atlas (banner) via plugin.labelle .resources.
  • .license / .author provenance.

What it demonstrates (all verified at generate time)

  • resource merge — atlases registered namespaced + repathed: registerAtlasFromMemory("tiles__tileset", @embedFile("packs/tiles/assets/tileset.json") …), "props__atlas", "fantasy_dungeon__banner".
  • frame-key namespacing — on-disk floor.pngtiles/floor.png, banner.pngfantasy_dungeon/banner.png; the packs' own prefab sprite_name refs rewritten to match.
  • scene auto-wiringscenes/main.jsonc names no pack atlas; referencing tiles__floor_tile etc. auto-wires tiles__tileset + props__atlas into the scene manifest (pub const main = &.{ "fantasy_dungeon__banner", "tiles__tileset", "props__atlas" }).
  • generator = ordinary scriptpacks/tiles/scripts/playing/50_dungeon_generator.zig wired as a playing-state pack script.

CI

New examples-integration step Generate + build + run the fantasy-dungeon asset-plugin example: runs generate, asserts the namespaced-merge shape in the generated main.zig + copied atlases + rewritten prefab, then builds and runs the headless .null binary and checks the generator script's log lines.

Assets

Minimal solid-colour placeholder PNGs, generated programmatically — the reference is about the resource mechanism, not the art. A real vendor plugin drops in packed sheets of the same shape with no manifest change.

Verification

labelle-assembler generate --project-root . is clean and produces every invariant above (asserted locally). A full zig build of the generated game needs engine ≥1.66 / gfx ≥1.20 / core ≥1.24 (the assembler-0.73+ renderMeshes/PackView seam) — CI checks out fresh main of those; the stale local sibling checkouts used during development are behind, so the local build wall is environmental (the existing packs-demo example hits it too), not a defect in this fixture.

Closes labelle-toolkit/labelle-engine#728

https://claude.ai/code/session_017pW3ifKf9wgxNg4viy6okw

Summary by CodeRabbit

  • New Features
    • Added the Fantasy Dungeon reference project with bundled tiles, props, prefabs, scenes, atlas assets, metadata, and a headless demo.
    • Added plugin support showcasing automatic discovery, asset namespacing, sprite-key rewriting, scene wiring, and generator-driven dungeon rows.
  • Documentation
    • Added setup, usage, asset behavior, metadata, and headless execution guidance.
  • Tests
    • Added end-to-end integration coverage validating generated assets, scene wiring, resource output, builds, and demo execution.

… P2, #728)

The Phase-2 acceptance fixture + reference vendor plugin for the
Asset-Plugins epic (labelle-engine#725, RFC-ASSET-PLUGINS rev 4). A game
attaches ONE plugin (`local:./plugin`) and gets a whole dungeon content kit
with ZERO manual `.resources` edits — that emptiness is the acceptance
criterion.

The `fantasy_dungeon` plugin exercises the full P1+P2 surface end to end:

- `.packs` — two packs BUNDLED at `plugin/packs/<name>/` (`tiles`, `props`),
  each discovered as a first-class pack flowing through the same copy / scan /
  `pack__` namespace / resource-merge machinery as a game-local pack.
- pack `.resources` (Phase 1) — `tiles__tileset` / `props__atlas` merged +
  repathed into `packs/<pack>/assets/…`, atlas frame keys rewritten to
  `<pack>/<frame>` and each pack's own prefab `sprite_name` refs rewritten to
  match.
- plugin `.resources` (Phase 2) — a plugin-level `banner` atlas merged as
  `fantasy_dungeon__banner`.
- `.license`/`.author` provenance metadata.
- scene auto-wiring — `scenes/main.jsonc` names no pack atlas; referencing the
  namespaced pack prefabs pulls each pack's atlas into the scene manifest.
- a generator = an ordinary dir-scanned pack script (RFC's "tiles are
  entities, tilesets are just atlases" — no new engine machinery).

Verified: `labelle-assembler generate` produces the namespaced+merged atlas
registrations (`register*("tiles__tileset", @embedfile("packs/tiles/assets/…"))`),
the auto-wired scene manifest, on-disk namespaced frame keys, and the rewritten
pack-prefab sprite refs. A new `examples-integration` CI step asserts all of
this, then builds + runs the headless `.null` binary so the pack generator
script fires.

Assets are minimal solid-colour placeholder PNGs (generated programmatically) —
the reference is about the resource MECHANISM, not the art.

Closes labelle-toolkit/labelle-engine#728

Claude-Session: https://claude.ai/code/session_017pW3ifKf9wgxNg4viy6okw
@gemini-code-assist

Copy link
Copy Markdown

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds the fantasy-dungeon reference asset plugin with bundled tiles and props packs, plugin-level banner assets, scene auto-wiring, a headless generator, documentation, and CI coverage for generation, namespacing, building, execution, and generator output.

Changes

Fantasy Dungeon Plugin

Layer / File(s) Summary
Plugin package and manifest
examples/fantasy-dungeon/plugin/plugin.labelle, examples/fantasy-dungeon/plugin/assets/banner.json, examples/fantasy-dungeon/plugin/build.zig, examples/fantasy-dungeon/plugin/build.zig.zon, examples/fantasy-dungeon/plugin/src/root.zig
Defines the fantasy_dungeon plugin, banner resource, bundled packs, provenance metadata, and referenceable Zig package.
Bundled packs and prefabs
examples/fantasy-dungeon/plugin/packs/tiles/..., examples/fantasy-dungeon/plugin/packs/props/...
Adds tiles and props pack manifests, atlas metadata, sprite assets, and prefab definitions with pack-local sprite names.
Demo project and generator
examples/fantasy-dungeon/project.labelle, examples/fantasy-dungeon/scenes/main.jsonc, examples/fantasy-dungeon/plugin/packs/tiles/scripts/...
Configures a headless project with no manual resources, references bundled prefabs and the banner, and logs four deterministic dungeon rows while in the playing state.
Acceptance validation and example documentation
examples/fantasy-dungeon/README.md, examples/fantasy-dungeon/.gitignore, .github/workflows/ci.yml
Documents the fixture and adds CI checks for generated namespaced resources, asset paths, build execution, and generator log output.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related issues

Possibly related PRs

Sequence Diagram(s)

sequenceDiagram
  participant CI
  participant Assembler
  participant GeneratedDemo
  participant DungeonGenerator
  CI->>Assembler: generate fantasy-dungeon
  Assembler-->>CI: generated main.zig and namespaced pack resources
  CI->>GeneratedDemo: fix fingerprint, build, and run
  GeneratedDemo->>DungeonGenerator: tick in playing state
  DungeonGenerator-->>GeneratedDemo: log dungeon rows
  GeneratedDemo-->>CI: run.log
Loading

Poem

A rabbit hops through packs of sprites,
With tiles and props in namespaced flights.
The banner gleams, the dungeon grows,
Four little rows in tidy prose.
CI checks each burrowed byte—
Then builds the demo through the night.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly names the fantasy-dungeon reference asset plugin and its Asset-Plugins P2 scope.
Linked Issues check ✅ Passed The PR adds the bundled tiles and props packs, generator script, plugin assets, metadata, and end-to-end validation required by #728.
Out of Scope Changes check ✅ Passed The added README, CI, and manifest files support the fantasy-dungeon fixture and do not appear unrelated.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/728-fantasy-dungeon-demo

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
.github/workflows/ci.yml (1)

595-598: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Consider adding $ASM install before generate for self-sufficiency.

This step uses the .null backend (output path .labelle/null_desktop) but skips $ASM install --project-root ., unlike the asset-streaming-smoke (line 213), flows-smoke (line 388), and packs-demo (line 456) steps. Those steps' comments explicitly note that .null is an extracted external backend whose backend.manifest.zon must be in the package cache before generate can splice codegen, and that install makes the fixture "self-sufficient and order-independent."

This step currently relies on earlier steps having populated the cache. That's consistent with the null (line 313) and plugin-controllers (line 521) steps, but those predate the explicit guidance. If the asset-streaming-smoke or flows-smoke steps are ever removed or reordered, this step will fail.

🔧 Suggested addition
       - name: Generate + build + run the fantasy-dungeon asset-plugin example
         run: |
           cd labelle-assembler/examples/fantasy-dungeon
-          $GITHUB_WORKSPACE/labelle-assembler/zig-out/bin/labelle-assembler generate --project-root .
+          ASM=$GITHUB_WORKSPACE/labelle-assembler/zig-out/bin/labelle-assembler
+          $ASM install --project-root .
+          $ASM generate --project-root .
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml around lines 595 - 598, Add an `$ASM install
--project-root .` command before `generate` in the fantasy-dungeon asset-plugin
workflow step, matching the setup used by asset-streaming-smoke, flows-smoke,
and packs-demo so the fixture independently populates the external `.null`
backend cache.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In @.github/workflows/ci.yml:
- Around line 595-598: Add an `$ASM install --project-root .` command before
`generate` in the fantasy-dungeon asset-plugin workflow step, matching the setup
used by asset-streaming-smoke, flows-smoke, and packs-demo so the fixture
independently populates the external `.null` backend cache.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0669b054-23be-4486-ad9d-f193d7b3dea7

📥 Commits

Reviewing files that changed from the base of the PR and between b8d3007 and 30ae7a7.

⛔ Files ignored due to path filters (3)
  • examples/fantasy-dungeon/plugin/assets/banner.png is excluded by !**/*.png
  • examples/fantasy-dungeon/plugin/packs/props/assets/props.png is excluded by !**/*.png
  • examples/fantasy-dungeon/plugin/packs/tiles/assets/tileset.png is excluded by !**/*.png
📒 Files selected for processing (19)
  • .github/workflows/ci.yml
  • examples/fantasy-dungeon/.gitignore
  • examples/fantasy-dungeon/README.md
  • examples/fantasy-dungeon/plugin/assets/banner.json
  • examples/fantasy-dungeon/plugin/build.zig
  • examples/fantasy-dungeon/plugin/build.zig.zon
  • examples/fantasy-dungeon/plugin/packs/props/assets/props.json
  • examples/fantasy-dungeon/plugin/packs/props/pack.labelle
  • examples/fantasy-dungeon/plugin/packs/props/prefabs/chest.jsonc
  • examples/fantasy-dungeon/plugin/packs/props/prefabs/torch.jsonc
  • examples/fantasy-dungeon/plugin/packs/tiles/assets/tileset.json
  • examples/fantasy-dungeon/plugin/packs/tiles/pack.labelle
  • examples/fantasy-dungeon/plugin/packs/tiles/prefabs/floor_tile.jsonc
  • examples/fantasy-dungeon/plugin/packs/tiles/prefabs/wall_tile.jsonc
  • examples/fantasy-dungeon/plugin/packs/tiles/scripts/playing/50_dungeon_generator.zig
  • examples/fantasy-dungeon/plugin/plugin.labelle
  • examples/fantasy-dungeon/plugin/src/root.zig
  • examples/fantasy-dungeon/project.labelle
  • examples/fantasy-dungeon/scenes/main.jsonc

@apotema
apotema merged commit bd450c3 into main Jul 10, 2026
4 checks passed
@apotema
apotema deleted the feat/728-fantasy-dungeon-demo branch July 10, 2026 18:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Asset plugins P2: fantasy-dungeon demo plugin (reference vendor plugin + acceptance fixture)

1 participant