mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 09:40:44 +00:00
trying to fix nondetermism
This commit is contained in:
@@ -22,7 +22,6 @@ class Client {
|
||||
|
||||
constructor() {
|
||||
this.lobbiesContainer = document.getElementById('lobbies-container');
|
||||
|
||||
}
|
||||
|
||||
initialize(): void {
|
||||
|
||||
+12
-11
@@ -35,15 +35,14 @@ export class ClientGame {
|
||||
private socket: WebSocket
|
||||
private isActive = false
|
||||
|
||||
private ticksPerTurn = 1
|
||||
|
||||
private ticksThisTurn = 0
|
||||
private currTurn = 0
|
||||
|
||||
private spawned = false
|
||||
|
||||
private intervalID: NodeJS.Timeout
|
||||
|
||||
private isProcessingTurn = false
|
||||
|
||||
constructor(
|
||||
private playerName: string,
|
||||
private id: ClientID,
|
||||
@@ -76,6 +75,7 @@ export class ClientGame {
|
||||
const message: ServerMessage = ServerMessageSchema.parse(JSON.parse(event.data))
|
||||
if (message.type == "start") {
|
||||
console.log("starting game!")
|
||||
this.turns = message.turns
|
||||
if (!this.isActive) {
|
||||
this.start()
|
||||
}
|
||||
@@ -122,21 +122,22 @@ export class ClientGame {
|
||||
}
|
||||
|
||||
public addTurn(turn: Turn): void {
|
||||
if (this.turns.length != turn.turnNumber) {
|
||||
console.error(`got wrong turn have turns ${this.turns.length}, received turn ${turn.turnNumber}`)
|
||||
}
|
||||
this.turns.push(turn)
|
||||
}
|
||||
|
||||
public tick() {
|
||||
if (this.ticksThisTurn >= this.ticksPerTurn) {
|
||||
if (this.currTurn >= this.turns.length) {
|
||||
return
|
||||
}
|
||||
this.executor.addTurn(this.turns[this.currTurn])
|
||||
this.currTurn++
|
||||
this.ticksThisTurn = 0
|
||||
if (this.currTurn >= this.turns.length || this.isProcessingTurn) {
|
||||
return
|
||||
}
|
||||
this.ticksThisTurn++
|
||||
this.isProcessingTurn = true
|
||||
this.gs.addExecution(...this.executor.createExecs(this.turns[this.currTurn]))
|
||||
this.gs.tick()
|
||||
this.renderer.tick()
|
||||
this.currTurn++
|
||||
this.isProcessingTurn = false
|
||||
}
|
||||
|
||||
private playerEvent(event: PlayerEvent) {
|
||||
|
||||
@@ -217,7 +217,7 @@ export class GameImpl implements MutableGame {
|
||||
this.execs.push(...this.unInitExecs)
|
||||
this.unInitExecs = []
|
||||
this.ticks++
|
||||
if (this.ticks % 10) {
|
||||
if (this.ticks % 100 == 0) {
|
||||
let hash = 1;
|
||||
this._players.forEach(p => {
|
||||
hash += p.hash()
|
||||
|
||||
@@ -77,6 +77,8 @@ export const ServerTurnMessageSchema = ServerBaseMessageSchema.extend({
|
||||
|
||||
export const ServerStartGameMessageSchema = ServerBaseMessageSchema.extend({
|
||||
type: z.literal('start'),
|
||||
// Turns the client missed if they are late to the game.
|
||||
turns: z.array(TurnSchema)
|
||||
})
|
||||
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ export class BotExecution implements Execution {
|
||||
if (ticks < this.ticksUntilStart) {
|
||||
return
|
||||
}
|
||||
return
|
||||
|
||||
if (!this.bot.isAlive()) {
|
||||
this.active = false
|
||||
|
||||
@@ -14,38 +14,32 @@ export class Executor {
|
||||
|
||||
}
|
||||
|
||||
addTurn(turn: Turn) {
|
||||
turn.intents.forEach(i => this.addIntent(i))
|
||||
createExecs(turn: Turn): Execution[] {
|
||||
return turn.intents.map(i => this.createExec(i))
|
||||
}
|
||||
|
||||
addIntent(intent: Intent) {
|
||||
createExec(intent: Intent) {
|
||||
if (intent.type == "attack") {
|
||||
this.gs.addExecution(
|
||||
new AttackExecution(
|
||||
intent.troops,
|
||||
intent.attackerID,
|
||||
intent.targetID,
|
||||
new Cell(intent.targetX, intent.targetY),
|
||||
this.playerConfig
|
||||
)
|
||||
return new AttackExecution(
|
||||
intent.troops,
|
||||
intent.attackerID,
|
||||
intent.targetID,
|
||||
new Cell(intent.targetX, intent.targetY),
|
||||
this.playerConfig
|
||||
)
|
||||
} else if (intent.type == "spawn") {
|
||||
this.gs.addExecution(
|
||||
new SpawnExecution(
|
||||
new PlayerInfo(intent.name, intent.isBot, intent.clientID),
|
||||
new Cell(intent.x, intent.y),
|
||||
this.playerConfig
|
||||
)
|
||||
return new SpawnExecution(
|
||||
new PlayerInfo(intent.name, intent.isBot, intent.clientID),
|
||||
new Cell(intent.x, intent.y),
|
||||
this.playerConfig
|
||||
)
|
||||
} else if (intent.type == "boat") {
|
||||
this.gs.addExecution(
|
||||
new BoatAttackExecution(
|
||||
intent.attackerID,
|
||||
intent.targetID,
|
||||
new Cell(intent.x, intent.y),
|
||||
intent.troops,
|
||||
this.playerConfig
|
||||
)
|
||||
return new BoatAttackExecution(
|
||||
intent.attackerID,
|
||||
intent.targetID,
|
||||
new Cell(intent.x, intent.y),
|
||||
intent.troops,
|
||||
this.playerConfig
|
||||
)
|
||||
} else {
|
||||
throw new Error(`intent type ${intent} not found`)
|
||||
@@ -54,6 +48,6 @@ export class Executor {
|
||||
|
||||
|
||||
spawnBots(numBots: number): void {
|
||||
new BotSpawner(this.gs).spawnBots(numBots).forEach(i => this.addIntent(i))
|
||||
new BotSpawner(this.gs).spawnBots(numBots).forEach(i => this.createExec(i))
|
||||
}
|
||||
}
|
||||
@@ -66,7 +66,9 @@ export class GameServer {
|
||||
private sendStartGameMsg(ws: WebSocket) {
|
||||
ws.send(JSON.stringify(ServerStartGameMessageSchema.parse(
|
||||
{
|
||||
type: "start"
|
||||
type: "start",
|
||||
// TODO: this could get large
|
||||
turns: this.turns
|
||||
}
|
||||
)))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user