refactor(frontend): multi-path trajectory protocol and team on throw

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
Jason Dekarske 2026-07-10 23:16:06 -07:00
parent a4e848c849
commit 722e6090d1
2 changed files with 33 additions and 11 deletions

View File

@ -1,5 +1,6 @@
import type { import type {
ServerGameStateMessage, ServerGameStateMessage,
ServerStoneTrajectory,
ServerMessageTyped as ServerMessage, ServerMessageTyped as ServerMessage,
Team, Team,
} from './protocol' } from './protocol'
@ -13,10 +14,10 @@ function resolveWsUrl(): string {
} }
export interface NetCallbacks { export interface NetCallbacks {
onJoined: (room: string, team: Team) => void onJoined: (room: string) => void
onWaiting: (message: string) => void onWaiting: (message: string) => void
onGameState: (msg: ServerGameStateMessage) => void onGameState: (msg: ServerGameStateMessage) => void
onTrajectory: (path: [number, number, number][]) => void onTrajectory: (paths: ServerStoneTrajectory[]) => void
onEndScored: (end: number, points: number, scoringTeam: Team | null) => void onEndScored: (end: number, points: number, scoringTeam: Team | null) => void
onGameOver: (scores: number[], winner: Team | null) => void onGameOver: (scores: number[], winner: Team | null) => void
onError: (message: string) => void onError: (message: string) => void
@ -25,10 +26,9 @@ export interface NetCallbacks {
let socket: WebSocket | null = null let socket: WebSocket | null = null
export function connect(room: string, team: Team | null, callbacks: NetCallbacks): void { export function connect(room: string, callbacks: NetCallbacks): void {
if (socket) return if (socket) return
const teamParam = team ? `&team=${encodeURIComponent(team)}` : '' const url = `${resolveWsUrl()}?room=${encodeURIComponent(room)}`
const url = `${resolveWsUrl()}?room=${encodeURIComponent(room)}${teamParam}`
const ws = new WebSocket(url) const ws = new WebSocket(url)
ws.onopen = () => { ws.onopen = () => {
@ -42,7 +42,7 @@ export function connect(room: string, team: Team | null, callbacks: NetCallbacks
switch (msg.type) { switch (msg.type) {
case 'joined': case 'joined':
callbacks.onJoined(msg.room, msg.team) callbacks.onJoined(msg.room)
break break
case 'waiting': case 'waiting':
callbacks.onWaiting(msg.message) callbacks.onWaiting(msg.message)
@ -51,7 +51,7 @@ export function connect(room: string, team: Team | null, callbacks: NetCallbacks
callbacks.onGameState(msg) callbacks.onGameState(msg)
break break
case 'trajectory': case 'trajectory':
callbacks.onTrajectory(msg.path) callbacks.onTrajectory(msg.paths)
break break
case 'end_scored': case 'end_scored':
callbacks.onEndScored(msg.end, msg.points, msg.scoring_team ?? null) callbacks.onEndScored(msg.end, msg.points, msg.scoring_team ?? null)
@ -76,7 +76,24 @@ export function connect(room: string, team: Team | null, callbacks: NetCallbacks
ws.onerror = () => {} ws.onerror = () => {}
} }
export function sendThrow(broomX: number, broomY: number, weight: number, curl: number, friction: number): void { export function sendThrow(
team: Team,
broomX: number,
broomY: number,
weight: number,
curl: number,
friction: number,
): void {
if (!socket || socket.readyState !== WebSocket.OPEN) return if (!socket || socket.readyState !== WebSocket.OPEN) return
socket.send(JSON.stringify({ type: 'throw', broom_x: broomX, broom_y: broomY, weight, curl, friction })) socket.send(
JSON.stringify({
type: 'throw',
team,
broom_x: broomX,
broom_y: broomY,
weight,
curl,
friction,
}),
)
} }

View File

@ -35,6 +35,7 @@ export interface DrawableStone {
export interface ClientThrowMessage { export interface ClientThrowMessage {
type: 'throw' type: 'throw'
team: Team
broom_x: number broom_x: number
broom_y: number broom_y: number
weight: number weight: number
@ -45,7 +46,6 @@ export interface ClientThrowMessage {
export interface ServerJoinedMessage { export interface ServerJoinedMessage {
type: 'joined' type: 'joined'
room: string room: string
team: Team
} }
export interface ServerWaitingMessage { export interface ServerWaitingMessage {
@ -63,9 +63,14 @@ export interface ServerGameStateMessage {
phase: Phase phase: Phase
} }
export interface ServerStoneTrajectory {
stone_id: number
path: [number, number, number][]
}
export interface ServerTrajectoryMessage { export interface ServerTrajectoryMessage {
type: 'trajectory' type: 'trajectory'
path: [number, number, number][] paths: ServerStoneTrajectory[]
} }
export interface ServerEndScoredMessage { export interface ServerEndScoredMessage {