Extends the v2.1.0 React-friendly snapshot pattern (originally on
SessionDataManager / RoomSessionManager) to two more session-state
holders the React client reads frequently:
- IgnoredUsersManager.getIgnoredUsersSnapshot(): ReadonlyArray<string>
- GroupInformationManager.getGroupBadgesSnapshot(): ReadonlyMap<number, string>
Both follow the same shape: lazy-frozen snapshot, cached until the
underlying state mutates, then invalidated and a dispatched event lets
the React client rebuild via useSyncExternalStore.
Two new NitroEventType members carry the invalidation signal:
- IGNORED_USERS_UPDATED — dispatched by IgnoredUsersManager whenever
the list changes (initial load, add, remove, queue-truncate case 2).
- GROUP_BADGES_UPDATED — dispatched by GroupInformationManager only
when the incoming HabboGroupBadges payload contains at least one
new or changed mapping (no-op refresh stays quiet).
This lets the user-info popup, profile page, friend/guild filtering,
and any other consumer share a single read through useSyncExternalStore
instead of each subscribing to the underlying message events
independently.
API additions are interface-respecting and backwards-compatible — the
existing `isIgnored(name)` / `getGroupBadge(groupId)` accessors stay
untouched.
IRoomSession.sendWhisperGroupMessage(userId) was declared in the
interface and implemented in RoomSession by sending 'new
ChatWhisperGroupComposer(userId)' — but no such composer class
exists in the renderer (the file was never created). The only
whisper composer is RoomUnitChatWhisperComposer, which takes
(recipientName, message, styleId), not a userId.
No client call site references sendWhisperGroupMessage (grep across
Nitro-V3/src returned zero hits). Removing the dead interface method
+ broken impl is safer than inventing a ChatWhisperGroupComposer
class with no server-side handler.
The IRoomSession interface was missing three things that have always
existed on the RoomSession implementation:
- `password: string` — the room session's join password (used by the
reconnect flow in RoomSessionManager).
- `sendBackgroundMessage(backgroundImage, backgroundStand, backgroundOverlay, backgroundCard?)`
— sends the profile-background composer (used by the React client's
BackgroundsView).
Plus a signature relaxation:
- `sendChatMessage` / `sendShoutMessage` `chatColour` is now optional.
The implementation already accepted `undefined` (the composer forwards
it through), and every historical call site in the React client passes
only 2 args — making the 3rd optional simply types reality.
Net renderer typecheck: 26 → 23.
The change also drops 7 errors on the consumer side
(see ../Nitro-V3 typecheck after the workspace link picks this up).
CLAUDE.md gotchas updated to reflect the new interface contract.
Each workspace package was still pinning `typescript: ~5.5.x` or
`~5.8.2` in its own devDependencies even though the root bumped to 6.0.3
in 60b1143. The pins were dead (yarn 1 hoists from root) but they're
misleading when reading a single package.json. Bring them all to
`^6.0.3` to match the root.
Other:
- @thumbmarkjs/thumbmarkjs 1.8.1 → 1.9.0 (root + communication package)
- yarn.lock regenerated from a clean install (vitest 4 hoisting was
flaking on the patch vite bump; reverted vite to ^8.0.10)
Adds CLAUDE.md at the repo root: short project context for future
sessions — stack, the 12-workspace layout, the React-friendly v2.1.0
additions (`subscribe()`, `subscribeMessage()`, snapshot getters), build
scripts, and known gotchas (`SessionDataManager.getUserData` does NOT
exist; sendChat* expects 3 args; dispatchEvent is sync).
- parse extra room snapshot data such as hotel time, room item limit and group context
- expose richer furni metadata including flags, dimensions and teleport targets
- expose richer user metadata including room-entry fields and ids needed by inspection tools
- keep session and room engine models aligned with the new wired monitor/inspection flow
- Animation canvas uses full landscape height for proper vertical positioning
- Animation assets always loaded from room collection
- Fallback to default plane when specific plane not found