@genex-ai/multiplayer 0.12.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -65,7 +65,7 @@ for (const [id, p] of room.players) {
65
65
 
66
66
  Remote players glide instead of teleporting between network updates — see **[Smoothing remote players](#smoothing-remote-players)**.
67
67
 
68
- Each player also carries `p.avatarUrl` — the VRM avatar that player picked on their genex profile (guests get a per-session pick), verified server-side from their identity token so it can't be spoofed. Render each player's own look with it (e.g. `loadVrm(p.avatarUrl || "./assets/avatar.vrm")` in a VRM-lane game); it's `''` when unknown (older relay/API), so always keep a bundled fallback. Don't put an avatar URL in your `me.set` state — this field replaces that.
68
+ Each player also carries `p.avatarUrl` — the VRM avatar that player picked on their genex profile (guests get a per-session pick), verified server-side from their identity token so it can't be spoofed. It's the **fallback** body, not the default one: in a game that generated its own character, every player wears that character, and `p.avatarUrl` renders each player's own look only when the game has none. The genex controller kit's `loadRemotePlayerCharacter({ avatarUrl: p.avatarUrl })` makes that decision for you and shares one parsed base across remotes. The field is `''` when unknown (older relay/API), so always keep a bundled fallback. Don't put an avatar URL in your `me.set` state — this field replaces that.
69
69
 
70
70
  ## `shared` — shared room state
71
71
 
package/dist/index.d.ts CHANGED
@@ -204,6 +204,19 @@ type Session<TState extends Record<string, unknown>> = {
204
204
  * by the relay itself (`state`, `shared`, `claim`, `obj`, `release`, `destroy`, and the
205
205
  * `match:`/`__` prefixes) are refused with a console warning — pick another name. */
206
206
  send(type: string, payload?: unknown): void;
207
+ /**
208
+ * HOST ONLY. Stop (or resume) the matchmaker placing NEW players into THIS room.
209
+ *
210
+ * For a lobby game: call `setRoomOpen(false)` when your match starts, so arrivals
211
+ * form the NEXT room instead of dropping into a fight already in progress, and
212
+ * `setRoomOpen(true)` when you return to the lobby. Everyone already in the room
213
+ * keeps playing, and a reconnecting player still gets back in (reconnection uses a
214
+ * reserved seat, not matchmaking).
215
+ *
216
+ * Ignored (with no error) when called by a non-host — read `isHost` first. All
217
+ * clients are told either way, so you can render "closed" from the `room:open` event.
218
+ */
219
+ setRoomOpen(open: boolean): void;
207
220
  /** Leave the room (deliberate — no auto-reconnect, no `disconnect` event). */
208
221
  leave(): void;
209
222
  };
package/dist/index.js CHANGED
@@ -25,6 +25,7 @@ var CAPABILITIES_REQUEST_MSG = "__capabilities:request";
25
25
  var OBJECT_CONTROL_RESULT_MSG = "__object:result";
26
26
  var OBJECT_CONTROL_VERSION = 2;
27
27
  var STATE_SNAP_MSG = "__state:snap";
28
+ var ROOM_OPEN_MSG = "__room:open";
28
29
  var OBJECT_SNAP_MSG = "__object:snap";
29
30
  var MP_PROTOCOL = 2;
30
31
  async function relayClient(opts) {
@@ -913,6 +914,9 @@ function attachSession(client, initialRoom) {
913
914
  }
914
915
  send0(type, payload, true);
915
916
  },
917
+ setRoomOpen(open) {
918
+ room.send(ROOM_OPEN_MSG, { open });
919
+ },
916
920
  leave() {
917
921
  intentionalLeave = true;
918
922
  connected = false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@genex-ai/multiplayer",
3
- "version": "0.12.0",
3
+ "version": "0.13.0",
4
4
  "description": "The multiplayer client wrapper + shared room schema for genex.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",