> **Before opening a PR:** discuss new features on [Discord](https://discord.gg/K9zernJB5z) first, and file bugs or small improvements as [issues](https://github.com/openfrontio/OpenFrontIO/issues/new/choose). You must be assigned to an `approved` issue — unsolicited PRs will be auto-closed. **Add approved & assigned issue number here:** Resolves #4165 ## Description: This PR update the test checking validity of Nation Names to include the new character constraint explained below. It also fixes the 10 Nations that invalid characters (that did not render correctly on the map). **The new character constraint** According to testing, the game map renders correctly all safe Extended-ASCII characters (non colored in www.ascii-code.com = [0x20–0x7E] or [0xA0-0xFF]). Other characters, when present in Nation Names, are rendered correctly in the rest of the game but not on the map, where they are trimmed to the last byte, which is then interpreted as Extended-ASCII and rendered if possible. **How to quickly check my assertion** 1. Change the file resources/maps/world/manifest.json, renaming one of the countries to "a.á.आ!š!慢!". 2. Start a game on the world map without any bots 3. Verify that the nation name is well displayed in its overlay but is shown as "a.á.!a!b!" on the map. (characters before a point are preserved, but characters before an exclamation mark are missing/changed). 4. run `npm run test` and notice that the NationName test fails and lists the three non-valid characters. Explanation: The string is represented in UNICODE-16 as \u0061\u002e\u00e1\u002e\u0906\u0021\u0161\u0021\u6162\u0021. Which, when we keep only the right-most byte of each character gives: 61 2e e1 2e 06 21 61 21 62 21 And, converted in Extended-ASCII gives: a.á.�!a!b! (which matches the showed name if we discard the control character). **The 10 Nations which needed a fix** Utqiaġvik from the Bearing Strait. Ar Rayyān from the Strait of Hormuz. 6 Nations in the Bosphorus Straits. 2 Easter-egg Nations from Luna. The 8 real-world Nations were adapted by simply removing the diacritics (after confirmation from a speaker of arabic and turkish, but sadly none for the Utqiaġvik Nation). The Secret Base from Luna was renamed "T0Þ $e¢®ët Mi|¡tªr¥ ß@§£", all within Extended-ASCII, keeping the same spirit as the original name. However, the Monolith Nation (previously named ▊, without any flag) has changed quite a lot and needs some explanation. **Easter-egg Nation Monolith** The new name is "ΜΟΝΟʟΙȚΗ", which is entirely outside of the valid character zone but in a way that entirely disappears on the map (as the आ character in the example above). This means that on the map, the Nation has no name and only its Monolith-flag. However, in all other places (leaderboard, overlay, alliances, warnings, etc.) the name is displayed correctly. The included test excludes this precise name from its violation list. <img width="1512" height="632" alt="image" src="https://github.com/user-attachments/assets/998693f2-edb4-417c-9054-35dc4819a57d" /> The Monolith Nation without its name but with a Monolith flag. ## 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: Katokoda
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
Installation
- Install go https://go.dev/doc/install
- Go to map-generator folder:
cd map-generator - Install dependencies:
go mod download - Run the generator for all maps:
go run .
Creating a new map
-
Create a new folder in
assets/maps/<map_name> -
Create
assets/maps/<map_name>/image.png -
Create
assets/maps/<map_name>/info.jsonwith name and countries -
Add the map name in
main.goThe<name>in{Name: "<name>"},should match the<map-name>folder atassets/maps/<map_name> -
Run the generator for your map:
go run . --maps=<map_name>By default,
go run .will process all defined maps.Use
--mapsto process a single map:go run . --maps=fourislandsTo process a subset of maps, pass a comma-separated list:
go run . --maps=northamerica,world -
Find the output folder at
../resources/maps/<map_name> -
Go back to the root directory:
cd .. -
Run Prettier:
npm run formatThis 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.
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.
Command Line Flags
--maps: Optional comma-separated list of maps to process.- ex:
go run . --maps=world,eastasia,big_plains
- ex:
Logging
--log-level: Explicitly sets the log level.- ex:
go run . --log-level=debug - values:
ALL,DEBUG,INFO(default),WARN,ERROR.
- ex:
--verboseor-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:
- Download world map (warning very large file)
- 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 & Magnitudemapping inGenerateMapTerrain Type->Thumbnail Colormapping ingetThumbnailColor
In-Game, terrain is rendered using themes. The color of a tile is determined dynamically based on its Terrain Type and Magnitude. Theme Files:
../src/core/configuration/PastelTheme.ts(Light)../src/core/configuration/PastelThemeDark.ts(Dark).
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:
{
"name": "MySampleMap",
"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
name is a CamelCaseName of your map. It is used to enable the map in-game.
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
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
Using the name from your json:
- Add to GameMapType and mapCategories in
../src/core/game/Game.ts - Add to the map playlist in
../src/server/MapPlaylist.ts - Add to the
maptranslation object in../resources/lang/en.json
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)orHeight - (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:
go fmt . -
Output Map Generator Documentation:
go doc -cmd -u -allThe map-generator is a cli tool, to get any visibility, we pass
-cmd. It also does not expose any API, so we use-uand-allto show all documentation for unexposed values.Known Bug Using
-httpdoes not respect the other flags and only renders the README