mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 07:50:45 +00:00
Fix troop count precision in name labels, throttle/stagger updates
Replace the hand-rolled formatTroops() in the name-pass with the canonical renderTroops() so map name labels match troop precision used elsewhere in the UI (Leaderboard, PlayerPanel, etc.). Also refresh each player's troop string at most every 500ms instead of every simulation tick, staggered by slot index so GPU string uploads spread across the window rather than bursting on a single tick.
This commit is contained in:
@@ -60,15 +60,3 @@ export function layoutString(
|
||||
|
||||
return (visualRight - visualLeft) * 0.5;
|
||||
}
|
||||
|
||||
/** Format internal troop count for display (internal values are 10x display). */
|
||||
export function formatTroops(internalTroops: number): string {
|
||||
const troops = internalTroops / 10;
|
||||
if (troops >= 1_000_000) {
|
||||
return (troops / 1_000_000).toFixed(1) + "M";
|
||||
}
|
||||
if (troops >= 1_000) {
|
||||
return (troops / 1_000).toFixed(1) + "K";
|
||||
}
|
||||
return troops.toFixed(0);
|
||||
}
|
||||
|
||||
@@ -56,6 +56,8 @@ export interface PlayerSlot {
|
||||
nameLen: number;
|
||||
troopLen: number;
|
||||
lastTroopStr: string;
|
||||
/** Last 500ms bucket this slot's troop string was refreshed in (staggered per slot). */
|
||||
lastTroopBucket: number;
|
||||
/** URL identifying which flag this player wants (dedup key). undefined = none. */
|
||||
flagUrl: string | undefined;
|
||||
/** Layer index in FlagAtlasArray, or -1 if not loaded yet / no flag. */
|
||||
|
||||
@@ -27,6 +27,7 @@ import { PlayerTypeEnum } from "../../../types";
|
||||
import type { RenderSettings } from "../../RenderSettings";
|
||||
import { createFullscreenQuad } from "../../utils/GlUtils";
|
||||
|
||||
import { renderTroops } from "../../../../Utils";
|
||||
import type { GlyphTables } from "./AtlasData";
|
||||
import {
|
||||
buildEmojiLookup,
|
||||
@@ -44,7 +45,7 @@ import { DebugProgram } from "./DebugProgram";
|
||||
import { FlagAtlasArray } from "./FlagAtlasArray";
|
||||
import { IconProgram } from "./IconProgram";
|
||||
import { StatusIconProgram } from "./StatusIconProgram";
|
||||
import { formatTroops, layoutString } from "./TextLayout";
|
||||
import { layoutString } from "./TextLayout";
|
||||
import { TextProgram } from "./TextProgram";
|
||||
import type { PlayerSlot } from "./Types";
|
||||
import { LINES_PER_PLAYER, MAX_CHARS } from "./Types";
|
||||
@@ -279,6 +280,7 @@ export class NamePass {
|
||||
nameLen: 0,
|
||||
troopLen: 0,
|
||||
lastTroopStr: "",
|
||||
lastTroopBucket: -1,
|
||||
flagUrl: p.flag,
|
||||
flagLayerIdx: -1,
|
||||
emojiAtlasIdx: -1,
|
||||
@@ -336,14 +338,19 @@ export class NamePass {
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
// Write troop count string (only if changed)
|
||||
const troops = troopsByPlayerID.get(playerID) ?? 0;
|
||||
const troopStr = formatTroops(troops);
|
||||
if (troopStr !== slot.lastTroopStr) {
|
||||
slot.troopLen = Math.min(troopStr.length, MAX_CHARS);
|
||||
slot.lastTroopStr = troopStr;
|
||||
this.uploadStringRow(slot.index * LINES_PER_PLAYER + 1, troopStr);
|
||||
dirty = true;
|
||||
// Write troop count string (refreshed per slot every 500ms, staggered by
|
||||
// slot index so updates spread across the window instead of bursting).
|
||||
const troopBucket = Math.floor((now + (slot.index % 5) * 0.1) / 0.5);
|
||||
if (snap || slot.troopLen === 0 || troopBucket !== slot.lastTroopBucket) {
|
||||
slot.lastTroopBucket = troopBucket;
|
||||
const troops = troopsByPlayerID.get(playerID) ?? 0;
|
||||
const troopStr = renderTroops(troops);
|
||||
if (troopStr !== slot.lastTroopStr) {
|
||||
slot.troopLen = Math.min(troopStr.length, MAX_CHARS);
|
||||
slot.lastTroopStr = troopStr;
|
||||
this.uploadStringRow(slot.index * LINES_PER_PLAYER + 1, troopStr);
|
||||
dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if target position changed — only then recompute lerp source
|
||||
|
||||
Reference in New Issue
Block a user