mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-21 10:35:09 +00:00
flags (#3985)
# Dynamic flag atlas (runtime TEXTURE_2D_ARRAY) Replaces the build-time `flag-atlas.png` with a runtime `TEXTURE_2D_ARRAY` populated on demand from each player's server-resolved flag URL. Layers are deduped by URL (every "Mercia" bot shares one slot), so the per-game working set is bounded by unique flags, not player count. ## Why The store will eventually ship hundreds of custom flags fetched from the CDN, which can't be baked into a static atlas. Moving to a runtime array also lets the catalog grow without bloating the client bundle. ## Side effect (bonus) Human players' country flags (`country:US`, etc.) now display next to their names in-game. The old atlas only contained nation names, so non-nation flags were silently dropped. ## Notes - Cell size is fixed at 128×85; loaded images are aspect-fit and centered. - Layer cap is 512 (clamped to `MAX_ARRAY_TEXTURE_LAYERS`). Past the cap, further flag requests render no icon. - Mipmaps are regenerated after each layer upload. - Recommend store pipeline caps custom flag uploads at SVG or PNG ≤ 256×170, ≤ 50 KB (decode-time RAM and bandwidth, not VRAM). ## Please complete the following: - [x] I have added screenshots for all UI updates - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file - [x] I have added relevant tests to the test directory - [x] I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced ## Please put your Discord username so you can be contacted if a bug or regression is found: evan
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { Colord } from "colord";
|
||||
import { base64url } from "jose";
|
||||
import { extractFlagName } from "../core/AssetUrls";
|
||||
import { assetUrl } from "../core/AssetUrls";
|
||||
import { decodePatternData } from "../core/PatternDecoder";
|
||||
import { PlayerType } from "../core/game/Game";
|
||||
import { GameView } from "../core/game/GameView";
|
||||
@@ -134,10 +134,11 @@ export class WebGLFrameBuilder {
|
||||
|
||||
this.writePaletteEntry(smallID, p.territoryColor(), p.borderColor());
|
||||
|
||||
let flag = p.cosmetics.flag;
|
||||
if (flag) {
|
||||
flag = extractFlagName(flag);
|
||||
}
|
||||
// p.cosmetics.flag has already been server-resolved to either a full URL
|
||||
// or a relative asset path (e.g. "/flags/US.svg" or a CDN URL for a
|
||||
// custom flag). assetUrl() passes URLs through and rewrites paths.
|
||||
const flagRef = p.cosmetics.flag;
|
||||
const flagUrl = flagRef ? assetUrl(flagRef) : undefined;
|
||||
|
||||
const pattern = p.cosmetics.pattern;
|
||||
if (pattern && pattern.patternData) {
|
||||
@@ -160,7 +161,7 @@ export class WebGLFrameBuilder {
|
||||
|
||||
newPlayers.push({
|
||||
...p.static,
|
||||
flag: flag,
|
||||
flag: flagUrl,
|
||||
color: p.territoryColor().toHex(),
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user