SOURCE / PINNED RELEASE
Made of little things.
GRAV / RIFT
- Release
- 288aa261ce07…
- Author-recorded commit
- c549b5a4e17e…
- License
- LICENSE
- Author’s source reference
- nostr://npub182jczunncwe0jn6frpqwq3e0qjws7yqqnc3auccqv9nte2dnd63scjm4rf/wss%3A%2F%2Fgit.napplet.soy%2F/n-8a7361981e8
Archive hash verified: e52a01aff70810b3…. The source-to-build association is the author’s claim; it has not been independently rebuilt.
# GRAV / RIFT
A playable physics salvage-combat prototype. Fly a tug through an industrial wreck field, capture debris with gravity, tear down bolted structures, and throw the wreckage at machines. The reactor Warden's armor can be torn off and reused against its exposed core.
## Play
```sh
soyli dev
```
Open the printed hosted preview URL. Choose **Foundry · Gravity on** for floor salvage and demolition, or **Orbital graveyard · Zero G** for floating wreckage. Then choose **Deploy tug** for a normal run or **Practice range** for regenerating hull. Stop the preview with Ctrl+C afterward. Workspace tooling and host boundaries: [docs/napplet-space.md](docs/napplet-space.md).
| Control | Action |
| --- | --- |
| WASD / arrows | Fly with momentum |
| Pointer | Turn the tug and direct the vortex ahead of it |
| Hold right click or Space | Gather debris; Surgical grabs the one object under the cursor |
| Release right / Space | Drop the remaining cargo without firing |
| Left click / F | Fire while gathering, or hurl the single Surgical object |
| R | Cycle Volley → Stream → Clusters |
| Hold Tab | 5%-speed radial selector; hover and release Tab, or click choices |
| Mouse wheel | Rotate the object held by Surgical |
| 1 — Orbit | Fast directional debris vortex, broad volley |
| 2 — Compress | Hold to charge a concentrated blast |
| 3 — Rip tether | Focus on armor joints or dismantle a small drone |
| 4 — Surgical | Precisely extract, drag and hurl one object or living enemy |
| U | Spend salvage on field range, vortex power and hull repair |
| P / Escape | Pause, help, sound, reduced effects and collision hull inspector |
| Touch | Stick flies; FIELD gathers/drops; FIRE discharges; selector changes modes; Surgical drags directly on the canvas |
The 4800×1000 stage starts with 224 smaller debris pieces: floor scrap in Foundry, floating wreckage in Zero G. A wider camera view and smaller tug make the wreck site feel larger; flight speed is increased to cover the distance. Short landscape screens follow the tug vertically.
The vortex sits ahead of the tug in its aim direction. Capture as much scrap as you can: there is no payload cap.
Three medium Striders walk through the floor debris in each site. Their cannons glow before firing a physical explosive shell. Aim your field at an incoming shell and hold to catch it (Surgical selects the shell directly); its ring turns mint and the HUD reads **SHELL SECURED**. Aim at the walker and press left mouse/F while holding to return it. Its fuse pauses while held; uncaught shells explode on contact or after six seconds. Touch auto-aim intercepts incoming shells and directs a secured shell back at its sender.
Striders and the Warden share a modular rig. Surgical can pull off individual leg
segments; losing legs reduces movement and support. Extract the violet **gravity
shield cell** to grab the living body with its remaining limbs. Hold RMB on the
part, drag it, and use LMB to hurl it. The gravity shield protects against capture;
the Warden's separate armor still protects its core from damage.
Discharge is independent of the field. **Volley** launches all cargo, **Stream**
feeds one piece every 75 ms, and **Clusters** sends five pieces every 380 ms. Hold
RMB to gather and LMB to fire simultaneously. Let go of LMB to stop firing while
continuing to gather; let go of RMB to drop the remaining cargo without a shot.
Stream and Clusters also work when LMB is held before RMB starts collecting.
Surgical always fires one selected object.
Strip at least four armor plates to expose the Warden's core. Destroyed enemies have a 35% chance to drop an amber energy cell. Throwing arms a cell: its first contact with a body, floor or ceiling detonates it. Hard impacts and nearby blasts also trigger loose cells. Pressure waves throw nearby scrap, damage machines, break supports and chain-react through other cells. Small enemies yield 40 salvage; medium Striders yield 75; torn plates yield 25. Three upgrades cost 50, 95 and 140. A debris supply replenishes near the tug when ammunition runs low (on the floor in Foundry). The run ends when the core is destroyed or the tug loses its hull.
## What the prototype proves
- Original procedural pixel sprite atlas with convex bodies extracted from opaque pixel boundaries.
- Fixed 120 Hz simulation, convex SAT collisions, angular impulses, friction and impact fragmentation.
- Four gravity modes and three independent release patterns, a fast mouse-directed vortex, uncapped payloads, charged volleys, shielding, explosive salvage and upgrades.
- Two sites: strong downward gravity with floor scrap, or true zero gravity with floating scrap. The tug auto-hovers in both.
- Bolted gantries and salvage racks with connected supports; unsupported sections fall as reusable convex bodies.
- Flying drones, wheeled sentries, four-legged medium artillery Striders with catchable shells, and a walking boss with animated leg segments and six independently breakable armor joints.
- Complete start, practice, pause, win, loss and retry flows; responsive keyboard/pointer and multi-touch controls.
- Optional host-scoped personal best / audio preference persistence, with a usable session-only fallback.
Attached rig joints use driven poses; severed parts become ordinary convex bodies. Full constraint-driven ragdolls and trajectory/ricochet prediction remain future work.
These are two selectable versions of one combat run, not a campaign. Armor morphability is a rig of detachable rigid pieces, not continuum soft-body metal deformation. Background terrain is an authored tunnel opening into a reactor bay, with flat collision bounds. Additional authored terrain and campaigns, imported AI sprite sheets, deeper enemy rigs, gamepad support and more upgrades remain future work.
## Structure
- `src/game/sprites.ts`: deterministic pixel sprites, atlas and alpha-derived collision hulls.
- `src/game/physics.ts`: hull generation, convex collision detection and impulse response.
- `src/game/game.ts`: combat, gravity fields, armor joints, progression and effects.
- `src/game/walkers.ts`: articulated stride, foot/debris response and cannon timing.
- `src/game/rigging.ts`: shared mount graph, joint stress, subtree detachment and role-based capabilities.
- `src/game/enemy-rigs.ts`: Strider/Warden blueprints and articulated poses.
- `src/game/launcher.ts`: volley/stream/cluster discharge cadence.
- `src/controls/radial.ts`: local slow-motion field and release selector.
- `src/game/structures.ts`: bolted assemblies and support connectivity.
- `src/game/world.ts`: shared stage dimensions, spawn positions and tug scale/speed.
- `src/game/render.ts`: pixel scene, articulated boss, field effects and hull overlay.
- `src/main.ts`: input, lifecycle, HUD, audio and optional SDK storage.
- [Design brief](docs/game-brief.md), [verification and captures](docs/verification.md).
No new runtime dependencies. The production artifact is one self-contained `dist/index.html`; all gameplay, art and sound are generated locally. There are no network, identity or relay requirements. The palette is app-owned in every host theme.
## Verify
```sh
pnpm verify
pnpm test:conformance
soyli check
# Keep soyli dev running in a separate terminal, then use its actual URL:
pnpm test:hosted -- http://127.0.0.1:PORT/
pnpm test:foundry -- http://127.0.0.1:PORT/
pnpm test:walkers -- http://127.0.0.1:PORT/
pnpm test:surgical -- http://127.0.0.1:PORT/
```
`verify` includes guidance checks, physics/combat regression tests, type checking and the single-file build. Hosted tests use the cached Playwright installed with the conformance CLI and require permission to launch a browser. They cover keyboard combat through victory, host storage and real Chromium multi-touch emulation. They temporarily make the host iframe fill the exact test viewport and remove the manager's 300px minimum; production host behavior is unchanged.
