SOURCE / PINNED RELEASE
Made of little things.
Crossfire
- Release
- 9614abe48623…
- Author-recorded commit
- 6f6c8299e2fb…
- License
- LICENSE
- Author’s source reference
- nostr://npub1n8ga89w8h6tvwamxusfyzexw8gjy84yxu9rxgnmk955cxtml4ujswzxydd/wss%3A%2F%2Fgit.napplet.soy%2F/n-347ab685aef
Archive hash verified: 34d5295141b419db…. The source-to-build association is the author’s claim; it has not been independently rebuilt.
# Crossfire
A free-for-all arena for 2–8 guests, first to seven eliminations. A player can
open an empty arena and practice moving while others arrive. Rounds restart
five seconds after a win. Desktop: WASD/arrows, mouse aim, hold click/space.
Touch: left movement stick and right aim/fire stick. Solo practice has one bot.
## Authority and networking
Required NAPs: CVM and WebRTC. Soy's listed room service discovers arenas with
capacity eight; no fixed eight-person queue. The creating actor is the stable
simulation host, identified by its public actor prefix in the room name. Room
membership renews every two seconds. A host departure ends the arena; players
can find a new one. There is no host migration or competitive anti-cheat.
The host simulates at 60 Hz and sends compact updates at 20 Hz. Every guest
connects directly to the host in one stable room session; guests never forward
traffic or upload world state. The host accepts input only from current CVM
members. Client prediction and snapshot interpolation keep rendering responsive.
Protocol: crossfire-8-v5. Details and verification are below. No direct network,
signer, browser persistence, relay escape hatch, or cross-napplet API is used.
## Form factor
Compact frame-filling toolbar and canvas, no title chrome. Optional runtime
theme with a dark fallback. Desktop regular/wide views show more arena; portrait
views follow the player. Touch sticks use 88px targets for gameplay. Below
280×240, keep menu controls and show an enlarge notice during play. No settings
or persistent state. Guest play does not require a Nostr profile.
## Verification
Run `pnpm verify`, `node --test tests/game.test.mjs`, `pnpm test:conformance`,
and `soyli check`. Reference-shell conformance skips manifest evidence, wire
traffic and lifecycle when not supplied; it is not a multiplayer test.
## Public lobby update
Expose listed Soy rooms through CVM: Host game creates a capacity-eight room;
Join targets exactly the selected room, never silently creates another. Show
arena identifier, occupancy, full/empty/loading/error states and Refresh. Poll
visible idle lobby every five seconds. No new domains, settings or protocol.
Keep existing host identity prefix for compatibility. Compact full-frame room
list scrolls internally at tiny/short sizes; wide frames use multiple columns.
Theme and gameplay minimum remain unchanged. Host connection consent remains
runtime-owned. Verify create, discovery, selected join, leave and stale room.
## Player identity and named arenas
Optional identity SDK getPublicKey/getProfile/onChanged supplies the local label
(displayName, then name, then shortened public key; Guest when signed out).
Profile failures do not block gameplay. Names are bounded plain text carried
over the authorized host connection and host snapshots; these casual
peer-reported labels are not proof of control of a Nostr account. No signer use.
Player names are included in keyframe rosters. Room title input is limited to 48
characters; the backend name retains the 16-character authority prefix plus
separator and human title, within Soy's 80-character limit. Render titles with
textContent. The full-frame lobby and optional theme contract are unchanged.
## Responsive multiplayer (protocol v5)
Guest movement is predicted at 60 Hz with the shared collision function, then
reconciled against host acknowledgements by replaying unacknowledged commands.
Aim and cosmetic local projectiles respond immediately; damage, kills, health,
respawn and round results stay host-authoritative. Remote players interpolate
buffered snapshots, with bounded extrapolation and teleport/life discontinuities.
Use one stable room session: host has no transport allowlist, guests allow only
the host. This is a star, not a mesh: guests never connect to each other and never
forward world state. The host validates every sender against live CVM membership.
This avoids reopening every existing link when a player joins. The shipped host
supports eight remote peers per session; seven are needed. No new infrastructure,
no direct browser networking, and no changes to host consent or NAP APIs.
Guests send only sequenced input batches and occasional profile metadata. Host
sends quantized state deltas at 20 Hz, with full keyframes once per second and
on peer joins. Bullet spawn/removal updates avoid repeating trajectories. Delta
base IDs detect gaps; a new client waits for a keyframe. Reliable ordered JSON
is the existing NAP transport; application send backpressure keeps one in-flight
send and does not accumulate obsolete snapshots.