A realtime multiplayer version of the boardgame Ricochet Robots
at master 4.8 kB view raw
1import type { games, users } from "~/server/db/schema"; 2import type { GridType, Rocket, Rockets, Tiles, TilesNoEmpty } from "./grid"; 3 4type UserId = number; 5 6export type Game = { 7 name: string; 8 password: string; 9 ownerId: UserId; 10 players: UserId[]; 11 grid: GridType; 12}; 13 14export type CtoSBasePacket = { 15 sessionToken: string; 16 gameId: number; 17}; 18 19export type CtoSPlayerJoinPacket = { 20 type: "playerJoin"; 21 sessionToken: string; 22 data: { 23 gameCode: string; 24 }; 25}; 26 27export type CtoSPlayerChatPacket = CtoSBasePacket & { 28 type: "playerChat"; 29 data: { 30 message: string; 31 }; 32}; 33 34export type CtoSRequestGameStartPacket = CtoSBasePacket & { 35 type: "requestGameStart"; 36}; 37 38export type CtoSRequestGameEndPacket = CtoSBasePacket & { 39 type: "requestGameEnd"; 40}; 41 42export type CtoSPlayerBidPacket = CtoSBasePacket & { 43 type: "playerBid"; 44 data: { 45 bid: number; 46 time: number; 47 }; 48}; 49 50export type MoveDirection = "up" | "down" | "left" | "right"; 51 52export type CtoSPlayerVerifyMovePacket = CtoSBasePacket & { 53 type: "playerVerifyMove"; 54 data: { 55 rocket: Rocket; 56 direction: MoveDirection; 57 }; 58}; 59 60export type CtoSPlayerVerifyResetPacket = CtoSBasePacket & { 61 type: "playerVerifyReset"; 62}; 63 64export type CtoSUpdateSettingsPacket = CtoSBasePacket & { 65 type: "updateSettings"; 66 data: Settings; 67}; 68 69export type CtoSPacket = 70 | CtoSPlayerJoinPacket 71 | CtoSRequestGameStartPacket 72 | CtoSRequestGameEndPacket 73 | CtoSPlayerChatPacket 74 | CtoSPlayerBidPacket 75 | CtoSPlayerVerifyMovePacket 76 | CtoSPlayerVerifyResetPacket 77 | CtoSUpdateSettingsPacket; 78 79export type PlayerInfo = { 80 id: number; 81 username: string; 82}; 83 84export type GameInfo = { 85 id: number; 86 name: string; 87 state: (typeof games.$inferSelect)["state"]; 88 ownerId: number; 89}; 90 91export type Bid = { 92 bid: number; 93 time: number; 94}; 95 96export const compareBid = (a: Bid, b: Bid) => { 97 if (a.bid === b.bid) { 98 return a.time - b.time; 99 } 100 101 return a.bid - b.bid; 102}; 103 104export type Settings = { 105 startingDelay: number; 106 verificationTime: number; 107 biddingCountdownTime: number; 108}; 109 110export type GameRoom = { 111 ingameState: 112 | "starting" 113 | "nobid" 114 | "countdown" 115 | "verify" 116 | "winner" 117 | "failed"; 118 board: GridType; 119 restorableRockets: Rockets; 120 currentRockets: Rockets; 121 currentBids: Record<number, Bid>; // playerId => bid 122 currentVerifyingPlayerId: number | null; 123 targetTile: TilesNoEmpty | null; 124 movesTaken: number | null; 125 wins: Record<number, TilesNoEmpty[]>; 126 usedTiles: TilesNoEmpty[]; 127 settings: Settings; 128}; 129 130export type StoCPlayerJoinResponse = { 131 type: "playerJoinResponse"; 132 data: { 133 game: GameInfo; 134 players: PlayerInfo[]; 135 room: GameRoom; 136 }; 137}; 138 139export type StoCErrorResponse = { 140 type: "errorResponse"; 141 data: { 142 message: string; 143 }; 144}; 145 146export type StoCResponsePacket = StoCPlayerJoinResponse | StoCErrorResponse; 147 148export type StoCPlayerJoinEvent = { 149 type: "playerJoinedEvent"; 150 data: PlayerInfo; 151}; 152 153export type Chat = { 154 playerId: number; 155 message: string; 156}; 157 158export type StoCPlayerChatEvent = { 159 type: "playerChatEvent"; 160 data: Chat; 161}; 162 163export type StoCGameStartEvent = { 164 type: "gameStartEvent"; 165 data: { 166 startUnix: number; 167 room: GameRoom; 168 }; 169}; 170 171export type StoCGamEndEvent = { 172 type: "gameEndEvent"; 173}; 174 175export type StoCGameRevealBoardEvent = { 176 type: "gameRevealBoard"; 177 data: { 178 room: GameRoom; 179 }; 180}; 181 182export type StoCPlayerBidEvent = { 183 type: "playerBidEvent"; 184 data: { 185 playerId: number; 186 bid: Bid; 187 endUnix: number | null; 188 }; 189}; 190 191export type StoCGameStartVerificationEvent = { 192 type: "gameStartVerification"; 193 data: { 194 playerId: number; 195 endUnix: number; 196 }; 197}; 198 199export type StoCPlayerVerifyMoveEvent = { 200 type: "playerVerifyMove"; 201 data: { 202 rocket: Rocket; 203 direction: MoveDirection; 204 }; 205}; 206 207export type StoCPlayerVerifyResetEvent = { 208 type: "playerVerifyReset"; 209}; 210 211export type StoCPlayerVerifyCompletedEvent = { 212 type: "playerVerifyCompleted"; 213 data: { 214 wins: Record<number, TilesNoEmpty[]>; 215 endUnix: number; 216 }; 217}; 218 219export type StoCGameVerifyNextEvent = { 220 type: "gameVerifyNext"; 221 data: { 222 newCurrentBids: Record<number, Bid>; 223 newVerifyingPlayerId: number; 224 endUnix: number; 225 }; 226}; 227 228export type StoCGameVerifyFailedEvent = { 229 type: "gameVerifyFailed"; 230}; 231 232export type StoCGameCompletedEvent = { 233 type: "gameCompleted"; 234}; 235 236export type StoCEventPacket = 237 | StoCPlayerJoinEvent 238 | StoCPlayerChatEvent 239 | StoCGameStartEvent 240 | StoCGamEndEvent 241 | StoCGameRevealBoardEvent 242 | StoCPlayerBidEvent 243 | StoCGameStartVerificationEvent 244 | StoCPlayerVerifyMoveEvent 245 | StoCPlayerVerifyResetEvent 246 | StoCPlayerVerifyCompletedEvent 247 | StoCGameVerifyNextEvent 248 | StoCGameVerifyFailedEvent 249 | StoCGameCompletedEvent; 250 251export type StoCPacket = StoCEventPacket | StoCResponsePacket;