# Copper movement lab — 27 October 2026

A playable, editable JavaScript experiment with an original copper-orange tenrec character on the original Sonic the Hedgehog REV00 Green Hill Act 1 reference terrain. This is a movement study for a future new game. It is not a complete reconstruction of the original game.

Run `python -m http.server 8776 --bind 127.0.0.1` in this folder, then open <http://127.0.0.1:8776/>. `start-lab.ps1` runs that command on Windows. The page needs HTTP because its modules load local JSON and images. The game itself has no package installation, emulator or external service dependency.

## Controls

The **Light & weather** panel adapts the supplied Fighting in the Streets handoff. Use Sunset, Rain, Snow or Storm for a running preview, or Original for the reference rendering. Clock speed affects only the environment. See `ENVIRONMENT-HANDOFF.md` for exact features, provenance, verification and the remaining independently painted scenery work.

USB/Bluetooth controllers are supported through the browser's [Gamepad API](https://www.w3.org/TR/gamepad/). Windows detects an HID-compliant game controller on this machine. A device must also be exposed by the browser to appear in this page's controller selector; this is not a raw HID driver.

Refresh the page after this update. Click the game and press a controller button to let the browser detect it. Release the controls, then press Start/Menu to play. On a standard controller, D-pad or left stick moves, all four face buttons jump, and Start/Menu pauses or resumes. Controller input feeds the same digital held states as keyboard input; physics constants and timing are unchanged.

For a generic HID layout, use **Map controls** below the game. Leave the pad at rest briefly, then assign Left, Right, Up, Down, Jump and Pause, releasing between each. Directions accept buttons, sticks or supported eight-way hat axes; Jump and Pause require buttons. Setup pauses the game. Escape or Cancel setup discards an unfinished mapping; Use defaults restores the automatic layout. The dead-zone slider filters stick drift. Mappings are stored per controller layout in this browser; storage failures leave session controls usable.

The game pauses when the controller disconnects or the window loses focus. Release the pad before resuming so stale held buttons do not move the character or trigger Start. Keyboard and touch inputs remain available.

- Left/right arrows or A/D: move. Space, Z or X: jump. Hold longer for a higher jump.
- Down/S: crouch; while moving without a horizontal direction held, enter a roll. Forward input does not accelerate an existing roll.
- Up/W: look up when stationary. Down shifts the view the other way. Moving or ordinary airborne movement restores the view according to the original routines.
- P: pause/resume. R: restart. The buttons also pause, restart or advance a single simulation update.
- Start-point selector: opening, first bridge, steep uphill, loop approach or roll tunnel. The loop study begins at ground speed9 so it can demonstrate all four terrain orientations immediately.
- Test assists: “No enemy hitbox” skips harmful enemy/projectile/spike contact without killing enemies or bouncing the player. “Keep rings when hit” retains rings while preserving the hit reaction. Attempts are unlimited; falling restarts at the checkpoint or selected study start.

## Why Copper can look still while the scenery moves

Screen position equals world position minus camera position. When both Copper and the camera move right by six world pixels, Copper remains in the same place on screen.

The yellow overlay shows the original horizontal follow window, screen X144 through159. The camera waits within it, then follows. The original rightward cap is16 pixels per update; the REV00 left branch has no matching cap. Normal ground vertical follow is capped at6 pixels, fast movement at16, and shifted look at2. Airborne motion has a64-pixel window around the default vertical follow position. Rolling uses the original five-pixel camera correction. The panel displays world, camera and screen coordinates independently.

The background also moves separately: REV00 clouds and distant mountains follow at3/8 camera speed, hills at1/2, and water scanlines interpolate toward camera X−512. Source Y is38−floor(cameraY/32). The camera bottom boundary changes after X6016 using the original dynamic-boundary step rules. No smoothing or interpolation is added to the physics or camera.

## What is close to the original code

The controller retains signed8.8 speed arithmetic,16.16 position increments, original sine/angle tables, update order, takeoff integration skip, acceleration/braking/friction, variable jump cut, near-apex drag, slope forces, rolling, roll-jump steering lock, body-radius quirk, four terrain sensor orientations, angle-dependent landing rules, slow-wall detachment and loop-route switching. See `physics-fidelity.md` for routine-by-routine details.

Collision comes from the actual original layout, chunks, blocks, normal/rotated height profiles, solidity bits and flip flags. It is not inferred from the displayed artwork. The foreground has original world registration and an original tile-priority mask. Object positions and155 rings come from the original records.

The independent implementation is compared with the unchanged original ROM in private development diagnostics. The playable page does not load that diagnostic core or any original ROM file.

## Verification and practical limits

