mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-30 23:43:34 +00:00
4c55f82e87
## Description: Adds map of the continental USA. This map was made for the brand new impassable terrain feature: https://github.com/openfrontio/OpenFrontIO/pull/4340 Only the territory of the US is playable, with canada and mexico being impassable terrain. Also, adds a new category called "countries" for Country maps like this map, that use Impassable Terrain. 49 default nations (Lower 48 + D.C.) , with additional nations (native nations and proposed states) for a total of 62, for private games and Human Vs Nations gamemode. Also standarizes many of the flags of the US states, since they did not have the black border like the other flags in the game <img width="857" height="567" alt="Captura de pantalla 2026-06-24 165158" src="https://github.com/user-attachments/assets/70a8d760-851f-40ed-ad79-d3e210dadb90" /> <img width="872" height="510" alt="Captura de pantalla 2026-06-24 165510" src="https://github.com/user-attachments/assets/c998cc10-ee89-41a7-b5e9-091be5e90da0" /> ## 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 ## Please put your Discord username so you can be contacted if a bug or regression is found: tri.star1011
205 lines
9.5 KiB
Markdown
205 lines
9.5 KiB
Markdown
# MapGenerator
|
|
|
|
This is a go-based tool to generate map files for OpenFront.
|
|
|
|
The map generator reads PNG files and converts pixels into terrain based primarily on the **Blue** channel.
|
|
Because only blue values are used, grayscale and other formats are fully supported. Many maps in `assets/maps/<mapname>` are grayscale.
|
|
|
|
Additional Guides, Tutorials, Scripts, Resources, and Third Party Unofficial Applications can be found on
|
|
the [Official Openfront Wiki](https://openfront.wiki/Map_Making)
|
|
|
|
## Installation
|
|
|
|
1. Install go <https://go.dev/doc/install>
|
|
2. Go to map-generator folder: `cd map-generator`
|
|
3. Install dependencies: `go mod download`
|
|
4. Run the generator for all maps: `go run .`
|
|
|
|
## Creating a new map
|
|
|
|
Maps are discovered automatically from the `assets/maps/` folders — `info.json` holds everything the game needs to know about a map.
|
|
|
|
1. Create a new folder in `assets/maps/<map_name>`
|
|
2. Create `assets/maps/<map_name>/image.png`
|
|
3. Create `assets/maps/<map_name>/info.json` (see below)
|
|
4. Run the generator for your map: `go run . --maps=<map_name>`
|
|
|
|
By default, `go run .` will process all defined maps.
|
|
|
|
Use `--maps` to process a single map:
|
|
|
|
`go run . --maps=fourislands`
|
|
|
|
To process a subset of maps, pass a comma-separated list:
|
|
|
|
`go run . --maps=northamerica,world`
|
|
|
|
5. Find the output folder at `../resources/maps/<map_name>`
|
|
6. Go back to the root directory: `cd ..`
|
|
7. Run Prettier: `npm run format`
|
|
This rewrites ALL files in place. Git figures out which files are actually changed, don't worry.
|
|
Alternatively, you can either run Prettier per file: `npx prettier --write resources/maps/<map_name>/<file_name>` or in VSCode install the Prettier extension and per file do Show and run Commands > Format Document.
|
|
|
|
Alternatively, `npm run gen-maps` (from the root directory) runs the generator for all maps and formats the output in one step.
|
|
|
|
## Output Files
|
|
|
|
- `../resources/maps/<map_name>/manifest.json` - JSON metadata containing map dimensions and land tile counts for all scales.
|
|
- `../resources/maps/<map_name>/map.bin` - Full-scale binary map data packed with terrain type and magnitude.
|
|
- `../resources/maps/<map_name>/map4x.bin` - 1/4 scale (half dimensions) binary map data used for mini-maps.
|
|
- `../resources/maps/<map_name>/map16x.bin` - 1/16 scale (quarter dimensions) binary map data used for mini-maps.
|
|
- `../resources/maps/<map_name>/thumbnail.webp` - WebP image thumbnail of the map.
|
|
- `../src/core/game/Maps.gen.ts` - Generated TypeScript (the `GameMapType` enum and the `maps` list of `MapInfo` objects) built from every map's info.json. Regenerated on every run, even with `--maps`.
|
|
- `../resources/lang/en.json` - The `map` section is rewritten with each map's display name. Regenerated on every run, even with `--maps`.
|
|
|
|
## Command Line Flags
|
|
|
|
- `--maps`: Optional comma-separated list of maps to process.
|
|
- ex: `go run . --maps=world,eastasia,big_plains`
|
|
|
|
### Logging
|
|
|
|
- `--log-level`: Explicitly sets the log level.
|
|
- ex: `go run . --log-level=debug`
|
|
- values: `ALL`, `DEBUG`, `INFO` (default), `WARN`, `ERROR`.
|
|
- `--verbose` or `-v`: Adds additional logging and prefixes logs with the `[mapname]`. Alias of `--log-level=DEBUG`.
|
|
- `--debug-performance`: Adds additional logging for performance-based recommendations, sets `--log-level=DEBUG`.
|
|
- `--debug-removal`: Adds additional logging of removed island and lake position/size, sets `--log-level=DEBUG`.
|
|
|
|
The Generator outputs logs using `slog` with standard log-levels, and an additional ALL level.
|
|
|
|
The `--verbose`, `-v`, `--debug-performance`, and `--debug-removal` flags all set the log level to `DEBUG`.
|
|
`debug-performance` and `debug-removal` are opt-in on top of the debug log level, as they can produce wordy output. You must pass the specific flag to see the corresponding logs if the `log-level` is set to `DEBUG`.
|
|
|
|
Setting `--log-level=ALL` will output all possible logs, including all `DEBUG` tiers, regardless of whether the specific flags are passed.
|
|
|
|
## Create image.png
|
|
|
|
The map-generator will process your input file at `assets/maps/<map_name>/image.png` to generate the map
|
|
thumbnail and binary files. To create this `png` input file, you can crop the world map:
|
|
|
|
1. [Download world map (warning very large file)](https://drive.google.com/file/d/1W2oMPj1L5zWRyPhh8LfmnY3_kve-FBR2/view?usp=sharing)
|
|
2. Crop the file (recommend Gimp)
|
|
|
|
If you are doing work in image editing software or using automated tools, `./map_generator.go` contains documentation for:
|
|
|
|
- `Pixel` -> `Terrain Type & Magnitude` mapping in `GenerateMap`
|
|
- `Terrain Type` -> `Thumbnail Color` mapping in `getThumbnailColor`
|
|
|
|
### Impassable Terrain
|
|
|
|
Pure black pixels (`#000000` / `rgb(0, 0, 0)` with alpha ≥ 20) are encoded as **impassable terrain**. This is a solid, static void that:
|
|
|
|
- Cannot be owned, attacked, or nuked.
|
|
- Nuke trajectories cannot pass over it (just as they cannot leave the map border).
|
|
- Renders as the map background colour, making the map appear non-rectangular.
|
|
|
|
Use impassable terrain to carve out non-rectangular map shapes or to create barriers that divide regions without water.
|
|
|
|
In-Game, the color of a tile is determined dynamically based on its **Terrain Type** and **Magnitude**.
|
|
|
|
- Ocean default color definition: `../src/client/render/gl/render-settings.json` (user changeable via settings)
|
|
- Terrain color calculations: `../src/client/render/gl/utils/ColorUtils.ts#L50`
|
|
|
|
## Create info.json
|
|
|
|
The map-generator will process your input file at `assets/maps/<map_name>/info.json` to determine the
|
|
position of Nations, their starting coordinates, and any flags.
|
|
|
|
Example:
|
|
|
|
```json
|
|
{
|
|
"id": "MySampleMap",
|
|
"name": "My Sample Map",
|
|
"translation_key": "map.mysamplemap",
|
|
"categories": ["europe"],
|
|
"multiplayer_frequency": 4,
|
|
"nations": [
|
|
{
|
|
"coordinates": [396, 364],
|
|
"name": "United States",
|
|
"flag": "us"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
`coordinates` is x/y position of the nation spawn on the map. Origin is at top left, with x extending right and y extending down
|
|
|
|
`id` is the `CamelCaseName` of your map. It must match the `assets/maps/<map_name>` folder name (lowercased) and becomes the `GameMapType` enum key.
|
|
|
|
`name` is the map's canonical name — the `GameMapType` enum value. It must never change once the map ships (it is part of the wire format and stored in game records).
|
|
|
|
`display_name` (optional) is the English display name written to the `map` section of `../resources/lang/en.json`. It defaults to `name` — set it only when the display name should differ from the canonical name (e.g. `MENA`, `Europe (Classic)`).
|
|
|
|
`translation_key` is the key of the map's display name in `../resources/lang/en.json`. It must be `map.<map_name>`.
|
|
|
|
`categories` groups the map in the map picker. Each entry must be one of: `new`, `featured`, `continental`, `world`, `europe`, `asia`, `north_america`, `africa`, `south_america`, `oceania`, `antarctica`, `countries`, `cosmic`, `tournament`, `fictional`, `arcade`. Maps that straddle regions (e.g. Black Sea, Bering Strait) can list more than one. Add `featured` to show the map in the featured section of the map picker.
|
|
|
|
`multiplayer_frequency` is how many times the map appears in the public multiplayer playlist. Use 0 (or omit) to keep the map out of the regular rotation.
|
|
|
|
`featured_rank` (optional, featured maps only) is the map's position in the featured grid (1 = first). Featured maps without a rank sort after ranked ones, alphabetically.
|
|
|
|
`special_team_count` (optional) is the map's preferred team count in team / special games — see `SPECIAL_TEAM_MAPS` in `../src/server/MapPlaylist.ts`. Omit it for no preference.
|
|
|
|
`flag` is the code for a country
|
|
|
|
- The full list of supported codes can be seen in `../src/client/data/countries.json` - all ISO_3166 codes are supported, with several additions.
|
|
|
|
- For quick reference, [Use country codes found here](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes)
|
|
|
|
## Update CREDITS.md
|
|
|
|
Add License & Attribution information to `../CREDITS.md`. If you are unsure if
|
|
a map's license can be used, open an issue or ask in Discord before beginning work.
|
|
|
|
## Adding Flags
|
|
|
|
Flags can be added to `../resources/flags/<iso_code>.svg`
|
|
|
|
The country will need to be added to `../src/client/data/countries.json`
|
|
|
|
## To Enable In-Game
|
|
|
|
Everything is generated from the info.json files when the map-generator runs —
|
|
there are no manual steps:
|
|
|
|
- The `GameMapType` enum and the `maps` list (one `MapInfo` per map) are
|
|
written to `../src/core/game/Maps.gen.ts`. Do not edit that file by hand.
|
|
- The `map` section of `../resources/lang/en.json` is rewritten with each
|
|
map's `display_name` (or `name`). Translations to other languages are
|
|
managed via Crowdin.
|
|
|
|
## Notes
|
|
|
|
- Islands smaller than 30 tiles (pixels) are automatically removed by the script.
|
|
- Bodies of water smaller than 200 tiles (pixels) are also removed.
|
|
- The map generator normalizes dimensions to multiples of 4. Any pixels beyond `Width - (Width % 4)` or `Height - (Height % 4)` are cropped.
|
|
|
|
For Performance Reasons:
|
|
|
|
- Maps should be between 2 - 3 million pixels square (area).
|
|
- Maps with over 3 million land tiles are not recommended.
|
|
- Average land tile count is around 1 - 2 million.
|
|
|
|
## 🛠️ Development Tools
|
|
|
|
- **Format map-generator code**:
|
|
|
|
```bash
|
|
go fmt .
|
|
```
|
|
|
|
- **Output Map Generator Documentation**:
|
|
|
|
```bash
|
|
go doc -cmd -u -all
|
|
```
|
|
|
|
The map-generator is a cli tool, to get any visibility, we pass `-cmd`. It also
|
|
does not expose any API, so we use `-u` and `-all` to show all documentation for
|
|
unexposed values.
|
|
|
|
_Known Bug_ Using `-http` does not respect the other flags and only renders the README
|