mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-13 21:19:04 +00:00
Move map metadata into info.json and generate map TypeScript from it (#4227)
**Add approved & assigned issue number here:** N/A — maintainer refactor. ## Description: Makes each map's `info.json` the single source of truth for map metadata — adding a map is now a folder with `image.png` + `info.json`, a `gen-maps` run, and an en.json display name. **info.json / manifest.json carry full map metadata.** Every `map-generator/assets/maps/<map>/info.json` declares `id` (the `GameMapType` enum key), `name` (the enum value — wire format, unchanged for all 94 maps), `translation_key`, `categories`, and `multiplayer_frequency` (the public-playlist weight that used to be the `FREQUENCY` record in MapPlaylist.ts). The generator validates everything and mirrors it into `resources/maps/<map>/manifest.json`. 23 stale info.json `name` values were normalized to the canonical enum value; enum values are byte-identical, so replays and stored game configs are unaffected. **The generator emits the TypeScript and discovers maps itself.** New `map-generator/codegen.go` generates `src/core/game/Maps.gen.ts` (`GameMapType`, `GameMapName`, `mapCategories`, `mapTranslationKeys`, `multiplayerFrequency` — now a full `Record<GameMapName, number>`, killing the old `Partial`) on every run; `Game.ts` re-exports it. The hardcoded map registry in `main.go` is gone — maps are auto-discovered from the `assets/maps` / `assets/test_maps` directories. MapConsistency tests fail with a "run `npm run gen-maps`" message if info.json, manifest.json, and Maps.gen.ts drift. The tracked `map-generator/map-generator` binary is rebuilt to match. **New categories: continents + world/cosmic/tournament/other, multi-category support.** `continental`/`regional`/`fantasy`/`arcade` are replaced by `featured`, `world`, `europe`, `asia`, `north_america`, `africa`, `south_america`, `oceania`, `antarctica`, `cosmic`, `tournament`, and `other`. Maps can list multiple categories, so straddlers (Black Sea, Bosphorus, Caucasus, Between Two Seas, Bering Sea/Strait, Mena, Strait of Gibraltar, Hawaii, Arctic) appear under both regions. Featured is itself a category (same 7 maps as before). MapPlaylist keeps its arcade exclusion via an explicit set. **Map picker UI.** Two tabs: **Featured** (default — featured maps plus a Favorites section when maps are starred) and **All** (one prominent collapsible bar per category with a map count, collapsed by default). The selected map is prepended to the featured grid when it lives elsewhere. `getMapName()` resolves through the generated `mapTranslationKeys`, which also fixes tourney maps never resolving a valid translation key. ## Please complete the following: - [ ] I have added screenshots for all UI updates (maintainer change — picker described above) - [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 ## Please put your Discord username so you can be contacted if a bug or regression is found: evanpelle 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+12
-93
@@ -8,12 +8,12 @@ import {
|
||||
GameMode,
|
||||
GameType,
|
||||
HumansVsNations,
|
||||
multiplayerFrequency,
|
||||
PublicGameModifiers,
|
||||
Quads,
|
||||
RankedType,
|
||||
Trios,
|
||||
UnitType,
|
||||
mapCategories,
|
||||
} from "../core/game/Game";
|
||||
import { PseudoRandom } from "../core/PseudoRandom";
|
||||
import { GameConfig, PublicGameType, TeamCountConfig } from "../core/Schemas";
|
||||
@@ -22,102 +22,21 @@ import { getMapLandTiles } from "./MapLandTiles";
|
||||
|
||||
const log = logger.child({});
|
||||
|
||||
const ARCADE_MAPS = new Set(mapCategories.arcade);
|
||||
// Arcade-style maps only appear in the "special" playlist.
|
||||
const ARCADE_MAPS = new Set<GameMapType>([
|
||||
GameMapType.TheBox,
|
||||
GameMapType.ChoppingBlock,
|
||||
GameMapType.Didier,
|
||||
GameMapType.DidierFrance,
|
||||
GameMapType.Labyrinth,
|
||||
GameMapType.Sierpinski,
|
||||
GameMapType.Onion,
|
||||
]);
|
||||
const SPECIAL_ONLY_MAPS = new Set<GameMapType>([GameMapType.ArchipelagoSea]);
|
||||
|
||||
// Hard cap on player count for performance. Applied after compact-map reduction.
|
||||
const MAX_PLAYER_COUNT = 125;
|
||||
|
||||
// How many times each map should appear in the playlist.
|
||||
// Note: The Partial should eventually be removed for better type safety.
|
||||
const FREQUENCY: Partial<Record<GameMapName, number>> = {
|
||||
Achiran: 5,
|
||||
Aegean: 6,
|
||||
Africa: 7,
|
||||
Alps: 4,
|
||||
AmazonRiver: 3,
|
||||
Antarctica: 1,
|
||||
ArchipelagoSea: 3,
|
||||
Arctic: 6,
|
||||
Asia: 6,
|
||||
Australia: 4,
|
||||
Baikal: 5,
|
||||
BajaCalifornia: 4,
|
||||
Balkans: 6,
|
||||
BeringSea: 5,
|
||||
BeringStrait: 2,
|
||||
BetweenTwoSeas: 5,
|
||||
BlackSea: 6,
|
||||
BosphorusStraits: 3,
|
||||
Britannia: 5,
|
||||
Caribbean: 5,
|
||||
Caucasus: 5,
|
||||
ChoppingBlock: 5,
|
||||
Conakry: 3,
|
||||
DanishStraits: 5,
|
||||
DeglaciatedAntarctica: 4,
|
||||
Didier: 1,
|
||||
DidierFrance: 1,
|
||||
Dyslexdria: 8,
|
||||
EastAsia: 5,
|
||||
Europe: 7,
|
||||
FalklandIslands: 4,
|
||||
FaroeIslands: 4,
|
||||
FourIslands: 4,
|
||||
GatewayToTheAtlantic: 5,
|
||||
GreatLakes: 6,
|
||||
GulfOfStLawrence: 4,
|
||||
Halkidiki: 4,
|
||||
Hawaii: 4,
|
||||
HongKong: 6,
|
||||
Iceland: 4,
|
||||
IndianSubcontinent: 8,
|
||||
Italia: 6,
|
||||
Japan: 6,
|
||||
JuanDeFucaStrait: 4,
|
||||
Korea: 5,
|
||||
Labyrinth: 6,
|
||||
Lemnos: 3,
|
||||
Lisbon: 4,
|
||||
LosAngeles: 8,
|
||||
Luna: 6,
|
||||
Manicouagan: 4,
|
||||
MareNostrum: 6,
|
||||
Mars: 3,
|
||||
Mena: 6,
|
||||
MiddleEast: 8,
|
||||
MilkyWay: 8,
|
||||
MississippiRiver: 3,
|
||||
Montreal: 6,
|
||||
NewYorkCity: 3,
|
||||
NileDelta: 4,
|
||||
NorthAmerica: 5,
|
||||
NorthwestPassage: 5,
|
||||
Pangaea: 5,
|
||||
Passage: 4,
|
||||
Onion: 2,
|
||||
Pluto: 6,
|
||||
SanFrancisco: 3,
|
||||
Sierpinski: 10,
|
||||
SouthAmerica: 5,
|
||||
SoutheastAsia: 5,
|
||||
StraitOfGibraltar: 5,
|
||||
StraitOfHormuz: 4,
|
||||
StraitOfMalacca: 4,
|
||||
Surrounded: 4,
|
||||
Svalmel: 8,
|
||||
TaiwanStrait: 5,
|
||||
TheBox: 3,
|
||||
Titan: 3,
|
||||
TradersDream: 4,
|
||||
TwoLakes: 6,
|
||||
Venice: 6,
|
||||
World: 20,
|
||||
WorldInverted: 8,
|
||||
YellowSea: 5,
|
||||
Yenisei: 6,
|
||||
};
|
||||
|
||||
const TEAM_WEIGHTS: { config: TeamCountConfig; weight: number }[] = [
|
||||
{ config: 2, weight: 10 },
|
||||
{ config: 3, weight: 10 },
|
||||
@@ -587,7 +506,7 @@ export class MapPlaylist {
|
||||
) {
|
||||
return;
|
||||
}
|
||||
let freq = FREQUENCY[key] ?? 0;
|
||||
let freq = multiplayerFrequency[key];
|
||||
// Boost frequency for special team maps in the team playlist
|
||||
if (type === "team" && SPECIAL_TEAM_MAPS.has(map)) {
|
||||
freq *= SPECIAL_TEAM_FREQ_MULTIPLIER;
|
||||
|
||||
Reference in New Issue
Block a user