curltastic/frontend/src/protocol.ts
eros 86153894ac feat: add Vite TypeScript frontend for curling game
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-24 08:18:13 -07:00

98 lines
2.1 KiB
TypeScript

export const TICK_RATE_HZ = 120
export const SAMPLE_RATE_HZ = 40
export const STONES_PER_TEAM = 8
export const ENDS = 10
export const SHEET_WIDTH = 5.0
export const SHEET_LENGTH = 45.0
export const HOUSE_CENTER = { x: 0, y: 38.5 }
export const HOUSE_RADIUS = 1.83
export const BUTTON_RADIUS = 0.1524
export const FOUR_FT_RADIUS = 0.6096
export const EIGHT_FT_RADIUS = 1.2192
export const TWELVE_FT_RADIUS = 1.8288
export const HOG_LINE_Y = 21.0
export const BACK_LINE_Y = 42.0
export const HACK_Y = 2.0
export const STONE_RADIUS = 0.15
export const MIN_SPEED = 3.0
export const MAX_SPEED = 6.45
export interface StoneState {
id: number
team: Team
x: number
y: number
rotation: number
active: boolean
}
export interface ClientThrowMessage {
type: 'throw'
broom_x: number
broom_y: number
weight: number
curl: number
friction: number
}
export interface ServerJoinedMessage {
type: 'joined'
room: string
team: Team
}
export interface ServerWaitingMessage {
type: 'waiting'
message: string
}
export interface ServerGameStateMessage {
type: 'game_state'
end: number
scores: number[]
hammer: Team
turn_team: Team
stones: StoneState[]
phase: Phase
}
export interface ServerTrajectoryMessage {
type: 'trajectory'
path: [number, number, number][]
}
export interface ServerEndScoredMessage {
type: 'end_scored'
end: number
points: number
scoring_team?: Team
}
export interface ServerGameOverMessage {
type: 'game_over'
scores: number[]
winner: Team | null
}
export interface ServerErrorMessage {
type: 'error'
message: string
}
export type ServerMessageTyped =
| ServerJoinedMessage
| ServerWaitingMessage
| ServerGameStateMessage
| ServerTrajectoryMessage
| ServerEndScoredMessage
| ServerGameOverMessage
| ServerErrorMessage
export type Team = 'red' | 'yellow'
export type Phase = 'waiting' | 'playing' | 'simulating' | 'scoring' | 'end_complete' | 'game_complete'
export type ServerMessage = ServerMessageTyped
export function isTeam(value: unknown): value is Team {
return value === 'red' || value === 'yellow'
}