SOURCE / PINNED RELEASE
Made of little things.
Limb Race
- Release
- 6a8ae4fc626e…
- Author-recorded commit
- 008c01ee6454…
- License
- LICENSE
- Author’s source reference
- nostr://npub182jczunncwe0jn6frpqwq3e0qjws7yqqnc3auccqv9nte2dnd63scjm4rf/wss%3A%2F%2Fgit.napplet.soy%2F/n-c2869f12ad8
Archive hash verified: 7be8492d1f89b891…. The source-to-build association is the author’s claim; it has not been independently rebuilt.
# Limb Race build spec
- Purpose: draw a rotating racer, time it over obstacle courses, compare designs and times.
- Product: ten deterministic courses; Classic locks limbs, Live Draw applies edits immediately. The four original tracks retain separate shared boards per mode/material; the six challenge tracks keep personal times.
- Core physics and drawing run locally, fixed 120 Hz simulation, no network authority.
- NAPs: CVM for Soy shared scores; optional storage for designs and personal races, identity for a display name, theme for host chrome, config for appearance settings.
- Hard requirements: none. Offline racing is a complete core task; missing CVM disables shared rankings only.
- Shared-board identity is the authenticated scoped transport actor, not a verified Nostr profile. Names are labels. Scores are client-reported.
- Shared drawings use Soy v2 attachments as specified in the expansion below. Personal records additionally keep Live Draw change timelines.
- SDK helpers: cvm.registry.call/callTool, storage.getItem/setItem, identity.getPublicKey/getProfile/onChanged, themeGet/themeOnChanged. No relay escape hatches, social publishing or interop.
- Data: bounded local history under limb-race-v2; shared boards under CLI-generated author namespace, 16 board IDs, separating material and physics revision. Provider from generated backend context.
- Form: compact toolbar, course on top, white drawing canvas below; rankings beside drawing at regular/wide sizes, behind a Scores tab at compact sizes. Wide layouts expand the course and show more records.
- Floor: 240 × 320 because both track and drawing pad must remain usable; below that show an enlarge notice and preserve state. Short landscape uses reduced chrome and a smaller pad.
- Density: 13px base, 28px desktop controls; 44px coarse-pointer hit targets; large monospaced timing as game feedback.
- Theme: host background/text/primary apply to all chrome and derived tokens. Canvas sky derives from theme. The drawing paper stays explicitly white, as requested, and uses dark ink in both themes.
- Empty: inviting pad instructions and no fabricated score rows. Errors: compact retryable score status; storage failure keeps session progress and explains it was not saved.
- Pause: explicit button, automatic on focus loss/hidden tab; fixed simulation time never catches up hidden elapsed wall time. Resizing preserves normalized drawings.
## Second iteration
- Square normalized drawing bounds [-1,1] on both axes, including corners. Remove the circular guide and Wheel preset.
- Replace the old height-only contact test with two-dimensional terrain contact, including vertical risers. No horizontal motor force; motion comes from angular drive and contact.
- Add two leg-climbing courses with wheel-failure and successful-leg regression fixtures.
- Add independent Rigid/Bendy material selection, available with Classic and Live Draw. Bendy uses contact-loaded spring joints; rendering follows the collision shape. Material locks during a run.
- New board IDs separate physics revision, track, editing mode and material; no mixing with original times. Keep at most the host limit of 16 configured boards.
## Challenge track expansion
- Add six authored courses, bringing the selection to ten: progressively tighter ledges, uneven teeth, trenches, steep ramps and a final combination course. Every new course must have a verified valid drawing that completes it with both rigid and bendy limbs; starter shapes should not solve every challenge.
- Preserve the four original courses and physics-v2 rules/times. More difficulty comes from terrain, not hidden forces or changed motor settings.
- Track selection shows course number, difficulty, a complete terrain profile and a short obstacle description. The expanded list scrolls within the modal, with the close action visible on phones and short frames. Preserve the existing minimum frame and runtime themes.
- Personal records continue through optional SDK storage, with drawing and material. No additional NAP domains, requirements, relay access or networking. Keep the 16 existing shared boards. The six new challenge courses use personal records, with explicit in-app feedback and no calls to nonexistent shared boards.
## Shared creations expansion
- Attach the complete finish drawing to each shared personal best using the shipped `soy.boards.v2` contract. Encode normalized coordinates as integers in [-1000,1000], at most 8 strokes / 240 points, with attachment version 1 and physics version 2. Use new immutable board IDs ending `-draw1`; keep original personal history. Shared Live Draw entries explicitly show the finish drawing, while personal records retain the edit timeline.
- Read entry data on selection with the row revision. Reject stale or malformed attachments; never pair a new drawing with an old time. Allow inspecting and reusing another racer's drawing. Check advertised v2 support and explain older-host/provider failures.
- Add a compact segment-based level editor: add/reorder/remove flats, slopes, steps, drops and trenches; tune width/height; show the resulting terrain; save named drafts and test them with current limbs. Bound geometry, length and work before constructing race collision samples.
- Add Your levels and Community tabs to the existing track picker. Use optional STORAGE for local drafts and the supplied public `soy.app-data/1` helper for a `levels` collection, schema `limb-race.level`, version 1. SDK OUTBOX/IDENTITY carry calls; the helper observes the documented host policy. No relay escape hatch or invented collection service. Hard requires remain empty because local racing/editor work without public sharing.
- Publish only from a player's explicit action through host consent. Browse anonymously; identify authors by their signed public key. Preserve a failed draft and prepared change for retry; detect account changes, stale revisions, incomplete reads, invalid records and unavailable relays. Owners can update/unpublish; other players can play or copy into a new draft. Unpublish uses the documented public tombstone.
- A custom run retains the complete level data and title; published race identity includes the signed revision. Editing a local draft creates a new local revision. Never compare times across changed terrain or depend on a replaceable event as historical geometry.
- Known host gap: automatic dynamic custom-level boards are not implemented; the 16 configured board limit remains. Custom levels and existing challenge-pack courses keep personal times. This limitation is surfaced rather than faked through overloaded score fields.
- Keep the current 240×320 minimum, compact controls and whole-surface theme. Editor and library must work with touch at portrait and short landscape sizes. Large data/media uploads are unnecessary for this bounded geometry.
