Skip to content

Repository files navigation

Redirect Loop

Play online

Play Redirect Loop in your browser

This repository contains the finished Milestone 14 release candidate for a 480 × 270 HTML Canvas factory game. It begins with a restrained opening screen, teaches the essential controls through a compact in-game reference and optional objective line, and delivers one complete tragic playthrough: build an iron line, watch the Foundry Compact expand, complete its one fixed trade, trigger Meridian Research, experience the warning escalation, and reach the unavoidable impact and ending at tick 4730 (07:53). The ending offers only an ordinary clean new game.

CURRENT RELEASE: one complete tragic playthrough ending with asteroid impact.

NOT IMPLEMENTED: a narrative time loop, retained knowledge, trust or persuasion, planetary defense, alternate endings, or post-impact progression.

For a short player-facing walkthrough, including a reliable building layout and troubleshooting, see HOW_TO_PLAY.md.

Run in development

  1. Install a current version of Node.js if it is not already available.
  2. From the project folder, run npm run dev.
  3. Open http://127.0.0.1:4173/ in a browser.

No project packages need to be installed for the game itself. The development server includes explicitly gated review fixtures; the release build does not.

Build and preview the release

  1. Run npm run build to create the deterministic static release in dist/.
  2. Run npm run preview.
  3. Open http://127.0.0.1:4174/.

The allowlisted release contains only the runtime HTML, CSS, JavaScript, authored game data, final visual assets, and WAV audio. It excludes review fixtures, generated source sheets, prompt archives, extraction scripts, tests, screenshots, reference images, audit output, and absolute local paths. Serve dist/ over HTTP; direct file:// loading is not a supported release path.

Every push to main runs the automated tests, recreates dist/, and deploys that exact release through GitHub Pages. Runtime paths remain relative so the same build works locally and under the public /redirect-loop/ project path.

Test the project

  • npm test runs deterministic simulation, onboarding, objective, progression-safety, restart, release-build, input, rendering, audio, and regression checks.
  • npm run verify:assets checks final visual assets for dimensions, palette, alpha, magenta contamination, frame completeness, and integer pixel rules.
  • npm run verify:live builds the release, launches the real development and production Canvas pages, drives the complete public-input Milestone 14 playthrough, audits rendering/audio/errors, and captures the twelve release screenshots. The earlier catastrophe-boundary audit remains available as npm run verify:live:m13; other milestone-specific commands remain listed in package.json.

