#Multiplayer Game
A simple multiplayer game with player positions and game state.
#Backend Configuration
// game.config.ts
import { createDialogue, defineEvent } from "./dialogue";
import { z } from "zod";
export const PlayerMove = defineEvent("player:move", {
schema: z.object({
playerId: z.string(),
x: z.number(),
y: z.number(),
direction: z.enum(["up", "down", "left", "right"]),
}),
});
export const GameState = defineEvent("game:state", {
schema: z.object({
players: z.array(
z.object({
id: z.string(),
x: z.number(),
y: z.number(),
health: z.number(),
score: z.number(),
})
),
gameTime: z.number(),
status: z.enum(["waiting", "playing", "ended"]),
}),
});
export const PlayerAction = defineEvent("player:action", {
schema: z.object({
playerId: z.string(),
action: z.enum(["attack", "defend", "heal", "special"]),
targetId: z.string().optional(),
}),
});
export const dialogue = createDialogue({
port: 3000,
rooms: {
"game:lobby": {
name: "Game Lobby",
events: [GameState],
maxSize: 8,
defaultSubscriptions: ["game:state"],
},
"game:match-1": {
name: "Match 1",
events: [PlayerMove, GameState, PlayerAction],
maxSize: 4,
defaultSubscriptions: ["player:move", "game:state", "player:action"],
},
},
hooks: {
clients: {
onConnected: (client) => {
client.join("game:lobby");
},
},
},
});
// Game loop - broadcast state 30 times per second
const TICK_RATE = 1000 / 30;
setInterval(() => {
const gameState = computeGameState();
dialogue.trigger("game:match-1", GameState, {
players: gameState.players,
gameTime: gameState.time,
status: gameState.status,
});
}, TICK_RATE);
// Handle player moves
dialogue.on("game:match-1", PlayerMove, (msg) => {
updatePlayerPosition(msg.data.playerId, msg.data.x, msg.data.y);
});
// Handle player actions
dialogue.on("game:match-1", PlayerAction, (msg) => {
processPlayerAction(msg.data.playerId, msg.data.action, msg.data.targetId);
});This documentation reflects the current implementation and is subject to evolution. Contributions and feedback are welcome.