import type { ColonyStatsData } from "./ColonyStats"; import Config from "./Config"; export default class StatsOverlay { private el: HTMLElement; private cursorEl: HTMLElement; private tpsEl: HTMLElement; private antsEl: HTMLElement; private carryingEl: HTMLElement; private tickTimestamps: number[] = []; constructor() { this.el = document.createElement("div"); this.el.id = "stats"; // insert after #info // biome-ignore lint/style/noNonNullAssertion: #info exists in index.html const info = document.getElementById("info")!; info.after(this.el); this.cursorEl = this.addLine("cursor"); this.tpsEl = this.addLine("tps"); this.antsEl = this.addLine("ants"); this.carryingEl = this.addLine("carrying"); } private addLine(label: string): HTMLElement { const line = document.createElement("div"); line.innerHTML = `${label}`; this.el.appendChild(line); // biome-ignore lint/style/noNonNullAssertion: .value span created by innerHTML above return line.querySelector(".value")!; } public recordTick(): void { const now = performance.now(); this.tickTimestamps.push(now); // keep last 60 timestamps for averaging if (this.tickTimestamps.length > 60) { this.tickTimestamps.shift(); } } public update( pointerPosition: { x: number; y: number }, colonyStats: ColonyStatsData, ): void { const gridX = Math.floor(pointerPosition.x * Config.worldSize); const gridY = Math.floor(pointerPosition.y * Config.worldSize); this.cursorEl.textContent = `${gridX}, ${gridY}`; // tps from tick timestamps if (this.tickTimestamps.length >= 2) { const span = this.tickTimestamps[this.tickTimestamps.length - 1] - this.tickTimestamps[0]; const tps = span > 0 ? ((this.tickTimestamps.length - 1) / span) * 1000 : 0; this.tpsEl.textContent = `${Math.round(tps)}`; } this.antsEl.textContent = `${colonyStats.totalAnts}`; const carrying = Math.round( colonyStats.foragerRatio * colonyStats.totalAnts, ); this.carryingEl.textContent = `${carrying}`; } }