- Movement: six selected traces,880 updates,13 fields per update,11,440 exact field comparisons with zero differences. These include running, tap/held jumps, neutral rolling, roll-jump lock and a90-update full loop traversal.
- Terrain queries:7,952 exact original-routine distance/angle cases across four directions, flips, solidity bits and both loop routes.
- Camera: five opening traces,790 updates,4,740 exact comparisons with zero differences. Nonzero teleport background initialization and later dynamic-boundary events are outside that equivalence scope. Four transient loop-teleport sampling differences are retained separately in the private camera observation report; no general camera equivalence claim is made.
- Portable unit checks cover scalar movement, original-stage seams and fast/slow loop behavior, camera windows and boundary steps. Separate object checks cover source behavior and an opening bridge crossing.
- Asset checks cover original mapping crops/pivots and actual palette contexts. Prototype bridge/platform palettes and yellow springs were decoded from the original palette/tile bytes; the earlier preservation gallery remains unchanged.
- Offline Canvas renders and a real-page-module bootstrap with DOM stubs verify asset loading, input wiring, readouts and section/restart controls. These are not interactive browser testing. Browser control was unavailable because local browser use is disabled in Work settings.

Unfinished: full original object-slot/respawn rules and collision ordering; monitors, Chopper/Newtron and several later objects; collapsing ledges and swinging-platform behavior; ring scatter; complete spring/spike `SolidObject` geometry; full animation and sound drivers; animated terrain/palettes; complete sprite/plane priority ordering; original lives, level-clear and save systems. This build is silent. The original preservation website retains its separate music and sound-effect players. No complete Act1 playthrough or full game compatibility is claimed.

## Character and provenance

`assets/copper-tenrec-sheet.png` is a new24-pose transparent sprite sheet made with the built-in ImageGen tool from the original tenrec concept. The prompt and spacing refinement are saved in `assets/generation-prompt.txt`. `assets/sprite-spec.json` supplies explicit crops/pivots because generated pose spacing is not pixel-identical. The collision box remains independent of the artwork. The generated originals remain in the Codex image output folder.

Sonic reference: Sonic Retro `s1disasm` commit `89c0e0e06b51fd9ebac44d988e4a89bd643fd031`, Revision0, FixBugs0. The reference build matches the supplied canonical ROM SHA256 `46160baa06362c711c9f1a5017cb7371026444936c8af5e93a78996cf32ff2a6`. Geometry/art source offsets and hashes are retained in `level/level-provenance.json` and `level/object-art/manifest.json`. Original Green Hill art is SEGA reference material for this study; the future course and character assets are separate work.

The original ROM, frozen releases, preservation website and previous dated entries have not been changed by this prototype. This is a local study build; it has not been published to the live website.

## Editable files

- `physics.mjs`: player movement and terrain contacts.
- `level/stage.mjs` and `level/data.json`: original course data, sensors and loop routing.
- `objects.mjs`: implemented object behavior and contact responses.
- `camera.mjs`: scrolling, look offset, dynamic boundary and background scanlines.
- `renderer.mjs`: character animation and scene drawing.
- `main.mjs`, `index.html`, `style.css`: local player interface and fixed60Hz update loop.
- `gamepad.mjs`, `controller-ui.mjs`, `controller.css`: controller polling, remapping, dead zone, local profiles and setup interface.
- `assets/`: the new character artwork, frame specification and generation record.

Portable tests: `npm test`, or `node --test tests/physics.test.mjs tests/physics-stage.test.mjs tests/camera.test.mjs tests/gamepad.test.mjs level/stage.test.mjs`. Controller tests use synthetic snapshots, including custom layouts, held jump, pause edges, reconnect/focus changes and storage/API errors. The actual page module also reaches the same180-update endpoint using controller and keyboard input. Physical-controller play testing remains unverified because browser automation is disabled in Work settings.

The bundled terrain comparison uses recorded expected distances/angles and does not instantiate an emulator. Private `tests/native-reference.cjs` and native state/core files stay in the full preservation workspace and are excluded from the standalone ZIP. Extraction tools live in the full preservation project's `tools/` folder and retain their original source requirements.


## Copper Test website edition — 2026-10-27 / 0.1.4

The public page is named **Copper Test**, as requested. It retains the original Copper character, JavaScript movement study, gamepad mapping, visible screen-blended lens flare and supplied weather presentation. A separate Java Sonic first-stage page lives at `/genesis/sonic-the-hedgehog/lighting-test/`. Original frozen local archives are retained. Copper remains an incomplete reference-course experiment; it is not the Java reconstruction.

Current publication checks: 49 portable tests passed, plus actual page-module initialization/input tests with DOM stubs and native Canvas. Interactive browser and physical controller play remain unverified because local browser control is disabled in Work settings.
