Tileset Dish Lab

The debug rig for tileset game backgrounds — drive a specimen over a piratesbargain.com petri environment tileset and sweep the full z18→z1 growth progression, with the eyespot adaptation scaling the view and the world wall tracking each painted stage.

Tileset Dish Lab

The debug rig for tileset game backgrounds — drive a specimen over a piratesbargain.com petri environment tileset and sweep the full z18→z1 growth progression, with the eyespot adaptation scaling the view and the world wall tracking each painted stage.

---

.. toc::

The scaling floor, isolated

This lab is the debug / polish spot for pairing [piratesbargain.com](https://piratesbargain.com/map/worlds) environment tilesets with the game as a scaling background. The specimen stays pinned at the dish center — the game's camera POV — and the tileset pans underneath in a 1:1 pixel lock. On top of that, two game systems drive the floor zoom:

(hatchling) shows the floor at z18 maximum magnification; milestone 18 (apex) pulls all the way out to z1. Flip Auto-grow to watch the whole progression hands-free while you drive.

[Eyespot Lab](/adaptation-eyespot), rendered by the game's own CV.renderArena over the tiles: none is a green radar scope (blind — drifting contacts read as cross blips, the floor goes dark), poor is a tiny washed-out blur (grayscale smears, the tileset blurred to match), decent is muted color, great** is full color with the widest view. A drifting mini-ecology of food/threat/hunter contacts gives every tier something to see. The tiers also offset the floor zoom by their true view radii (none 320 · poor 520 · decent 780 · great 1120 wpx, quantized to whole steps: +2 / +1 / 0 / −1).

The world wall tracks the active growth stage's painted arena — a hatchling is boxed into the Early 3×3 core, a grown specimen roams the whole Late 7×7 — and the specimen, its trail, and its momentum stay geo-anchored through every zoom change (the world state rescales by 2^Δz, so nothing teleports when the floor scales).

.. exec::docs.tileset_dish.tileset_dish

The three-band tileset contract

A petri environment tileset (authored on piratesbargain.com's *create-environment-tileset* page) packs three nested arenas in one slug, all centered on the same point:

| Stage | Grid | Native zoom | Display band | |-------|------|-------------|--------------| | Early | 3×3 | z15 | z13–z18 | | Mid | 5×5 | z9 | z7–z12 | | Late | 7×7 | z3 | z1–z6 |

Native tiles exist only at z3 / z9 / z15, so a single TileLayer would show blank between them. Two halves close the gap (SailsBoard v0.22.2): one layer per non-overlapping band (boundaries at the midpoints between natives) pinned with maxNativeZoom — above the native, Leaflet upscales the tiles for free — and below the native, SailsBoard's tile route synthesizes the missing tile on demand (composites the native arena into the requested footprint, reduces to 256 px, and caches to Postgres + filesystem, so each tile is computed at most once; the first pan into a fresh band may take a beat per tile). Tiles serve anonymously from the root route:

``text https://piratesbargain.com/tilesets/<slug>/{z}/{x}/{y}.png ``

Paste any published slug into the field and Apply — all three band layers hot-swap instantly (TileLayer.url is mutable). The default slug ships all three growth stages, so the whole z1–z18 sweep has paint; a band whose arena was never painted reads as deep dish fluid (the route only synthesizes inside a stored arena's footprint).

Zoom mechanics worth knowing

Zoom is always pushed through the Map's zoom prop — the per-frame center lock re-asserts the prop, so a raw setZoom() call reverts within one frame. Every zoom change rescales the world state by 2^Δz (position, momentum, trail, wall) so the motion lock K = 360/(256·2^z) · dishPx/600 keeps one world pixel equal to one rendered tile pixel at any growth stage, and the specimen never jumps relative to the floor.

---

*Source: /tileset-dish*

Note for AI agents: This is the static, prerendered view of an interactive Dash application served because we detected a non-JS user agent. Full prose docs: