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}`;
}
}