# 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**: - **Growth** — the milestone slider sweeps a simulated playthrough: milestone 1 (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 adaptation** — the full **first-person vision treatment from the [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//{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*