From a417a7b2a3678f9cc77a8768fa76cb6a342e49ba Mon Sep 17 00:00:00 2001 From: evanpelle Date: Wed, 14 Aug 2024 08:12:29 -0700 Subject: [PATCH] fixed multiplayer --- TODO.txt | 3 ++- src/client/Client.ts | 3 ++- src/client/ClientGame.ts | 13 +++++-------- src/core/Game.ts | 4 +++- src/core/Schemas.ts | 1 + src/core/configuration/Config.ts | 2 -- src/core/configuration/DefaultConfig.ts | 10 +--------- src/core/execution/Executor.ts | 2 +- 8 files changed, 15 insertions(+), 23 deletions(-) diff --git a/TODO.txt b/TODO.txt index cd885c41b..af488b6bb 100644 --- a/TODO.txt +++ b/TODO.txt @@ -14,7 +14,8 @@ * add username in front page DONE 8/12/2024 * improve front page DONE 8/12/2024 * attacks cancel out DONE 8/13/2024 -* upload and start server +* upload and start server DONE 8/13/2024 +* fix multiplayer * better algorithm for name render placement * make boats larger * have boats not get close to shore diff --git a/src/client/Client.ts b/src/client/Client.ts index f6cf2d29d..b3dceb4c7 100644 --- a/src/client/Client.ts +++ b/src/client/Client.ts @@ -86,7 +86,8 @@ class Client { if (this.game != null) { return } - this.game = createClientGame(getUsername(), this.random.nextID(), lobbyID, defaultConfig, map) + // TODO make id more random, if two player join same millisecond get same id. + this.game = createClientGame(getUsername(), new PseudoRandom(Date.now()).nextID(), lobbyID, defaultConfig, map) this.game.joinLobby() }) } diff --git a/src/client/ClientGame.ts b/src/client/ClientGame.ts index e8b1c9aad..29f1343d8 100644 --- a/src/client/ClientGame.ts +++ b/src/client/ClientGame.ts @@ -14,13 +14,11 @@ export function createClientGame(name: string, clientID: ClientID, lobbyID: Lobb let eventBus = new EventBus() let gs = createGame(terrainMap, eventBus) let gameRenderer = new GameRenderer(gs, config.theme(), document.createElement("canvas")) - let ticker = new Ticker(config.tickIntervalMs(), eventBus) return new ClientGame( name, clientID, lobbyID, - ticker, eventBus, gs, gameRenderer, @@ -50,7 +48,6 @@ export class ClientGame { private playerName: string, private id: ClientID, private gameID: LobbyID, - private ticker: Ticker, private eventBus: EventBus, private gs: Game, private renderer: GameRenderer, @@ -81,8 +78,7 @@ export class ClientGame { this.start() } if (message.type == "turn") { - if (message.turn.intents) - this.addTurn(message.turn) + this.addTurn(message.turn) } }; } @@ -126,15 +122,13 @@ export class ClientGame { this.ticksThisTurn = 0 } this.ticksThisTurn++ - console.log('client ticking') this.gs.tick() this.renderer.tick() } private playerEvent(event: PlayerEvent) { console.log('received new player event!') - // TODO: what if multiple players has same name - if (event.player.info().name == this.playerName) { + if (event.player.info().clientID == this.id) { console.log('setting name') this.myPlayer = event.player } @@ -180,6 +174,7 @@ export class ClientGame { gameID: this.gameID, intent: { type: "spawn", + clientID: this.id, name: this.playerName, isBot: false, x: cell.x, @@ -204,6 +199,7 @@ export class ClientGame { gameID: this.gameID, intent: { type: "attack", + clientID: this.id, attackerID: this.myPlayer.id(), targetID: targetID, troops: troops, @@ -229,6 +225,7 @@ export class ClientGame { gameID: this.gameID, intent: { type: "boat", + clientID: this.id, attackerID: this.myPlayer.id(), targetID: targetID, troops: troops, diff --git a/src/core/Game.ts b/src/core/Game.ts index 3bb7f61ca..ef07cf215 100644 --- a/src/core/Game.ts +++ b/src/core/Game.ts @@ -36,7 +36,9 @@ export interface Execution extends ExecutionView { export class PlayerInfo { constructor( public readonly name: string, - public readonly isBot: boolean + public readonly isBot: boolean, + // null if bot. + public readonly clientID: ClientID | null ) { } } diff --git a/src/core/Schemas.ts b/src/core/Schemas.ts index d92171c41..999a324e6 100644 --- a/src/core/Schemas.ts +++ b/src/core/Schemas.ts @@ -23,6 +23,7 @@ export type ClientJoinMessage = z.infer // Zod schemas const BaseIntentSchema = z.object({ type: z.enum(['attack', 'spawn', 'boat']), + clientID: z.string(), }); export const AttackIntentSchema = BaseIntentSchema.extend({ diff --git a/src/core/configuration/Config.ts b/src/core/configuration/Config.ts index 5be6a386e..18b269fb3 100644 --- a/src/core/configuration/Config.ts +++ b/src/core/configuration/Config.ts @@ -6,8 +6,6 @@ export interface Config { theme(): Theme; player(): PlayerConfig turnIntervalMs(): number - tickIntervalMs(): number - ticksPerTurn(): number lobbyCreationRate(): number lobbyLifetime(): number } diff --git a/src/core/configuration/DefaultConfig.ts b/src/core/configuration/DefaultConfig.ts index 40829a4a4..519988c7a 100644 --- a/src/core/configuration/DefaultConfig.ts +++ b/src/core/configuration/DefaultConfig.ts @@ -6,10 +6,6 @@ export const defaultConfig = new class implements Config { player(): PlayerConfig { return defaultPlayerConfig } - - ticksPerTurn(): number { - return 1 - } turnIntervalMs(): number { return 100 } @@ -17,13 +13,9 @@ export const defaultConfig = new class implements Config { return 2 * 1000 } lobbyLifetime(): number { - return 3 * 1000 + return 10 * 1000 } theme(): Theme {return pastelTheme;} - - tickIntervalMs(): number { - return 1000 / 20; // 50ms - } } export const defaultPlayerConfig = new class implements PlayerConfig { diff --git a/src/core/execution/Executor.ts b/src/core/execution/Executor.ts index 959e125dc..a555d48ce 100644 --- a/src/core/execution/Executor.ts +++ b/src/core/execution/Executor.ts @@ -31,7 +31,7 @@ export class Executor { } else if (intent.type == "spawn") { this.gs.addExecution( new SpawnExecution( - new PlayerInfo(intent.name, intent.isBot), + new PlayerInfo(intent.name, intent.isBot, intent.clientID), new Cell(intent.x, intent.y), this.playerConfig )