Threads the multiplayer publisher all the way from useMultiplayerGame
down through GameView → RulesDrawer → ModifierProfileEditor →
CustomModifierEditor, surfacing a Share with Room button in the
custom modifier editor when (and only when) the editor was opened
from a multiplayer game.
Wiring summary (top-down):
- useMultiplayerGame.ts: returns sendRegisterCustomModifier(descriptor),
a thin wrapper around the GameClient.sendRegisterCustomModifier
helper added in the previous commit.
- useMultiplayerGame.ts: onError handler surfaces CUSTOM_MODIFIER_INVALID
and CUSTOM_MODIFIER_LIMIT as toasts on top of the existing in-game
error banner so the user notices the rejection immediately.
- GameView.tsx: GameEngineState gains an optional
sendRegisterCustomModifier field; the multiplayer destructure
pulls it out and passes it to RulesDrawer as
onShareCustomModifierWithRoom (omitted in solo, where the prop is
undefined and Share UI doesn't render).
- RulesDrawer.tsx: optional onShareCustomModifierWithRoom prop;
conditionally forwards to ModifierProfileEditor.
- ModifierProfileEditor.tsx: optional onShareCustomModifierWithRoom
prop; conditionally forwards to CustomModifierEditor as onShareWithRoom.
- CustomModifierEditor.tsx: when onShareWithRoom is provided, renders
a green Share with Room button in the header alongside Save. Click
invokes the publisher with the current descriptor; toast confirms
the share landed (server broadcast is the actual proof, observed
by the local PredictionManager subscriber registering the descriptor
on the engine's customModifiers registry).
E2E coverage (both formerly-fixme tests now PASS):
- multiplayer custom modifier sharing — both clients see the
registered descriptor: opens two browser contexts via raw WS
(matches modifier-profiles.spec.ts MP pattern), host registers a
descriptor after both reconnect-by-token complete, both sides
observe custom-modifier.registered.
- server rejects custom modifier with > 50 primitives — error event
observed: host registers a 51-primitive descriptor, asserts an
INVALID_MESSAGE / CUSTOM_MODIFIER_INVALID error is observed and
no broadcast fires.
Final state: 79/79 e2e + 1386 unit tests, zero fixmes, zero skipped.