Controls

  • On the opening screen, use the arrow keys or W/S and Enter, or click, to choose NEW GAME, CONTROLS, or AUDIO / ACCESSIBILITY.
  • Move the camera with W, A, S, D or the arrow keys.
  • Hold the middle mouse button and drag to pan.
  • Move the pointer over the map to inspect a tile; left-click to keep a tile or structure selected.
  • Press B to open or close the build menu, or click the compact B marker at the right edge of the resource HUD to open it.
  • While the menu is open, press 16 or left-click an icon to choose Biomass Generator, Iron Extractor, Smelter, Storage, Conveyor, or Trade Station. The unique Trade Station becomes available after the player accepts the Foundry offer.
  • Move over the world to preview the selected footprint; left-click a valid location to place it. The selected item stays active for repeated placement.
  • Beginning Conveyor placement initializes EAST. Press R to rotate the Conveyor ghost clockwise or Shift+R to rotate it counterclockwise; that active direction carries across repeated placements until placement ends. Other buildings do not rotate. While a Conveyor ghost is active, counterclockwise rotation takes priority over the debug reset shortcut.
  • Press Escape once, right-click, or use the cancel icon to cancel the active item. With no active item, press Escape or use cancel again to close the menu.
  • Press Space to open the pause menu. Escape also opens it when no build, placement, or options action needs to consume that key. The pause menu contains RESUME, CONTROLS, AUDIO / ACCESSIBILITY, and RESTART NEW GAME; restart requires confirmation.
  • With the build menu closed, press 1 for normal speed or 2 for double speed. While the menu is open, 16 continue to select build items instead.
  • Once FOUNDRY_TRADE_READY opens the offer, select any Foundry-owned building. Press T or click T ACCEPT CONTRACT in the bottom HUD to accept the fixed 4 PLT > 2 CIR +1 exchange.
  • Select the Meridian sensor to inspect MONITORING or UNUSUAL READING. Its post-trade response is automatic and has no player command.
  • Press O to open or close the compact options strip. While it is open, 1 cycles music volume, 2 cycles sound-effect volume, 3 toggles reduced flash, 4 toggles reduced motion, and Escape closes it. The same controls can be clicked. Volume steps are 0, 25, 50, 75, and 100.
  • Press G to show or hide the optional contextual objective line. This changes presentation only and cannot change or rewind simulation progress.
  • Use the compact Canvas clock controls for Pause, 1×, and 2× with the same behavior as the keyboard shortcuts.
  • In an explicitly debug-enabled development session only, press the backtick key (`) to toggle the development overlay. Debug tools are absent from the release build.

Ordinary tile selection is hidden during placement, but camera movement remains available. Conveyor placement remains one tile per click; drag-to-build paths are deferred.

Playable start

The application first shows the release opening screen while the canonical world remains at tick 0. Choosing NEW GAME begins with only the player Headquarters, open construction space, one unused claimable iron deposit, and the Foundry Compact and Meridian Research Directorate settlements. There is no player Generator, Extractor, Smelter, Storage, Conveyor, or Trade Station. Player power begins at 0/0; placing the first Biomass Generator changes only the player pool to 0/4. The Foundry begins separately in phase 0 with its headquarters/industrial core, 4 power capacity, and a small owner-local stockpile. The one trade contract begins LOCKED, with zero Foundry standing and no trade events. Meridian begins in MONITORING with no observed trade completion, scheduled response, detected tick, or Research event. Warnings begin exact CALM with no observed source, no active deadline source, a fixed scheduled start of tick 4200, no current/completed stage, and no warning event. Presentation preferences begin at music 50, SFX 75, full flash, and full motion.

The optional objective sequence is BUILD A BIOMASS GENERATORPLACE AN EXTRACTOR ON THE IRON DEPOSITCONNECT THE EXTRACTOR TO A SMELTERROUTE METAL PLATES TO STORAGEMONITOR FOUNDRY TRANSMISSIONSSELECT FOUNDRY / PRESS T TO ACCEPTROUTE 4 PLATES TO THE TRADE STATIONRESPOND TO MERIDIANSENSOR ARRAY ACTIVECONTINUE OPERATIONS. It reads authoritative world state, advances monotonically, and never reveals the destruction in advance.

The earlier visual-foundation player machinery remains available only in development/review material. Historical Milestone 06 screenshots may show that fixture and do not define the current playable start.

Construction resources and costs

The Headquarters supplies one fixed construction inventory. Metal Plates is the canonical name for the resource earlier documents called Iron Plates. Circuits is the same prototype resource earlier called Sensor Components; it is not a fifth resource.

Resource Starting amount
Biomass 8
Iron Ore 0
Metal Plates 48
Circuits 3
Buildable Fixed cost Power
Biomass Generator 8 Metal Plates, 6 Biomass, 2 Circuits Supplies 4
Iron Extractor 8 Metal Plates, 1 Circuit Demands 2
Smelter 8 Metal Plates Demands 2
Storage 6 Metal Plates No power required
Conveyor 1 Metal Plate No power required
Trade Station 4 Metal Plates No power required

The HUD and build menu show current balances, costs, and whether the selected item can be afforded. An unaffordable item can still be inspected, but confirmation fails without placing anything or deducting part of its cost. A successful placement creates one ordered construction transaction and deducts the whole cost at once. Because this prototype has exactly one required processing line and no demolition/refund system, a second player Smelter or second player Storage is rejected without spending resources or advancing deterministic IDs. This narrowly prevents an unrecoverable construction-wallet mistake; it is not a general building limit system.

Clock and power

Simulation advances through integer ticks at 10 ticks per second, so one tick is 100 ms of simulation time. The browser-facing clock clamps each incoming frame delta to 250 ms before applying 1× or 2× speed. Pausing processes no ticks, while camera movement and interface input remain responsive. The Foundry schedule, 30-tick trade packet, Meridian Research response, four warning stages, and seven-stage finale use this same clock. Normal gameplay remains active through 4719, stops exactly when IMPACT is processed at 4720, and never resumes during the destroyed or ending states.

Power is capacity, not a stored resource, fuel timer, or cable network. Each owner has a separate deterministic pool. A Generator adds 4 capacity to its owner; Extractors and Smelters request 2 from that same owner; Storage and Conveyors show NOT REQUIRED.

Power is allocated within each owner in stable structure-ID order. A player placement is allowed when player capacity is exhausted, but the newly allocated machine may show UNPOWERED; existing earlier player machines keep their deterministic priority. Foundry demand cannot consume player supply, and player demand cannot consume Foundry supply. Biomass is charged only as part of the player's Generator construction cost and is not consumed as fuel.

Local production inventories

The four main HUD counters are the construction inventory only. Machine output never enters those counters automatically. Each machine owns bounded local state that can be inspected and can exchange approved Ore or Plates only through the fixed-port Conveyor rules below.

Machine Local production rule Local capacity Operational states
Iron Extractor While fully powered, produces 1 Iron Ore every 20 ticks Output: 8 Iron Ore RUNNING, UNPOWERED, BLOCKED OUTPUT, IDLE when applicable
Smelter Atomically consumes 2 Iron Ore, processes 30 powered ticks, then produces 1 Metal Plate Input: 8 Iron Ore; output: 8 Metal Plates RUNNING, STARVED INPUT, BLOCKED OUTPUT, UNPOWERED, IDLE when applicable
Storage Accepts Iron Ore or Metal Plates through its fixed west Conveyor input 32 total units EMPTY, PARTIALLY FILLED, FULL
Biomass Generator Supplies 4 power; no fuel inventory N/A ONLINE
Conveyor Moves at most one Iron Ore or Metal Plate toward its recorded cardinal output One item slot; 10 ticks per tile EMPTY, WAITING FOR INPUT, MOVING ORE, MOVING PLATE, BLOCKED, INVALID OUTPUT
Trade Station Accepts only player-owned Metal Plates through its west port; the accepted contract removes exactly 4 at once Cargo: 4 Metal Plates EMPTY, PARTIALLY FILLED, FULL; contract state remains separate

Local insertion and removal are atomic: a request either fits completely or leaves the inventory unchanged. A Smelter consumes its complete input when a cycle starts, retains partial cycle progress while unpowered, and produces its complete output only when the cycle finishes. Milestone 08 can move physical Ore and Plates between these local inventories, but it never adds them to the construction inventory. The construction-inventory counters therefore remain unchanged while the factory runs.

Selecting a machine shows its ID, power and operational states, integer-tick cycle progress, and relevant local quantities/capacities in the existing retro HUD. Storage lists contents only when non-empty. Progress uses an eight-step bitmap meter such as [==------], paired with the coordinated state badge rather than a smooth web-style bar.

Directional logistics

Every Conveyor stores exactly one output direction: NORTH, EAST, SOUTH, or WEST. Clockwise rotation is NORTH → EAST → SOUTH → WEST → NORTH; counterclockwise rotation reverses that order. Entering a new Conveyor-placement session initializes EAST; repeated placements during that session keep the active direction. Every placed direction is permanent during this milestone, and reset restores the placement default to EAST.

Buildings do not rotate. Relative coordinates below use the upper-left tile of each 2 × 2 building as anchor (0,0):

Building port Building-side tile Required external Conveyor target Resource
Iron Extractor output (+1,+1) (+2,+1) east Iron Ore out
Smelter input (0,+1) (-1,+1) west Iron Ore in
Smelter output (+1,+1) (+2,+1) east Metal Plates out
Storage input (0,+1) (-1,+1) west Iron Ore or Metal Plates in
Storage output (+1,+1) (+2,+1) east Metal Plates out
Trade Station input (0,+1) (-1,+1) west Metal Plates in
Biomass Generator / Headquarters None None No item ports

Port markers are subtle and temporary: they appear only while placing a Conveyor, selecting the building, or using the development overlay. A machine never transfers directly to an adjacent machine. Its item can leave only into a Conveyor occupying its output target. It can receive only from a Conveyor occupying the input target and pointing from that target into the building-side tile—for the west Smelter/Storage inputs, that delivery Conveyor points EAST.

Each Conveyor has one optional item slot. An item stores a deterministic item ID, either iron-ore or metal-plates, its current Conveyor/source location, and integer movement progress. It takes exactly 10 simulation ticks to cross one tile. Canvas interpolation is visual only and quantized to whole internal pixels; pause, 1×/2×, refresh rate, and camera position cannot change authoritative movement.

Transfers use two phases. First, every source inspects the same immutable state and proposes an intention. Second, intentions are sorted by stable source ID and applied atomically. If two sources target one destination, only the lowest source ID succeeds; every other item remains at its source. Destination direction does not need to match the source, so adjacent differently directed Conveyors form corners.

An Extractor can offer one Ore from its output buffer; a Smelter or Storage can offer one Plate through its approved east output. A completed Conveyor may enter another empty Conveyor, deliver Ore to the Smelter's west input, deliver Ore/Plates to Storage's west input, or deliver a player-owned Plate to the Trade Station's west input. Occupied or full destinations block without removing the source. Wrong resources, owners, building sides, blocked terrain, and missing targets report INVALID OUTPUT; items are never deleted or rerouted.

Selecting a Conveyor shows its deterministic ID, direction, item or EMPTY, 0–10 tick progress, target type, and operational state. The development-only conservation audit reconciles initial local quantities and production with machine buffers, Conveyor slots, Storage, Trade Station cargo, recipe consumption/output, and the exact four Plates externally removed at dispatch, independently for PLAYER and FOUNDRY. Items and transfer intentions retain their owner, cross-owner delivery is rejected, and the audit itself never changes or appears in the player construction wallet; the separate two-Circuit completion reward uses the resource ledger.

EMPTY means the slot has no item and no recognized upstream source is connected; WAITING FOR INPUT means the slot is empty with a valid upstream source that has not offered an item. MOVING ORE and MOVING PLATE mean an item is below 10 ticks of progress. BLOCKED means a completed item faces a valid but unavailable destination. INVALID OUTPUT means its completed output has no valid target, reaches a non-port side, or offers a resource the target rejects.

Foundry Compact expansion

The Foundry follows one data-authored plan; it is not a general planning AI. Simulation phase starts use the same 10 Hz clock as production, stop while paused, and reach identical states at the same tick under 1× or 2× speed.

Phase Ordinary trigger Accelerated review trigger Result
0 — Core Online Opening state Opening state Existing headquarters/core, 4 Foundry power, and owner-local stockpile
1 — Extraction Expansion Tick 450 (00:45) Tick 10 Build Extractor and first eastbound Conveyor
2 — Processing Expansion Tick 1050 (01:45) Tick 60 Build Smelter and second eastbound Conveyor
3 — Storage and Annex Tick 1800 (03:00) Tick 140 Build Storage and activate the predefined export-yard annex
4 — Trade Ready Tick 2400 (04:00) or later, with at least 3 Foundry Metal Plates in Foundry Storage Tick 240 or later, with the same inventory threshold Emit FOUNDRY_TRADE_READY once

Ordinary construction durations are 40 ticks for the Extractor, 20 for its Conveyor, 60 for the Smelter, 20 for its Conveyor, 60 for Storage, and 80 for the annex. Accelerated review overrides each to 10 ticks. All six sites use WAIT_FOR_CLEAR_SITE: the Foundry waits at its approved location and never relocates, overwrites, or deletes a player structure.

Site ID Anchor Footprint/direction
foundry-extractor (22,11) 2 × 2; includes the Foundry Ore node at (23,12)
foundry-ore-belt (24,12) 1 × 1; EAST
foundry-smelter (25,11) 2 × 2
foundry-plate-belt (27,12) 1 × 1; EAST
foundry-storage (28,11) 2 × 2
foundry-export-annex (30,13) 2 × 2 export yard

The base territory is fixed at y=7 x=26–31; y=8 x=25–29 and x=31; y=9 x=25–31; y=10 x=30–31; and y=11–12 x=22–31. The annex tiles x=30–31/y=13–14 are reserved from the opening state and become visibly claimed in phase 3. Boundaries appear only near an active placement ghost, in the development overlay, or when a Foundry structure is selected. Player confirmation on any protected tile reports FACTION TERRITORY — FOUNDRY.

Foundry machines use real owner-local power, bounded inventories, production cycles, directional one-slot items, and atomic logistics. Selecting its central structure shows phase, Foundry power, total Ore/Plates, next objective, and trade-readiness state; selecting a machine shows its owner, local state, inventory, phase, and power where relevant. Temporary retro notifications surface important changes without replacing the simulation-owned event log.

The event log records deterministic ID, tick, faction ID, event type, and relevant site/structure references for FOUNDRY_CORE_ONLINE, FOUNDRY_EXTRACTION_STARTED, FOUNDRY_PROCESSING_STARTED, FOUNDRY_ANNEX_COMPLETED, and FOUNDRY_TRADE_READY. Core Online is recorded on the first processed tick after a start/reset; the empty tick-0 reset snapshot therefore remains exact. Milestone 10 consumes the Trade Ready event once to open the fixed offer; presentation text is not the unlock authority.

Fixed Foundry trade

The prototype has exactly one contract, foundry-plates-01:

Requirement Transit Reward Limit
4 player-owned Metal Plates in one player Trade Station 30 simulation ticks 2 Circuits and +1 Foundry standing Once per run

The contract begins LOCKED. The authoritative FOUNDRY_TRADE_READY event changes it to OFFER_AVAILABLE, but the Trade Station remains unavailable. Select any Foundry building and press T or click the bottom-HUD action to accept; the offer is always 4 PLT > 2 CIR +1. Acceptance changes the state to ACCEPTED/LOADING, unlocks exactly one Trade Station, and does not reserve or remove goods.

After acceptance, build shortcut 6 can select the unique 2 × 2 Trade Station. It costs 4 construction-ledger Metal Plates, needs no power, and accepts only same-owner physical Metal Plates through its fixed west input. Placement rejects the station before acceptance, after dispatch/completion, and whenever the one allowed station already exists. Fewer than 4 cargo Plates wait safely. At exactly 4/4, the contract removes all four atomically, records one dispatch, and enters IN_TRANSIT. A visible authored packet advances for exactly 30 processed ticks; pause freezes it, and speed changes do not alter its arrival tick.

Arrival changes the contract to COMPLETED, grants exactly 2 Circuits to the player construction ledger, and changes Foundry standing from 0 to 1. Standing is one displayed story/progression variable only: it is not currency, a price, a build cost or condition, a power or production modifier, a discount, an autonomous-AI input, or a general diplomacy/reputation system. It unlocks nothing in Milestone 11. The deterministic trade log contains at most one each of TRADE_OFFER_AVAILABLE, TRADE_CONTRACT_ACCEPTED, TRADE_CARGO_DISPATCHED, and TRADE_CONTRACT_COMPLETED. Repeated acceptance, dispatch, arrival, or later ticks cannot spend or reward twice.

There is no currency, fluctuating price, negotiation, second offer, repeatable contract, merchant inventory, market screen, or autonomous trader.

Meridian Research response

Milestone 11 adds one automatic, authored observation response. Meridian begins MONITORING and recognizes only a fully consistent completion of foundry-plates-01: the trade must be COMPLETED once and its log must contain exactly one matching TRADE_CONTRACT_COMPLETED event from FOUNDRY at the authoritative completion tick. Similar interface text, incomplete state, wrong ownership, duplicate events, or Foundry standing alone cannot trigger it.

After the canonical completion, Meridian schedules its response for max(3600, trade completion tick + 20). An early trade therefore waits until 06:00; a late trade waits exactly 20 simulation ticks. Without the completed contract it remains MONITORING indefinitely. Pause advances no ticks, and 1×/2× speed produce the same state at the same tick.

At the response tick, Meridian changes once to UNUSUAL_READING and records one MERIDIAN_ANOMALY_DETECTED event with its deterministic ID and source-trade references. The sensor holds its confirmed-reading frame, selection reports NOISY RETURN | SOURCE UNKNOWN, and an eighty-tick non-blocking scientist message reports NOISY HIGH-ALT RETURN / SOURCE UNRESOLVED in the existing HUD.

Only Research state changes at the Milestone 11 transition. No resource, transaction, standing value, structure, power pool, production process, Conveyor item, cargo quantity, contract state, faction expansion, or AI plan is modified. The separate warning state described below may observe its canonical event, but it cannot mutate any of those systems either.

Pre-catastrophe warnings

The ordinary release always uses the fixed warning deadline. A valid canonical MERIDIAN_ANOMALY_DETECTED observed by tick 4200 supplies the normal Research/trade provenance. If that detection is absent, late, duplicate, or malformed, the warning state activates from its explicit release-deadline source at tick 4200 instead; it does not change or falsely complete Trade, Research, standing, resources, objectives, or faction state. A later detection cannot move the schedule or replace the chosen source. The exact sequence is:

Tick/time Stage/event Visible and audible cue
4200 / 07:00 SENSOR_PULSE / WARNING_SENSOR_PULSE Registered cyan pulse at the Meridian sensor, first quiet anomaly layer, compact Research notice
4350 / 07:15 SKY_SHIFT / WARNING_SKY_SHIFT Restrained amber aperture treatment and conflicting report
4500 / 07:30 SHADOW_PASS / WARNING_SHADOW_PASS Authored airborne shadow and distant low rumble
4650 / 07:45 SIGNAL_BREAKUP / WARNING_SIGNAL_BREAKUP Localized scanlines, occasional two-pixel row displacement, authored glitch strip, stronger anomaly/rumble mix

Each event occurs once and changes warning state only. The intended completed route retains the full Research/trade source chain; the safety route records only sourceDeadlineTick: 4200 and never fabricates a completed trade or Research event. Pause freezes advancement; 1× and 2× reach the same stage on the same tick. The renderer and audio controllers read events but do not create them. Audio begins only after a player gesture. Four warning masters provide the quiet factory bed, anomaly layer, event ping, and low rumble; two additional Milestone 14 cues provide restrained Foundry communication and the one Meridian scan. Final mixing/mastering and OGG/MP3 fallback packaging are deferred.

The options strip is presentation state outside the simulation. Independent music and SFX volumes change playback only. Reduced flash caps warning-light intensity, while reduced motion holds representative pulse/shadow poses and suppresses row displacement. These settings never change event timing, economy state, or the map and may persist through development reset and ordinary clean restart.

Milestone 12 stops at SIGNAL_BREAKUP. The completed Milestone 13 layer alone owns asteroid approach, impact, destruction, and the ending. Narrative loop reset, retained knowledge, trust, and persuasion do not belong to the approved release at all.

Catastrophe and ending

The approved release finale is strict and does not wait for tutorial, construction, trade, or production progress:

Tick/time State Release behavior
4650 / 07:45 Existing SIGNAL_BREAKUP Preserve the completed warning state; gameplay continues
4660 / 07:46 ASTEROID_VISIBLE Reveal the authored upper-right diagonal approach
4680 / 07:48 INCOMING_CONFIRMED Show a compact non-blocking Meridian trajectory confirmation
4700 / 07:50 SYSTEM_FAILURE Escalate readable interference while normal simulation continues
4715 / 07:51.5 NEAR_IMPACT Present the final approach; controls and economy remain active through 4719
4720 / 07:52 IMPACT Stop normal gameplay exactly here and begin contact/destruction presentation
4724 / 07:52.4 DESTROYED Hold the terminal destroyed world with no gameplay or post-impact progression
4730 / 07:53 ENDING Show the tragic ending screen and one ordinary clean-restart action

Before impact, placement, camera, production, logistics, Foundry, trade, Research, warnings, options, and ordinary interface behavior remain active. At tick 4720 those gameplay processors and player commands freeze exactly once; only the short catastrophe state advances to DESTROYED and ENDING. Reduced flash and reduced motion change only presentation and never the ticks.

Restart is a new game, not a story loop. It restores the Headquarters-only map, starting resources and IDs, unused deposit, default Conveyor direction, player power 0/0, Foundry phase 0, locked trade and zero standing, Meridian MONITORING, warnings CALM, initial catastrophe state, tick 0, 1×, and unpaused. No world/story state survives. Music/SFX and reduced-effects preferences may persist. An optional time-loop expansion is only a possible separately approved future version, not a feature or promise of this release.

Placement rules

Every footprint tile must be inside the map, on land, clear of roads and the map's explicitly blocking trees/details, outside the fixed Foundry territory/reserved annex, and unoccupied by authored, faction-owned, or session-placed structures. The central ore marker is the prototype's one player-claimable iron patch; distant ore traces are authored landmarks and cannot be claimed. Only the 2 × 2 Iron Extractor may cover the player patch, which may occur anywhere inside its footprint. A successful extractor marks it as used, so a second extractor cannot claim it. Other buildings are rejected on the patch so the introductory production chain cannot be accidentally deadlocked.

Invalid clicks never partly alter the world. Valid clicks add one deterministic record to the session world state, including its ID, type, owner, anchor tile, footprint, occupied tiles, optional deposit reference, power assignment, and machine state. Clicking any occupied tile later selects the same placed structure.

Development-only review tools

The following reset and review routes are served only by npm run dev and require the explicit ?debug=1 query. They are unavailable from the ordinary interface, omitted from dist/, and cannot be activated by release keyboard input. They remain test infrastructure, not player features.

Development reset

Open http://127.0.0.1:4173/?debug=1 and, while no Conveyor ghost is active, press Shift+R to restore the ordinary start: player Headquarters only; no player session buildings, belts, Trade Station, cargo, or physical items; empty player machine inventories/progress; the four starting construction balances; unused player deposit; initial player IDs/counters; default EAST Conveyor direction; tick 0/00:00; 1×; unpaused; and player POWER 0/0. It also restores Foundry phase 0, its original base structures, initial 4-power pool and stockpile, no expansion structures/items, an empty expansion-event log ready to emit the core event deterministically, and initial Foundry structure/item/event sequences. The trade contract returns to LOCKED with no offer acceptance, packet, completion, reward transaction, standing, events, or consumed cargo and with its initial deterministic sequences. Meridian returns to exact MONITORING with no observed source, schedule, detection, event, or consumed Research event ID. Warnings return to exact CALM, null observed Research/deadline sources, fixed scheduled tick 4200, a null current stage, empty completed-stage/event arrays, and their first event sequence. Finale state returns to exact DORMANT, with no source warning, current/completed stage, terminal marker, or finale event and with its first event sequence. Music/SFX and reduced-effect preferences remain unchanged because they are not world state. During active Conveyor placement, the same keys rotate counterclockwise instead. The terrain, roads, scenery, and authored faction structures remain unchanged. This test control is deliberately omitted from ordinary in-game instructions.

Placement-art review mode

The Milestone 04 non-mutating review remains available at http://127.0.0.1:4173/?debug=1&review=placement&case=menu-open. In a debug-enabled development session, press P to toggle the review, use [ and ] to cycle its authored cases, and press Escape to close it. Review fixtures cannot create, remove, or alter ordinary world state.

Production review mode

Open http://127.0.0.1:4173/?debug=1&review=production&case=<id> with one of these case IDs:

  • extractor-empty
  • extractor-nearly-full
  • smelter-starved
  • smelter-running
  • smelter-output-full
  • machine-unpowered
  • storage-partial

These isolated fixtures use the real simulation and real Canvas page. They may seed local machine inventories for verification, but they do not add a direct, manual, or global transfer shortcut. Shift+R restores the selected review case's own deterministic tick-0 snapshot.

Logistics review mode

Open http://127.0.0.1:4173/?debug=1&review=logistics&case=<id> with one of these case IDs:

  • straight-eastbound
  • northbound-line
  • corner-path
  • extractor-output
  • conveyor-to-smelter
  • smelter-to-storage
  • blocked-destination
  • full-smelter-input
  • full-storage
  • invalid-resource-smelter
  • two-sources-one-destination
  • complete-chain

These isolated fixtures use the real logistics simulation and Canvas renderer. Use [ and ] to cycle cases. Shift+R restores the selected scenario, including its item IDs, inventories, belt progress, audit counters, time, speed, and placement direction.

Foundry review mode

Open http://127.0.0.1:4173/?debug=1&review=foundry&case=<id> with one of these case IDs:

  • phase-0-core
  • construction-site-active
  • phase-1-extraction
  • phase-2-processing
  • ore-moving
  • phase-3-annex
  • storage-receiving-plates
  • phase-4-trade-ready
  • paused-mid-construction
  • reset-phase-0

These fixtures use the real Foundry simulation, ownership rules, production/logistics systems, event log, and Canvas renderer. Use [ and ] to cycle cases. Shift+R restores the selected case's exact state; the paused case remains frozen until resumed.

Trade review mode

Open http://127.0.0.1:4173/?debug=1&review=trade&case=<id> with one of these case IDs:

  • offer-locked
  • offer-available
  • contract-accepted
  • station-loading
  • station-ready
  • packet-in-transit
  • trade-completed
  • insufficient-cargo
  • paused-in-transit
  • reset-offer-locked

These fixtures use the real Foundry readiness signal, contract, Trade Station, physical Plate route, packet timing, construction reward ledger, standing state, and Canvas renderer. Use [ and ] to cycle cases. Shift+R restores the selected case exactly; the paused transit case does not advance until resumed.

Research review mode

Open http://127.0.0.1:4173/?debug=1&review=research&case=<id> with one of these case IDs:

  • monitoring
  • waiting-for-trade
  • scheduled-response
  • unusual-reading
  • paused-before-detection
  • late-trade-response
  • reset

These fixtures use the real Research clock/state machine, canonical trade-completion shape, sensor animation, selected status, notification, and reset boundary. Use [ and ] to cycle cases. Shift+R restores the selected case exactly; paused cases remain frozen until resumed.

Warning review mode

Open http://127.0.0.1:4173/?debug=1&review=warnings&case=<id> with one of these case IDs:

  • calm
  • awaiting-warning
  • sensor-pulse
  • sky-shift
  • shadow-pass
  • signal-breakup
  • paused-before-shadow
  • reset

These fixtures create the canonical Research prerequisite through the real Research state machine and then use the real warning state, renderer, notices, options, audio controller, and reset boundary. They do not seed a reward, alter player resources, or run a separate decorative warning clock. Use [ and ] to cycle cases. Shift+R restores the selected case exactly; awaiting, stage, and paused cases remain frozen for stable visual comparison.

Finale review mode

Open http://127.0.0.1:4173/?debug=1&review=finale&case=<id> with asteroid-visible, incoming-confirmed, near-impact, impact, destroyed, ending, ending-reduced-motion, or ending-reduced-flash. These frozen fixtures use the real Research, warning, finale, renderer, options, and audio paths while leaving the player economy, trade, and faction state unchanged. Use [ and ] to cycle cases; Shift+R reconstructs the selected fixture with the same exact ticks, IDs, provenance, and presentation override.

The acceptance-only route ?debug=1&acceptance=finale seeds the canonical real ASTEROID_VISIBLE boundary, then advances through the ordinary finale processors to ENDING in about seven real seconds. It exists only to verify the continuous exact-tick path and the normal Enter-to-new-game restart; it is not an ordinary-play shortcut or a second renderer.

Current release boundary

Milestone 14 completes the single-playthrough MVP release candidate. The release includes the opening screen, compact controls reference, optional monotonic objectives, pause and confirmed clean restart, independent music/SFX controls, reduced-flash and reduced-motion modes, restrained event communication audio, deterministic dist/ packaging, and separated development fixtures. The underlying game remains the exact Milestones 1–13 path: normal gameplay through tick 4719, a one-time stop at impact, destroyed and ending states, and an ordinary clean restart with presentation preferences optionally retained. The strict warning deadline also guarantees the tragic ending if the player does not finish the optional progression path; it never auto-completes that path.

The certified ordinary live audit used only public controls. It observed the Generator at tick 605, Extractor at 1206, functioning factory at 1869, Foundry acceptance at 2409, visible Trade Station cargo at 3026, contract completion at 3078, Meridian at 3600, and the ending at 4730. The uninterrupted run took 236.350 seconds of 2× gameplay (236.847 seconds from opening to ending); the authored 1× timeline remains exactly 07:53. Player reading and placement time make an actual first run somewhat longer.

Milestone 14 acceptance passed with 354 automated tests, all 75 audited visual assets, a deterministic 149-file release build, all twelve requested real release Canvas screenshots, and zero browser or server errors or warnings across development, production, and reduced-effects production runs. The current public-release suite contains 356 tests after adding GitHub Pages workflow and project-subpath regression coverage.

The implementation, generated visual/audio families, development tooling boundary, reference-image status, and third-party audit are recorded in CREDITS.md.

Known limitations

  • The map, Foundry expansion, contract, Meridian response, warning sequence, catastrophe, and ending are handcrafted and deterministic rather than procedural.
  • There is one production line, one Foundry contract, and one ending. There is no save system, demolition/refund action, mobile control scheme, gamepad support, generalized market, strategic faction AI, or combat. The finite construction wallet funds the intended line, Trade Station, and eight Conveyors; excessive unnecessary belt placement can still exhaust it, so restart is the only recovery from deliberate overbuilding.
  • Final audio mixing/mastering and optional compressed OGG/MP3 delivery remain polish; the release uses the reproducible WAV prototype masters.
  • The release intentionally contains no automatic or narrative time loop, retained knowledge, trust, persuasion, planetary defense, alternate timeline or ending, dialogue branch, or post-impact progression.

Earlier milestone-number prefixes retained in prompt, audit, and screenshot filenames are legacy traceability names; milestone numbering in PLAN.md is canonical.

About

A tragic pixel-art factory strategy game built with HTML Canvas.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages