.claude/skills/websocket-protocol/SKILL.md
# Skill: Extend the WebSocket Protocol Use this when adding a new message type. Both client and server must be updated together. ## Message flow ``` Client → Server: join, move, spell_cast, rename, [new type] Server → Client: welcome, player_join, player_leave, player_move, spell_cast, player_rename, [new type] ``` ## Step 1: Define the message before coding Document these before touching any file: - **Name**: snake_case - **Direction**: client→server, server→client, or
npx skillsauth add dschonholtz/MultiMagicDungeonWeb .claude/skills/websocket-protocolInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Use this when adding a new message type. Both client and server must be updated together.
Client → Server: join, move, spell_cast, rename, [new type]
Server → Client: welcome, player_join, player_leave, player_move,
spell_cast, player_rename, [new type]
Document these before touching any file:
handle(ws, raw) {
const msg = JSON.parse(raw);
switch (msg.type) {
case 'join': return this._onJoin(ws, msg);
case 'move': return this._onMove(ws, msg);
case 'spell_cast': return this._onSpellCast(ws, msg);
case 'rename': return this._onRename(ws, msg);
case 'player_emote': return this._onEmote(ws, msg); // NEW
default: console.warn(`[MSG] Unknown: ${msg.type}`);
}
}
_onEmote(ws, msg) {
const player = this._playerForWs(ws);
if (!player) return;
const VALID = ['wave', 'cheer', 'taunt'];
const emote = VALID.includes(msg.emote) ? msg.emote : 'wave';
const session = this.sessionManager.getSessionForPlayer(player.id);
if (!session) return;
this._broadcastToSession(session, {
type: 'player_emote',
playerId: player.id,
emote,
});
}
// In MmdNetworkClient:
sendEmote(emote) { this.send({ type: 'player_emote', emote }); }
// In keydown handler:
if (e.code === 'KeyE') net.sendEmote('wave');
// In MmdNetworkClient._handle(msg):
case 'player_emote': return this._onPlayerEmote(msg);
_onPlayerEmote(msg) {
const player = remotePlayers.get(msg.playerId) ?? localPlayer;
if (player?.id === msg.playerId) player.playEmote?.(msg.emote);
}
default: warn)_broadcastToSession(session, data, excludeWs = null) {
const json = JSON.stringify(data);
for (const player of session.players.values()) {
if (player.ws !== excludeWs && player.ws.readyState === 1) {
player.ws.send(json);
}
}
}
welcome message so reconnecting clients recoverdevelopment
# Skill: Add a Three.js Feature to MultiMagicDungeonWeb This game is a **single monolithic `index.html`** — no build step, no bundler. Everything lives in one file. ## File structure inside index.html ``` <html> <head> ... styles ... </head> <body> <!-- HUD overlay divs: #hud, #rename-panel, etc. --> <canvas id="c"></canvas> <script type="module"> // === CONSTANTS (WS_URL, PLAYER_SPEED, HP_MAX, etc.) === // === GLOBALS (scene, camera, renderer, clock) === //
development
Creates simple Three.js web apps with scene setup, lighting, geometries, materials, animations, and responsive rendering. Use for: "Create a threejs scene/app/showcase" or when user wants 3D web content. Supports ES modules, modern Three.js r150+ APIs.
tools
# Skill: Test Multiplayer Locally Use this skill any time you need to verify multiplayer behavior in MultiMagicDungeonWeb. ## Stack - Game: `index.html` (open as `file://` — no HTTP server needed) - WS server: `server/index.js` on port 8080 - Node binary: `~/.nvm/versions/node/v22.22.0/bin/node` (shell aliases don't apply in Bash tool) ## Step 1: Start the WS server ```bash export PATH="$HOME/.nvm/versions/node/v22.22.0/bin:$PATH" cd /Users/douglasschonholtz/repos/MultiMagicDungeonWeb/server
development
# Skill: Task Workflow Use this checklist for every non-trivial piece of work. Four steps, always in order. Never skip or merge steps. --- ## Step 1 — Plan _(requires user approval before any code is written)_ - [ ] Create `tasks/active/NNN-short-title.md` from `tasks/TEMPLATE.md` - [ ] Document 2–3 options with pros/cons - [ ] Pick the best option and explain why, clearly - [ ] Write numbered, measurable **success criteria** (not "looks better" — testable outcomes) - [ ] Write a **testing s