## Description:
I saw multiple occasions of 3h long four islands team games because of
the 2x gold multiplier. For example
[here](https://www.reddit.com/r/Openfront/comments/1sca6g4/endless_game/).
People just get too many SAMs.
Without the extreme gold amount, team games on four islands are actually
fun.
This PR excludes `goldMultiplier` and `startingGold25M` from special
game modifiers when the map is FourIslands.
## 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:
FloPinguin
## Description:
The new hashed public asset pipeline treated `manifest.json` as a
derived asset, but BMFont XML files were still copied as raw files.
That broke bitmap fonts in production:
- the XML was loaded through the hashed asset manifest
- the XML still referenced an unhashed `file="...png"` page
- Pixi resolved that relative to the hashed XML URL
- the unhashed page file did not exist under `/_assets/...`
This PR extends the derived asset rewriting model to BMFont XML so font
page references are rewritten before hashing and emission.
## What changed
- Refactored the public asset build pipeline to distinguish:
- raw assets hashed from source bytes
- derived assets hashed from rewritten content
- Replaced the `manifest.json` one-off special case with a small
derived-asset registry
- Added BMFont XML derived-asset handling for `fonts/**/*.xml`
- Rewrote `<page file="...">` entries to hashed relative page paths
- Moved `_assets/asset-manifest.mjs` emission to the end of the Vite
asset sync step
Added regression coverage for:
- rewritten web manifest hashing
- BMFont XML page rewrite
- nested relative BMFont page paths
- hard failure on missing derived asset references
## Please complete the following:
- [ ] I have added screenshots for all UI updates
- [ ] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [ ] I have added relevant tests to the test directory
- [ ] 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:
DISCORD_USERNAME
add map dyslexdria to map rotation
## Description:
I forgot to add dyslexdria to the map rotation and must atone for my
mistakes
## 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
##Discord username
PlaysBadly
Re-submission, previous request was not branched properly.
Add custom map Dyslexdria. Based off of large_world_map_recolor.tif and
rivers from the XL World map. Map is intended for long term use.
Suggesting that map be used as an April Fools gag by replacing thumbnail
and title with 'World' during first run.
<img width="995" height="721" alt="dyslexdria screenshot"
src="https://github.com/user-attachments/assets/8826839f-b4e0-431d-af9c-0b0e43dc601d"
/>
- [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
- Build log, screen shots, and test videos.
https://discord.com/channels/1284581928254701718/1456890656147374080
PlaysBadly
---------
Co-authored-by: Duwibi <86431918+Duwibi@users.noreply.github.com>
Co-authored-by: VariableVince <24507472+VariableVince@users.noreply.github.com>
Requesting that these 4 maps be added temporarily for the April Fools
holiday. Included are:
- A wider version of the Amazon River to allow for larger ships.
- An edit of The Box with more varied terrain.
- A modification to The World which optimizes play for mobile users.
- A custom remix to Antarctica which re-adds ice to the map.
All maps are edits of existing work. All maps have been added as their
own individual map files rather than edits to existing files for ease of
management.
<img width="912" height="1067" alt="temp"
src="https://github.com/user-attachments/assets/089ef59f-8bdf-4c86-b479-620b8c220c3a"
/>
https://discord.com/channels/1284581928254701718/1483786939332169830
- [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
PlaysBadly
## Description:
Make the april fool maps have the same name as the normal maps, in order
to make the prank better.
NOTE: In order for this to work, it re-adds the normal maps into
rotation. These normal maps have been given a lower rotation however.
In custom matches the maps will appear with the april fools names.
This change will be reverted after April Fools.
Check this for proof of it working:
https://canary.discord.com/channels/1359946986937258015/1450487807242932336/1488682300924231882
## 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:
DISCORD_USERNAME
Re-submission, previous request was not branched properly.
## Description:
Add custom map Dyslexdria. Based off of large_world_map_recolor.tif and
rivers from the XL World map. Map is intended for long term use.
Suggesting that map be used as an April Fools gag by replacing thumbnail
and title with 'World' during first run.
<img width="995" height="721" alt="dyslexdria screenshot"
src="https://github.com/user-attachments/assets/8826839f-b4e0-431d-af9c-0b0e43dc601d"
/>
- [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
## Following:
- Build log, screen shots, and test videos.
https://discord.com/channels/1284581928254701718/1456890656147374080
## Discord username:
PlaysBadly
---------
Co-authored-by: Duwibi <86431918+Duwibi@users.noreply.github.com>
Co-authored-by: VariableVince <24507472+VariableVince@users.noreply.github.com>
## Description:
Requesting that these 4 maps be added temporarily for the April Fools
holiday. Included are:
- A wider version of the Amazon River to allow for larger ships.
- An edit of The Box with more varied terrain.
- A modification to The World which optimizes play for mobile users.
- A custom remix to Antarctica which re-adds ice to the map.
All maps are edits of existing work. All maps have been added as their
own individual map files rather than edits to existing files for ease of
management.
<img width="912" height="1067" alt="temp"
src="https://github.com/user-attachments/assets/089ef59f-8bdf-4c86-b479-620b8c220c3a"
/>
https://discord.com/channels/1284581928254701718/1483786939332169830
- [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
## Discord username
PlaysBadly
## Description:
Update from Express 4.22 > 5.2.1. And @types/express 4.17 > 5.0.6.
### CodeQL errors unjustified: Please dismiss the unjustified [CodeQL
scanning
results](https://github.com/openfrontio/OpenFrontIO/security/code-scanning?query=pr%3A3549+tool%3ACodeQL+is%3Aopen)
for playground/server.ts: they were flagged for this PR but i didn't
touch those specific parts of the file. More importantly: it is a test
server, created by Mole/ @Aareksio. I made requests to dismiss the
alerts but don't have the permissions to actually dismiss them myself
Version 5 was the first major upgrade in 10 years when it was released
in Sept 2024. 5.21 is from Dec 2025 so v5 teething problems should be
over by now. Many of its dependencies also updated by some major
versions. So it seems a worthy update but that is for you to decide. v4
will be EOL when v6 arrives, however that could be a year from now still
maybe.
- Migration:
-- Updated package.json, ran `npm install "express@5"` and `npm install
"@types/express@5.0.6"`.
-- Used https://expressjs.com/en/guide/migrating-5.html
-- Ran the codemods from the migration guide `npx codemod@latest
@expressjs/v5-migration-recipe`.
-- Checked manually.
-- Checked again with help of Gemini 3.1 Pro based on same guide.
-- Master.ts: use `*splat` instead of `*`, tested and going to
non-existing URL lands back on index.html like it should.
-- Worker.ts: MIME type _webp_ is now supported natively so remove added
config.
-- playground/server.ts: fix type error after upgrading types/express
for `name` in `req.params`. And `app.listen` handles user provided
callback on error, use that. The latter may not be not needed per se.
-- While v5 does this now "When an error is thrown in an async function
or a rejected promise is awaited inside an async function, those errors
will be passed to the error handler as if calling next(err).", choose to
leave our try/catch'es be. Since we use specific errors, probably easier
for consistency in log searches and user reporting.
- About performance:
-- While [Express 5 seems a bit slower than
4](https://www.repoflow.io/blog/express-4-vs-express-5-benchmark-node-18-24),
it is not by much especially on Node24 which we're on. Also there's a
working group dedicated to improving Express performance, albeit they
expect v6/7 to benefit from that more than v5 will.
-- While there are faster alternatives in benchmarks, [in real-world
usage Express still holds up as one of the best and even beats most
'faster'
alternatives](https://medium.com/deno-the-complete-reference/node-js-the-fastest-web-framework-in-2025-static-file-server-case-1df462ad38cd).
## 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:
tryout33
## Description:
Adds Mediterranean sea map, from Iberia to Asia. Map contains ancient
Roman Empire provinces and its rivals as Nations.
This map was requested by the dev.
elevation data from Opentopography
<img width="2850" height="1450" alt="image"
src="https://github.com/user-attachments/assets/6aa5ba12-f4f7-414d-a712-b90323f1d796"
/>
<img width="590" height="304" alt="Captura de pantalla 2026-03-27
010038"
src="https://github.com/user-attachments/assets/efd1deea-bd88-4ae2-92a0-47a6626a0c0f"
/>
<img width="585" height="302" alt="Captura de pantalla 2026-03-27
005758"
src="https://github.com/user-attachments/assets/a127696e-fe34-424c-a88d-b86b99a5f414"
/>
## 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:
tri.star1011
## Description:
Adds Milky Way galaxy map based on real reconstruction by NASA. Star
density simulated as terrain. Best played in Dark Mode.
Also adds credits to JPL NASA
<img width="532" height="533" alt="Captura de pantalla 2026-03-26
142938"
src="https://github.com/user-attachments/assets/87bb19bb-4e2d-4383-a3e9-6e14b714b84c"
/>
## 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:
tri.star1011
## Description:
When the host of a private lobby disconnects before the game starts, the
lobby is now closed:
- **Server:** Detects host disconnection via `creatorPersistentID`
match, kicks all remaining clients with a `host_left` reason, and marks
the game as ended so it's cleaned up by the game manager and can no
longer be joined.
- **Client:** Participants receive an `alert()` saying "The host has
left the lobby." and their JoinLobbyModal is closed automatically via
the `leave-lobby` event.
- **Phase logic:** `phase()` now returns `Finished` for ended private
lobbies that haven't started, preventing the game from lingering in
`Lobby` state.
## 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:
FloPinguin
## Description:
Adds 5 new public game modifiers to the Special game mode modifier pool:
- **Ports Disabled** - disables port construction, focus on factories
- **Nukes Disabled** - disables atom bombs, hydrogen bombs, MIRVs,
missile silos and SAM launchers
- **SAMs Disabled** - disables SAM launchers (thats funny, you cant
protect against nukes, have to space out your stuff) (mutually exclusive
with nukes disabled)
- **1M Starting Gold** - gives all players 1M starting gold (was
requested by people, new chill tier alongside existing 5M and 25M)
- **4min Peace Time** - grants 4 minutes of PVP spawn immunity
All `PublicGameModifiers` boolean fields are now optional - inactive
modifiers are omitted from game JSON instead of being serialized as
`false` (stop bloating the JSON size)
I think we have enough modifiers now :) Good variety
## 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:
FloPinguin
## Description:
needs prereq of https://github.com/openfrontio/infra/pull/272
## 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:
w.o.n
## Description:
Add support for purchasable/gated flags.
* Create a new "Store" modal that renders both skins & flags
* move all store related logic out of TerritoryPatternsModal
* use nation:code for existing nation flags & flag:key for gated flags
* check if user has the appropriate flags before purchasing
## 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
Normal (FFA and Team) public games no longer roll random modifiers.
Special games remain fully unaffected and continue to use random
modifiers as before.
I also increased the gold multiplier ticket count in the special
modifier pool from 1 to 4 because of player feedback.
Edit: And because I saw complaints of too much random spawn I decreased
the chance of it.
- [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
regression is found:
FloPinguin
Normal (FFA and Team) public games no longer roll random modifiers.
Special games remain fully unaffected and continue to use random
modifiers as before.
I also increased the gold multiplier ticket count in the special
modifier pool from 1 to 4 because of player feedback.
Edit: And because I saw complaints of too much random spawn I decreased
the chance of it.
- [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
regression is found:
FloPinguin
## Description:
This reworks asset delivery and cacheability across the app and moves
non-bundled public resources onto immutable, content-hashed URLs.
Vite bundle outputs continue to live under `/assets/**` and remain
content-hashed by Vite. Public resources that were previously fetched
from stable paths in `resources/` now go through a custom hashed
namespace under `/_assets/**`, backed by a generated asset manifest that
is available to the server, browser, and worker runtime.
In parallel, the root app shell is now cacheable shared HTML instead of
request-time `no-store` HTML. Dynamic and live routes remain explicitly
uncached.
## Why
- Improve browser and Cloudflare cacheability for static assets.
- Remove query-string and release-version cache busting for
runtime-fetched assets.
- Allow unchanged public assets to keep the same URL across releases.
- Reduce avoidable work on `/` by serving a shared app shell instead of
rendering HTML on every request.
- Make cache behavior explicit instead of relying on mixed framework
defaults and file-extension heuristics.
## What Changed
### 1. Content-hashed public asset pipeline
- Added a build-time public asset manifest and hashing pipeline for
non-Vite resources.
- Production now emits hashed public assets under `/_assets/**`.
- Added runtime manifest loading for Node so server-rendered paths
resolve against built hashed files instead of rebuilding from source at
runtime.
- Emitted the runtime asset manifest as an ESM module for server
consumption.
Result:
- `/assets/**` = Vite-managed hashed bundle outputs
- `/_assets/**` = custom content-hashed public resources
### 2. Runtime asset URL migration
- Added a shared `assetUrl(...)` resolution path.
- Migrated runtime references away from query-string versioning and
stable source paths.
- Updated browser, worker, and server-side rendering paths to resolve
through the asset manifest.
- Moved map manifests, map binaries, thumbnails, sprites, sounds, fonts,
flags, icons, screenshots, and other runtime-fetched resources onto
hashed URLs.
### 3. Map and preview fixes
- Fixed directory and per-file map asset resolution so map manifest and
binary fetches resolve to the correct hashed URLs.
- Updated preview metadata and map thumbnail paths to use the hashed
asset namespace.
- Fixed runtime manifest loading in prod after deployment.
### 4. Explicit cache policies
- Added explicit immutable cache headers for:
- `/assets/**`
- `/_assets/**`
- worker-prefixed equivalents under `/wN/...`
- Added explicit `no-store` headers for live and dynamic APIs.
- Removed the old `/api/env` bootstrap request and baked `gameEnv` into
the HTML bootstrap instead.
### 5. Cacheable root app shell
- Refactored the root HTML path to serve a shared app shell with:
- `Cache-Control: public, max-age=0, s-maxage=300,
stale-while-revalidate=86400`
- `/` and the SPA fallback now serve shared cacheable HTML instead of
request-time `no-store` rendering.
- `/game/:id` remains dynamic and `no-store`, but now reuses the shared
shell before injecting preview tags.
### 6. Matchmaking instance handling
- Because the app shell is now cacheable, `INSTANCE_ID` was removed from
shared HTML.
- Added `/api/instance` as a temporary `no-store` runtime lookup used
only by matchmaking.
- This preserves correctness with the current random-per-boot
`INSTANCE_ID` model while keeping `/` cacheable, but it is not the
intended long-term design.
## Behavior Changes
### Asset URL contract
Production URLs for non-Vite public resources now change from stable
paths such as:
- `/maps/...`
- `/images/...`
- `/manifest.json`
to content-hashed paths under:
- `/_assets/...`
Examples:
- `/_assets/maps/<map>/manifest.<hash>.json`
- `/_assets/images/Favicon.<hash>.svg`
### Bootstrap/config
- `/api/env` is removed.
- `gameEnv` is now bootstrapped from HTML.
### HTML caching
- `/` and the SPA fallback are now cacheable shared HTML.
- `/game/:id` remains dynamic.
## Cache Matrix After This Branch
- `/_assets/**`: `public, max-age=31536000, immutable`
- `/assets/**`: `public, max-age=31536000, immutable`
- live `/api/**`: explicit `no-store`
- `/api/health`: explicit `no-store`
- `/api/instance`: explicit `no-store`
- `/game/:id`: explicit `no-store`
- `/` and SPA fallback: `public, max-age=0, s-maxage=300,
stale-while-revalidate=86400`
## Notes / Tradeoffs
- `/api/instance` is a temporary compromise. It exists because
`INSTANCE_ID` is currently random per boot, which is not safe to embed
into cacheable shared HTML.
- The current matchmaking flow still asks the client to provide
`instance_id` during `matchmaking/join`. That is functional, but it is
the wrong ownership boundary: instance selection should be handled by
the matchmaking service, not by the browser.
- The cleaner end-state would be:
- make `matchmaking/join` stop requiring `instance_id` from the client,
and let the matchmaking service select a healthy instance from worker
check-ins
- This branch makes the origin behavior edge-cache-friendly, but
Cloudflare still needs matching cache rules if HTML itself should be
cached at the edge.
## Validation
Verified during development with:
- `npx tsc --noEmit`
- `node node_modules\\vite\\bin\\vite.js build`
- `node node_modules\\vitest\\vitest.mjs run
tests/server/RenderHtml.test.ts tests/server/NoStoreHeaders.test.ts
tests/server/StaticAssetCache.test.ts
tests/core/configuration/ConfigLoader.test.ts`
Additional targeted tests added:
- `tests/AssetUrls.test.ts`
- `tests/core/game/FetchGameMapLoader.test.ts`
- `tests/core/configuration/ConfigLoader.test.ts`
- `tests/server/NoStoreHeaders.test.ts`
- `tests/server/StaticAssetCache.test.ts`
- `tests/server/RenderHtml.test.ts`
## Known Existing Warnings
The production build still reports pre-existing warnings that are not
addressed by this branch:
- inconsistent JSON import attributes for `resources/countries.json`
- inconsistent JSON import attributes for `resources/QuickChat.json`
- large chunk warnings from Vite
## Rollout Notes
- Cache rules should treat `/_assets/**` and `/assets/**` as immutable.
- Cloudflare will still classify HTML as dynamic after deploy unless
matching edge cache rules are configured for it.
## Follow-ups
- Remove `/api/instance` by changing `matchmaking/join` so the server
selects the target instance, or by making `INSTANCE_ID` deploy-stable if
the current contract must remain.
## Please complete the following:
- [ ] I have added screenshots for all UI updates
- [ ] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [ ] I have added relevant tests to the test directory
- [ ] 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:
DISCORD_USERNAME
## Description:
Perviously, JoinLobbyModal did not show settings like "Infinite gold" or
"Instant Build" or changed tribe count.
Now it does. Only if the setting differs from the default. I tested a
lot of scenarios, I also thought of the public game modifiers.
And we show a small map image now.
Public game with lots of modifiers:
<img width="780" height="758" alt="Screenshot 2026-03-21 011805"
src="https://github.com/user-attachments/assets/9d3fcaa9-3a50-42b2-a351-ac737ef18230"
/>
A private game with lots of custom settings:
<img width="776" height="530" alt="Screenshot 2026-03-21 011940"
src="https://github.com/user-attachments/assets/8f9a3809-844d-4f24-8f92-46c4ce480f8c"
/>
A private game with disabled units:
<img width="786" height="562" alt="Screenshot 2026-03-21 012134"
src="https://github.com/user-attachments/assets/61058329-1d86-4667-a945-7819b89cbf41"
/>
Regular public FFA (No modifiers):
<img width="780" height="372" alt="Screenshot 2026-03-21 012228"
src="https://github.com/user-attachments/assets/abdc42f0-8f2c-40c1-8719-76c648a12bae"
/>
This PR also includes a fix for UsernameInput:
<img width="910" height="647" alt="Screenshot 2026-03-20 222021"
src="https://github.com/user-attachments/assets/e1922395-9dfc-4b32-b987-e2dbff9af917"
/>
This PR also fixes the default private lobby difficulty in GameManager
## 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:
FloPinguin
## Description:
Normal (FFA and Team) public games no longer roll random modifiers.
Special games remain fully unaffected and continue to use random
modifiers as before.
I also increased the gold multiplier ticket count in the special
modifier pool from 1 to 4 because of player feedback.
Edit: And because I saw complaints of too much random spawn I decreased
the chance of it.
## 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:
FloPinguin
## Description:
Normal (FFA and Team) public games no longer roll random modifiers.
Special games remain fully unaffected and continue to use random
modifiers as before.
I also increased the gold multiplier ticket count in the special
modifier pool from 1 to 4 because of player feedback.
Edit: And because I saw complaints of too much random spawn I decreased
the chance of it.
## 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:
FloPinguin
## Description:
Increases the spawn immunity duration from 30s to 45s for maps with 5M
starting gold.
The previous 30s was too short - 45s gives players 15s longer than it
takes to build a SAM, allowing them to establish basic defenses before
becoming vulnerable.
## 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:
FloPinguin
## Description:
Increases the spawn immunity duration from 30s to 45s for maps with 5M
starting gold.
The previous 30s was too short - 45s gives players 15s longer than it
takes to build a SAM, allowing them to establish basic defenses before
becoming vulnerable.
## 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:
FloPinguin
## Description:
Prevent client from spamming ws messages before joining a game server.
## 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
## Description:
On replays, there can be a burst of traffic from hashes, so instead just
have a 2MB limit per client for the entire game. Also the winner message
can be 100s of kb on a large game with many players, so now we don't
need to put a special case for that.
## 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
## Description:
For the next v30 fix version
<img width="868" height="364" alt="imaege"
src="https://github.com/user-attachments/assets/520a999c-67e7-4c57-8651-895ad9eeb73a"
/>
HvN balancing for the revamped difficulty steps of v30 sadly doesn't
really work out...
In medium difficulty games humans nearly always win (boring)
In hard difficulty games humans usually lose
It was intended differently...
So lets get rid of medium difficulty HvN, always use hard difficulty and
disable the donation-capability for public game nations.
That will tune the human winrate towards a middle ground at about 65% I
think. Which should be nice.
Easier than in v29 (was frustrating sometimes) but not as easy as it's
now.
We can only test this in prod lol
## 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:
FloPinguin
## Description:
For the next v30 fix version
<img width="868" height="364" alt="imaege"
src="https://github.com/user-attachments/assets/520a999c-67e7-4c57-8651-895ad9eeb73a"
/>
HvN balancing for the revamped difficulty steps of v30 sadly doesn't
really work out...
In medium difficulty games humans nearly always win (boring)
In hard difficulty games humans usually lose
It was intended differently...
So lets get rid of medium difficulty HvN, always use hard difficulty and
disable the donation-capability for public game nations.
That will tune the human winrate towards a middle ground at about 65% I
think. Which should be nice.
Easier than in v29 (was frustrating sometimes) but not as easy as it's
now.
We can only test this in prod lol
## 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:
FloPinguin
## Description:
* Adds ClientMsgRateLimiter — a per-client token-bucket rate limiter
that gates all incoming WebSocket messages. Returns "ok", "limit"
(drop), or "kick" based on the violation type.
* Intent messages are capped at 500 bytes each (they are stored in turn
history for the game duration, so oversized intents
accumulate in server RAM). Violations kick the client.
* Winner messages bypass the byte rate limit (they include stats for all
players and can be 100s of KB) but are strictly capped at one per client
— a second winner message kicks the client.
* All other messages go through the standard per-second (10/s) and
per-minute (150/min) rate limits. Violations drop the message; byte
budget exhaustion kicks the client.
* WebSocket maxPayload set to 2 MB on game workers.
Invalid (unparseable) messages now immediately kick the client rather
than being silently dropped.
Unit tests added for all rate limiting behaviors.
## 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