fix vision logic and game tick timer
This commit is contained in:
+18
-7
@@ -7,6 +7,8 @@ import Projectile from './projectile.js'
|
||||
import Terrain from './terrain.js'
|
||||
|
||||
export default class Game {
|
||||
id = crypto.randomUUID()
|
||||
|
||||
abilities = Object.values({...Ability})
|
||||
buffs = Object.values({...Buff})
|
||||
averageTick = 0
|
||||
@@ -16,6 +18,7 @@ export default class Game {
|
||||
height = 0
|
||||
projectiles = []
|
||||
secondToSlowestTick = 0
|
||||
startTimestamp = 0
|
||||
terrains = []
|
||||
tickRate = 30
|
||||
width = 0
|
||||
@@ -100,7 +103,9 @@ export default class Game {
|
||||
start() {
|
||||
if (this.gameLoopIntervalId != null) { return }
|
||||
|
||||
this.gameLoopIntervalId = setInterval(this.#gameLoopCall.bind(this), 1)
|
||||
this.startTimestamp = performance.now() + (this.currentTick * this.tickBudget)
|
||||
console.log(`Started game ${this.id} with ${this.tickRate} tps. Starting on tick ${this.currentTick}.`)
|
||||
this.gameLoopIntervalId = setInterval(this.#gameLoopCall.bind(this), this.tickBudget / 5)
|
||||
}
|
||||
|
||||
stop() {
|
||||
@@ -108,6 +113,7 @@ export default class Game {
|
||||
|
||||
clearInterval(this.gameLoopIntervalId)
|
||||
this.gameLoopIntervalId = null
|
||||
console.log(`Stopped game ${this.id}. Stopped on tick ${this.currentTick}.`)
|
||||
}
|
||||
|
||||
subscription(websocket, id) {
|
||||
@@ -123,8 +129,9 @@ export default class Game {
|
||||
}
|
||||
|
||||
update() {
|
||||
this.entities.forEach((e) => e.update())
|
||||
this.projectiles.forEach((p) => p.update())
|
||||
const callUpdate = function callUpdate(object) { object.update() }
|
||||
this.entities.forEach(callUpdate)
|
||||
this.projectiles.forEach(callUpdate)
|
||||
if (this.#logic != null) {
|
||||
this.#logic()
|
||||
}
|
||||
@@ -151,6 +158,7 @@ export default class Game {
|
||||
return entityVisionSources.concat(projectileVisionSources)
|
||||
}
|
||||
|
||||
// TODO: castingVision should not reveal casting in non-lanes (= only spawn castingVision if slightly outside regular vision [or obstructeed])
|
||||
visionByTeam(team) {
|
||||
const visionSources = this.visionSources(team)
|
||||
const visibleEntities = new Set(visionSources.map((it) => it.entitiesInVision()).flat())
|
||||
@@ -180,9 +188,11 @@ export default class Game {
|
||||
this.update()
|
||||
const after = performance.now()
|
||||
const taken = (after - before)
|
||||
const prevBehind = this.#behindMs
|
||||
this.#behindMs = Math.max(0, this.#behindMs + taken - tickBudget)
|
||||
this.#nextTickAt = start + tickBudget - prevBehind
|
||||
|
||||
const useAbsoluteBehind = true
|
||||
const absoluteBehind = Math.max(0, (start - this.startTimestamp) - ((this.currentTick) * tickBudget))
|
||||
this.#behindMs = absoluteBehind
|
||||
this.#nextTickAt = start + tickBudget - (useAbsoluteBehind ? absoluteBehind : prevBehind)
|
||||
|
||||
this.#timings[this.#currentTiming] = taken
|
||||
if (this.#currentTiming++ > this.#timings.length) {
|
||||
@@ -190,7 +200,8 @@ export default class Game {
|
||||
}
|
||||
|
||||
if (after - before > tickBudget) {
|
||||
console.warn(`Can't keep up! A tick took ${taken.toFixed(1)} ms / ${tickBudget.toFixed(1)} ms. (Behind ${this.#behindMs.toFixed(1)} ms)`)
|
||||
const behindNotice = absoluteBehind > 0.1 ? `(Was already behind ${absoluteBehind.toFixed(1)} ms)` : ``
|
||||
console.warn(`Can't keep up! A tick took ${taken.toFixed(1)} ms / ${tickBudget.toFixed(1)} ms. ${behindNotice}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user