Commit Graph

8 Commits

Author SHA1 Message Date
Christian Semmler
a588e3bb67
Disable all NPCs when maxActors=0
Allow the game room server to accept maxActors=0 (previously floored
at 5). When received, the client disables extra actor spawning, camera
animations, and continuously purges all extras including the ambient
NPCs (mama, papa, brickster) that PurgeExtra(TRUE) deliberately skips.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-13 16:05:55 -07:00
foxtacles
569c8b467b
Separate extensions (#18)
* WIP

* WIP

* Make camera the single source of truth for broadcast state

Remove redundant local copies of walkAnimId, idleAnimId, and
displayActorIndex from NetworkManager. BroadcastLocalState now reads
these from the camera's Controller, eliminating dual-copy sync issues.

Additional cleanup:
- Early-return on null cam in SendEmote/HandleCustomize for clarity
- Only consume camera-dependent pending requests when cam is available
- Move local name bubble creation from BroadcastLocalState to Tickle
- Remove dead NetworkManager::SetDisplayActorIndex method

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Fix clang format

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 23:12:07 +01:00
Christian Semmler
9e8ecd6d44
Move routing info into message header, make relay type-agnostic 2026-03-08 10:21:36 -07:00
foxtacles
eb6d2b8728
Sync sky light (#9)
* Sync sky color and light position in multiplayer

Add ENTITY_SKY and ENTITY_LIGHT to the WorldEvent system so the host
controls sky color (hue/saturation via observatory sun/moon/palette
buttons) and light position (globe arrows) with the same
host-authoritative pattern used for plants and buildings. Non-host
players send requests to the host who applies and broadcasts. Sky/light
state is appended to the world snapshot so joining players get the
current values.

https://claude.ai/code/session_01X2cPVQEo7c92wpWA7QPPMG

* Clean up sky/light sync: remove debug logging, DRY apply logic, fix host routing

- Extract ApplySkyLightState helper to deduplicate sky/light apply code
  between RestoreSkyLightState and HandleWorldSnapshot
- Remove all SDL_Log debug calls and SDL_log.h includes
- Remove dead OnWorldEnabled method from WorldStateSync (replaced by
  OnHostChanged in OnSaveLoaded)
- Fix HandleSkyLightMutation host path: return FALSE to let local
  switch case proceed, instead of duplicating via ApplyWorldEvent
- Simplify isle.cpp HandleControl: split observatory cases into
  individual switch arms with single early-return multiplayer hook
- Add save load hooks to sync world state with multiplayer peers
- Fix player count to exclude local player without valid actor
- Support broadcast snapshots (targetPeerId=0) in relay server

---------
2026-03-08 05:55:00 +01:00
Christian Semmler
853e8981fa
Control NPC count per room 2026-03-07 14:58:27 -08:00
foxtacles
a9747dec11
Character customization (#8)
* WIP: Add character customization to multiplayer

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Refine character customization: fix message buffering, DRY up code, request-based model

- Register NetworkManager with TickleManager via HandleCreate hook in
  LegoOmni::Create(), so packets are processed continuously instead of
  buffering between Connect() and OnWorldEnabled()
- Spawn unspawned remote players in OnWorldEnabled() (created before
  world was ready)
- Switch to request-based customization: HandleROIClick sends
  MSG_CUSTOMIZE to server, server echoes to all peers, HandleCustomize
  applies state and plays effects
- DRY up SwitchVariant to delegate LOD cloning to ApplyHatVariant
- Add ApplyChange helper consolidating the switch-on-changeType pattern
- Fix InitFromActorInfo to derive dependent color parts from independent
  parts (matching Unpack rules)
- Remove dead code: m_hasBeenTicked, ApplyCustomizeChange on
  RemotePlayer, m_localCustomizeState on NetworkManager
- Add null ROI checks in HandleCustomize for unspawned players
- Move MSG_CUSTOMIZE constant to shared protocol.ts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Fix

* Fix character customization bugs from code review

- BUG-1: Add bounds check in SwitchColor to prevent OOB access from
  unvalidated network input (p_partIndex could exceed array bounds)
- BUG-2: Enforce allowRemoteCustomize on receiver side in HandleCustomize
  (was only checked on sender side, byppassable by malicious client)
- BUG-3: Document stale-state sound asymmetry for remote targets
- OBS-1: Remove unused bodyVariantIndex from CustomizeState (never
  modified, wasted 3 bits per state message)
- NAME-1: Fix p_ prefix convention on ApplyCustomizeChange parameters
2026-03-07 23:20:55 +01:00
Christian Semmler
5b56db3c33
Add room management, relay capacity, and rejection handling
- Remove hardcoded multiplayer config from emscripten config.cpp
- Add relay HTTP endpoints for room preview (GET) and creation (POST)
  with capacity check, CORS headers, and configurable max players
- Add WebSocket rejection detection (room full/503) via onclose flag
- Add CheckRejected extension call in IsleApp::Tick for clean shutdown
  through SDL_APP_SUCCESS path instead of calling exit()
- Set Module._exitCode in JS for sessionStorage-based toast after reload
2026-03-01 14:37:08 -08:00
Christian Semmler
dac40932a6
Refactor relay server into separate modules, fix Docker signal handling
Split relay.ts into protocol.ts (constants, binary helpers), gameroom.ts
(Durable Object), and a thin relay.ts entry point. Replace magic numbers
with named constants matching protocol.h. Run wrangler directly as PID 1
in Docker so Ctrl+C shuts down gracefully instead of being swallowed by npx.
2026-03-01 10:27:52 -08:00