miaoda-game-crazy-eights-react
v0.3.3
Published
React DOM bindings for the fixed basic Crazy Eights rules profile.
Readme
miaoda-game-crazy-eights-react
React DOM bindings and a framework-neutral controller for the fixed basic Crazy Eights profile.
pnpm add miaoda-game-crazy-eights-reactReact view
import {
CrazyEightsController,
createCrazyEightsGame,
useCrazyEightsView,
} from 'miaoda-game-crazy-eights-react';
const controller = new CrazyEightsController(
createCrazyEightsGame({ playerIds: ['human', 'bot'], seed: 2026 }),
'human',
);
function Table() {
const view = useCrazyEightsView(controller);
return view.legalActions.playOptions.map((play) => (
<button
key={play.cardId}
onClick={() => controller.dispatch({
type: 'play-card',
playerId: view.viewerId,
cardId: play.cardId,
...(play.calledSuits[0] ? { calledSuit: play.calledSuits[0] } : {}),
declaredLastCard: play.requiresLastCardDeclaration,
})}
>
{play.cardId}
</button>
));
}Render playOptions, initialSuitChoices, and canDraw directly from controller.view. The view
contains the viewer's own hand and public counts, never the authoritative deck or opponent hands.
Commits and reconnects
const unsubscribe = controller.onCommit(({ revision, view, events }) => {
queueAnimations(events);
persistRevision(revision);
renderHud(view);
});
controller.replaceSnapshot(JSON.parse(savedJson), serverRevision);
controller.setViewerId('bot');revision advances only for accepted actions. Rejected actions publish nothing. Snapshot replacement
validates the complete state and publishes a new view without replaying historical events. A lower
revision, corrupt snapshot, or unknown viewer throws without partially changing the controller.
Phaser
pnpm add miaoda-game-command-phaserimport { PhaserGameBridge } from 'miaoda-game-command-phaser';
const bridge = new PhaserGameBridge().setup(controller);
bridge.consumeWith((event) => animateCrazyEightsEvent(event));
bridge.dispatch({ type: 'draw-card', playerId: controller.state.activePlayerId });
// Dispose when the scene shuts down.
bridge.destroy();
unsubscribe();The bridge consumes successful commits in order and exposes the same player-safe view and public events as React. Draw events contain a count, never the physical card id.
