The GameTank machine
GameTank is spriteCart's second fantasy-machine profile — a browser-emulated model of the real GameTank console, selected by a cart's machine_id header byte 0x02 (SC8 is 0x01). Where SC8 aims for classic fantasy-console simplicity, GameTank trades that simplicity for hardware fidelity: the studio's Export .gtr button (or a source-tree cart-build --emit gtr build) compiles the same cart source into a burnable native ROM. See Building & exporting .gtr ROMs for that half of the story.
What changes vs SC8
| Capability | SC8 | GameTank |
|---|---|---|
| Color | 16-color fixed indexed palette (3 built-in swatches, per-cart choice) | 256-color fixed HSL-derived lookup table, no per-cart choice — color is picked per-pixel while painting a sheet |
| Sprites | Fixed 8×8 tile sheet (256 tiles), drawn with sprite | 8 sheets of 256×256 8-bit pixels, drawn with the variable-rect blit primitive — see Sprite sheets & blit |
| Audio | 5 fixed-role synth voices (sq0, sq1, triangle, sawtooth, noise) | Hybrid tracker + PCM — synth voices or imported sample instruments; see Samples & sample instruments |
| Cart cap | 32 KB flat (only option) | 2 MB flash-2m by default (or 8 KB micro-8k) |
| Cost model | 1 op = 1 cycle, flat 500,000-op budget | Measured native 6502 cycle costs per op / per draw, charged against a 59,009-cycle budget (55,509 with music) — see Cart-Forth subset's execution-model section for the full breakdown |
Selecting GameTank
The studio's Cart tab has a machine picker. Switching a cart to GameTank changes what the other tabs look like — the Sprites tab becomes a 256×256 sheet editor, Sounds gains a Synth/Sample instrument-kind toggle, and a new Samples tab appears. Every fresh workspace — first studio visit, or New — is already seeded with a small working starter for the active machine (ship + star sprites, a looping BGM pattern, an A-button blip, d-pad movement) rather than a blank editor, so switching to GameTank on an untouched workspace swaps in GameTank's version of that same starter (a 16×16 ship + 8×8 star on sheet 0, a sample-kind blip instrument backed by PCM). Once you've made edits, switching machine keeps today's header-only behavior instead of re-seeding over your work.
Authoring gotchas
Column 127 is the border-color register
On real GameTank hardware, the composite video output's side borders take their color from whichever pixel ends up in framebuffer column 127 each scanline — the emulator replicates this faithfully. Gameplay pixels must never touch column 127 unless you're deliberately coloring the border. Practical rule: clamp every draw call so x + w <= 127 (max painted column 126) — this includes wide overlays drawn at another entity's position (an explosion frame wider than the sprite it replaces is the classic miss) and step-based wall checks (a 2px step means the flag condition is x + w > 125, not 126). Sprites may still slide off the left edge freely — only the right edge feeds the border color.
Only ~100 of 128 lines are visible on a real CRT
Per the GameTank manual, a real CRT overscans the framebuffer's top and bottom edges — only about 100 of the 128 vertical lines are reliably visible. Keep critical HUD elements (score, lives, prompts) inside the central ~100 lines; the browser emulator shows the full 128 lines, so a layout that looks fine on /play can crop on hardware.
Cart RAM: 7,424 B native vs 8,192 B in the browser VM
The browser VM gives every cart the full RAM_BYTES = 8,192 (8 KB) cart-RAM window, bounds-checked on every access. Native .gtr builds are smaller and unchecked: the runtime's cart-RAM window is $0200–$1EFF — 7,424 bytes — and out-of-range reads/writes are not guarded (a deliberate SP2 tradeoff — bounds-checking every memory op would cost real 6502 cycles the hardware doesn't spend, and would diverge from the runs in budget in the browser ⇒ runs on hardware contract). A cart written against the VM's full 8 KB that also targets --emit gtr must stay under 7,424 B, or it will silently corrupt adjacent native runtime state with no error in either environment.
Budget + honest throttling
GameTank's cost model doesn't drop work when a frame runs over budget — it finishes the frame's logic and the runner drops to an honest lower effective framerate instead (with a rate-limited warning), rather than truncating game state mid-execution the way SC8's op-budget exhaustion does. Full details, including the SC8/GameTank contrast, live in Cart-Forth subset — Memory + execution model.
Studio frame diagnostics
Run a GameTank cart in Studio and read Frame diagnostics below the preview. The panel shows modeled cycles and budget, worst cost and frame ID, minimum headroom, over-budget updates, skipped ticks, yields, faults and init failure. Console warnings are sampled: their line count is not a count of slow frames. These figures measure the browser's cost model; verify native timing with the exported ROM in an emulator or on hardware.
Download frame CSV retains the newest 120,000 observations and reports how many older rows were evicted. Panel totals cover the whole run. Rows distinguish init, update and skip; logical frame IDs include skipped ticks, while executed IDs count update attempts. Timestamps use the page's wall-time clock (performance.now in milliseconds), not the cart's clock. Each row includes modeled cycles, budget, SOND presence, held buttons and outcome.
Stop keeps the recording for download; Run starts a new one. The displayed SHA-256 and CSV filename identify the initially loaded cart bytes, even if you later edit or compile another cart. Live audio edits do not change that hash, so keep those changes in mind when comparing captures.