Back to collection

Light Relay

Rotate mirrors. Route one beam through three optical puzzles.

Game · v1
PROJECT PREVIEW
Light Relay project preview

Prompt

Create a complete standalone light-relay.html with inline CSS and JavaScript: a three-chamber light-routing puzzle. No dependencies, network, storage, external assets, eval, forms, or audio. Include meta CSP exactly: default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; img-src data:; connect-src 'none'. Work inside iframe sandbox='allow-scripts' with an opaque origin. After synchronous initialization, call window.parent.postMessage({type:'pls-demo-ready'}, '*').

Visual direction: a near-black instrument panel (#080808), inset 7-by-7 square circuit board, thin gray cell borders, white labels, system monospace controls, a large condensed sans-serif LIGHT RELAY heading, warm amber active beam and cool cyan receiver. Keep color inside the game. This is geometric circuit visualization, not an illustration. Desktop: board left, compact mission/control panel right. Below 700px stack board before panel. Use readable rem text (body 16px, controls 14px), minimum 44px action targets, strong visible focus, no motion required, and fit at 320px without horizontal scrolling or clipped text. Display the primary puzzle in the first viewport with brief instructions: Rotate mirrors. Connect the light to the receiver.

Rules: 7 rows and 7 columns, coordinates below are zero-based [row,column]. Source occupies its listed cell and sends light east. Receiver occupies its listed cell. Walls absorb light. Empty cells transmit straight. Mirrors stay in their fixed cells and toggle between / and backslash on activation. Use direction indices E=0,S=1,W=2,N=3. Slash maps [3,2,1,0]; backslash maps [1,0,3,2]. Trace one cell at a time from source to outside board, wall, receiver, or repeated (row,column,direction). Only reaching receiver solves. Draw connected segments through cell centers with SVG over the board; make its layer pointer-events:none and aria-hidden. Actual mirror buttons below/above it must remain clickable. Keep lit-cell state and a plain text path description (one-based cell coordinates) available in a details disclosure, so light color is not the sole feedback. Use an aria-live status for changes, not frame updates. No timer.

Chambers, with mirror triples [row,column,orientation] (use '/' or backslash):

  1. FIRST CONTACT: source [4,0], receiver [1,6], mirrors initially [4,2,backslash],[1,2,backslash]; solution both '/'; walls [0,4],[2,4],[3,4],[5,4]. Optimal solution from initial board: 2 rotations.
  2. DOGLEG: source [5,0], receiver [1,6], mirrors initially [5,2,backslash],[2,2,backslash],[2,4,'/'],[1,4,backslash]; solution in that same order ['/','/','/','/']; walls [3,3],[4,4],[0,1],[6,5]. Optimal: 3 rotations.
  3. LONG WAY HOME: source [5,0], receiver [1,6], mirrors initially [5,1,backslash],[3,1,backslash],[3,3,'/'],[5,3,'/'],[5,5,backslash],[1,5,backslash]; solution ['/','/','backslash','backslash','/','/']; walls [2,2],[4,4],[0,3],[6,3]. Optimal: 6 rotations.

Render source as a right arrow and receiver as a ring, with visible S and R identifiers in their cells and accessible text. Render walls as crosshatch or #. Each mirror is a real type=button with data-cell='row,column', one-based accessible label naming row, column and slash/backslash orientation, and aria-pressed=true for slash. Clicking/Enter/Space toggles it, increments rotations once, saves undo history, retraces light, and retains focus. Board arrow keys move focus among mirror buttons in row-major order: Right/Down next, Left/Up previous, wrapping. Include a persistent legend.

Show chamber name, chamber number, rotations, optimal rotations, and session best (dash until solved). Add an ordered chamber selector; first unlocked initially, later chambers unlock only when the previous is solved. Undo reverts one rotation and decrements count, disables when empty; retain unlocks and bests on undo. Reset chamber restores its initial orientations/count/history and keeps session best/unlocks. Hint outlines the first mirror differing from its solution and announces its one-based coordinates, without rotating or incrementing count; clear old hint on rotation/undo/reset/chamber change. Hint usage must be visibly counted per attempt and recorded beside session best: best is lowest rotations, then fewest hints on ties. Undo does not erase hint usage. Reset sets attempt hints to zero. Solving unlocks the next chamber and enables Next chamber; final completion reads All three chambers connected. Re-entering any unlocked chamber starts its initial board. On solution keep mirrors and Undo available; further moves can unsolve without revoking earned unlocks. Provide Reset all that restores chamber 1, all initial states, no bests, no hints, and only first unlocked. Disable Next chamber when current board is not solved or final. Initial board must not appear solved. User text input is unnecessary.

Test inside an allow-scripts-only iframe with the exact CSP. Confirm all three chambers start unsolved and solve using the listed mirror orientations. Check rotation counts 2,3,6 from initial states, undo, reset, session best/hint tie handling, locked chamber buttons, next-chamber gating, final completion, hint coordinates without movement, Enter/Space and arrow focus, and full reset. Check at 320,375,768,1024,1440,1600px and 200% root text at 320px. Confirm no horizontal overflow, external requests, script errors, or storage access. Repairs identified during this build: explicitly set seven equal CSS grid rows so beam centers match cells; render the SVG above opaque mirror backgrounds while retaining pointer-events:none; allow narrow chamber buttons and board-header labels to shrink/wrap at 200% root text. Keep fixed board symbols small enough to fit each cell at enlarged root text, while body and controls still scale. Preserve every puzzle rule and control. Repair any other issues found and return the corrected standalone file. Report actual checks and any untested behavior; do not claim one-shot, pixel-identical, or cross-browser reproduction.