mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 09:10:42 +00:00
embeddedurlfix
3339 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
b4e8f1b4f7 | Merge branch 'main' into embeddedurlfix | ||
|
|
5594109641 |
Build(deps): bump fast-xml-parser from 5.3.6 to 5.4.1 in the npm_and_yarn group across 1 directory (#3347)
Bumps the npm_and_yarn group with 1 update in the / directory: [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser). Updates `fast-xml-parser` from 5.3.6 to 5.4.1 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/NaturalIntelligence/fast-xml-parser/releases">fast-xml-parser's releases</a>.</em></p> <blockquote> <h2>Separate Builder</h2> <p>XML Builder was the part of <a href="https://github.com/NaturalIntelligence/fast-xml-builder">fast-xml-parser</a> for years. But considering that any bug in builder may false-alarm the users who are only using parser and vice-versa, we have decided to split it into a separate package.</p> <h2>Migration</h2> <p>To migrate to fast-xml-builder;</p> <p>From</p> <pre lang="js"><code>import { XMLBuilder } from "fast-xml-parser"; </code></pre> <p>To</p> <pre lang="js"><code>import XMLBuilder from "fast-xml-builder"; </code></pre> <p>XMLBuilder will be removed from current package in any next major version of this library. So better to migrate.</p> <h2>support strictReservedNames</h2> <p><strong>Full Changelog</strong>: <a href="https://github.com/NaturalIntelligence/fast-xml-parser/compare/v5.3.9...v5.3.9">https://github.com/NaturalIntelligence/fast-xml-parser/compare/v5.3.9...v5.3.9</a></p> <h2>handle non-array input for XML builder && support maxNestedTags</h2> <ul> <li>support maxNestedTags</li> <li>handle non-array input for XML builder when preserveOrder is true (By <a href="https://github.com/Angelopvtac">Angelo Coetzee</a>)</li> <li>save use of js properies <strong>Full Changelog</strong>: <a href="https://github.com/NaturalIntelligence/fast-xml-parser/compare/v5.3.7...v5.3.8">https://github.com/NaturalIntelligence/fast-xml-parser/compare/v5.3.7...v5.3.8</a></li> </ul> <h2>CJS typing fix</h2> <h2>What's Changed</h2> <ul> <li>Unexport <code>X2jOptions</code> at declaration site by <a href="https://github.com/Drarig29"><code>@Drarig29</code></a> in <a href="https://redirect.github.com/NaturalIntelligence/fast-xml-parser/pull/787">NaturalIntelligence/fast-xml-parser#787</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/Drarig29"><code>@Drarig29</code></a> made their first contribution in <a href="https://redirect.github.com/NaturalIntelligence/fast-xml-parser/pull/787">NaturalIntelligence/fast-xml-parser#787</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/NaturalIntelligence/fast-xml-parser/compare/v5.3.6...v5.3.7">https://github.com/NaturalIntelligence/fast-xml-parser/compare/v5.3.6...v5.3.7</a></p> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md">fast-xml-parser's changelog</a>.</em></p> <blockquote> <p><!-- raw HTML omitted -->Note: If you find missing information about particular minor version, that version must have been changed without any functional change in this library.<!-- raw HTML omitted --></p> <p>Note: Due to some last quick changes on v4, detail of v4.5.3 & v4.5.4 are not updated here. v4.5.4x is the last tag of v4 in github repository. I'm extremely sorry for the confusion</p> <p><strong>5.4.2 / 2026-03-03</strong></p> <ul> <li>support maxEntityCount option</li> </ul> <p><strong>5.4.1 / 2026-02-25</strong></p> <ul> <li>fix (<a href="https://redirect.github.com/NaturalIntelligence/fast-xml-parser/issues/785">#785</a>) unpairedTag node should not have tag content</li> </ul> <p><strong>5.4.0 / 2026-02-25</strong></p> <ul> <li>migrate to fast-xml-builder</li> </ul> <p><strong>5.3.9 / 2026-02-25</strong></p> <ul> <li>support strictReservedNames</li> </ul> <p><strong>5.3.8 / 2026-02-25</strong></p> <ul> <li>support maxNestedTags</li> <li>handle non-array input for XML builder when preserveOrder is true (By <a href="https://github.com/Angelopvtac">Angelo Coetzee</a>)</li> <li>save use of js properies</li> </ul> <p><strong>5.3.7 / 2026-02-20</strong></p> <ul> <li>fix typings for CJS (By <a href="https://github.com/Drarig29">Corentin Girard</a>)</li> </ul> <p><strong>5.3.6 / 2026-02-14</strong></p> <ul> <li>Improve security and performance of entity processing <ul> <li>new options <code>maxEntitySize</code>, <code>maxExpansionDepth</code>, <code>maxTotalExpansions</code>, <code>maxExpandedLength</code>, <code>allowedTags</code>,<code>tagFilter</code></li> <li>fast return when no edtity is present</li> <li>improvement replacement logic to reduce number of calls</li> </ul> </li> </ul> <p><strong>5.3.5 / 2026-02-08</strong></p> <ul> <li>fix: Escape regex char in entity name</li> <li>update strnum to 2.1.2</li> <li>add missing exports in CJS typings</li> </ul> <p><strong>5.3.4 / 2026-01-30</strong></p> <ul> <li>fix: handle HTML numeric and hex entities when out of range</li> </ul> <p><strong>5.3.3 / 2025-12-12</strong></p> <ul> <li>fix <a href="https://redirect.github.com/NaturalIntelligence/fast-xml-parser/issues/775">#775</a>: transformTagName with allowBooleanAttributes adds an unnecessary attribute</li> </ul> <p><strong>5.3.2 / 2025-11-14</strong></p> <ul> <li>fix for import statement for v6</li> </ul> <p><strong>5.3.1 / 2025-11-03</strong></p> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/NaturalIntelligence/fast-xml-parser/commit/4e7ca80e788a23b07531ac2ff8906e5e9f4bf892"><code>4e7ca80</code></a> update release info</li> <li><a href="https://github.com/NaturalIntelligence/fast-xml-parser/commit/36023b496382717c82bd68863b3f95629d0c9311"><code>36023b4</code></a> fix (<a href="https://redirect.github.com/NaturalIntelligence/fast-xml-parser/issues/785">#785</a>) unpairedTag node should not have tag content</li> <li><a href="https://github.com/NaturalIntelligence/fast-xml-parser/commit/b3660266f53e383193ae152cde878d9b2db7240f"><code>b366026</code></a> separate builder</li> <li><a href="https://github.com/NaturalIntelligence/fast-xml-parser/commit/6f333a85693e20713fea2d733795fef7e11ac51c"><code>6f333a8</code></a> update release info</li> <li><a href="https://github.com/NaturalIntelligence/fast-xml-parser/commit/c3ffbab9e5a2bab9db65803933d0af656076fc33"><code>c3ffbab</code></a> support strictReservedNames</li> <li><a href="https://github.com/NaturalIntelligence/fast-xml-parser/commit/c692040f6b5f5045d38b66b1da04e4d3abc97052"><code>c692040</code></a> update release info</li> <li><a href="https://github.com/NaturalIntelligence/fast-xml-parser/commit/107e34c046d4997ee3b67a32d32eef52fe63edb2"><code>107e34c</code></a> avoid <code>{}</code> to create an empty object</li> <li><a href="https://github.com/NaturalIntelligence/fast-xml-parser/commit/60835a4c7279ddc349d192097fb41afa52930d8b"><code>60835a4</code></a> support maxNestedTags</li> <li><a href="https://github.com/NaturalIntelligence/fast-xml-parser/commit/f55657c2b1cf29b433124390c32acba45a5a67aa"><code>f55657c</code></a> avoid direct call to hasOwnProperty</li> <li><a href="https://github.com/NaturalIntelligence/fast-xml-parser/commit/c13a961910f14986295dd28484eee830fa1a0e8a"><code>c13a961</code></a> handle non-array input for XML builder when preserveOrder is true</li> <li>Additional commits viewable in <a href="https://github.com/NaturalIntelligence/fast-xml-parser/compare/v5.3.6...v5.4.1">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore <dependency name> major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore <dependency name> minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore <dependency name>` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore <dependency name>` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore <dependency name> <ignore condition>` will remove the ignore condition of the specified dependency and ignore conditions You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/openfrontio/OpenFrontIO/network/alerts). </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Evan <evanpelle@gmail.com> |
||
|
|
c594487f5e |
Starting gold input in millions with decimal support ✨ (#3349)
## Description: **Starting gold input: use millions** Changes the starting gold input in singleplayer and host lobby modals to accept values in millions (e.g. enter `5` for 5M gold). Supports decimals like `6.6` for 6.6M. The value is multiplied by 1,000,000 before being sent to the game config. - Label updated to "Starting Gold (Millions)" - Input uses float parsing with min 0.1, matching gold multiplier behavior - JoinLobbyModal shows clean values without unnecessary decimals (e.g. "5M" not "5.00M") Previous <img width="215" height="139" alt="image" src="https://github.com/user-attachments/assets/00ce5b6d-f74d-4aee-92f5-c9be1a0a6d3d" /> <img width="292" height="74" alt="image" src="https://github.com/user-attachments/assets/4de936a3-22bd-4ffc-8dbe-0d5066f28186" /> Now <img width="216" height="151" alt="image" src="https://github.com/user-attachments/assets/489de13e-65b5-4b02-a654-5f6f74b165d1" /> <img width="292" height="72" alt="image" src="https://github.com/user-attachments/assets/51723d5a-55ab-4b7b-bbce-011a586eeb44" /> ## 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 |
||
|
|
6254cc0598 |
Add Arctic map (#3341)
## Description: Adds Arctic map, a map centered about the Geographical North Pole using an azimuthal equidistant projection. Features Cold War themed countries and subdivisions as nations. Square map with 1.6M land tiles. Terrain data from Opentopography and Arctic SDI real relief data <img width="1830" height="1830" alt="image" src="https://github.com/user-attachments/assets/0b8b1e42-f477-4ebf-a256-c07536db87d9" /> ## 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 |
||
|
|
0dc520b1c8 |
Add confirmation dialog before closing host lobby modal 🔧 (#3364)
## Description: Show a confirm prompt when the user tries to close the host lobby via click-outside or Escape key, preventing accidental lobby exits. Happened to many people and also DougDoug... Does not show the prompt when the user clicks the arrow button because it's probably intentional. ## 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 |
||
|
|
6154b779f5 |
Fix compact map playercount 🔧 (#3361)
## Description: The recently improved `supportsCompactMapForTeams` only checked that each team had ≥2 players but not that there were ≥2 teams. On very small maps with compact + Duos (rare), this allowed lobbies with 1 team of 2, which makes no sense (Wonder noticed that randomly while looking at the homepage). Added a `numberOfTeams ≥ 2` check so the compact map modifier isn't active when the player count can't sustain multiple teams. The 125-player performance cap was also applied inside `calculateMapPlayerCounts` before the compact 75% reduction, so a map sized for 200 players would get capped to 125 then reduced to 31 instead of the expected 50. Moved the cap (`MAX_PLAYER_COUNT`) to after the compact reduction. ## 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 |
||
|
|
0733c680b9 |
homepage UI improvements (#3352)
## Description: A bunch of small UI improvements: * Make the content width a bit smaller so gutter ads fit * remove the "duos" "trios" "quads" description on the game card since it's redundant * update UI in game card * minor footer layout changes * update z-index to ensure content appears above ads * removed hasUnusualThumbnailSize, instead just check the map ratio * Use "object cover" for non-irregular maps to the entire game card is filed * remove white ouline from the version * changed solo button to sky blue * make timer "s" lowercase I think we may need to change the openfront logo color a bit too to match the color palette, but we can do that in a follow up. <img width="1591" height="969" alt="Screenshot 2026-03-05 at 2 04 48 PM" src="https://github.com/user-attachments/assets/7bb9ea4c-5a17-47e1-bdad-9d6437b363b3" /> ## 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 |
||
|
|
47ef5a032b |
update favicon to blue warship icon (#3360)
## Description: light mode: <img width="160" height="31" alt="Screenshot 2026-03-05 at 1 44 26 PM" src="https://github.com/user-attachments/assets/2b80979c-9a4a-45c2-9fbc-bd6e48ddd823" /> dark mode: <img width="172" height="50" alt="Screenshot 2026-03-05 at 1 44 34 PM" src="https://github.com/user-attachments/assets/2cfa12cb-cd8e-4466-a2e2-1ccb9b7f2538" /> ## 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 |
||
|
|
b3c01d4c85 |
improve streamer mode (#3353)
## Description: improves streamer mode (doesn't show the gameID in the url, it just says "streamer-mode" ## 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 |
||
|
|
cf3e3a7a74 |
Fix bot/nation player ID collisions causing missing players 🔧 (#3354)
## Description: BotSpawner used the same PRNG seed (simpleHash(gameID)) as createGameRunner, causing bot IDs to collide with nation IDs. When a bot's SpawnExecution found a nation with the same ID via hasPlayer(), it silently reused that nation instead of creating a new player - resulting in far fewer players than configured (e.g. ~670 instead of 800 with 400 bots + 400 nations) with no console warnings. Offsets the BotSpawner seed by +2 to avoid the shared PRNG sequence (matching the +1 pattern already used by Executor). ## 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 |
||
|
|
e137fcaa6c |
Fix/Perf/Refactor: playerActions and buildableUnits, their callers and related types (#3220)
## Description: TL;DR: it's faster. buildableUnits is called via PlayerView.actions from UnitDisplay (each tick without TileRef), BuildMenu (each tick when open), MainRadialMenu (each tick when open), PlayerPanel (each tick when open), StructureIconsLayer (when placing a building from build bar), NukeTrajectoryPreviewLayer (when placing nuke, on tick when tile changes), ClientGameRunner (on click to attack/auto-boat or hotkey B or G). After https://github.com/openfrontio/OpenFrontIO/pull/3213 got merged, the change with largest impact in https://github.com/openfrontio/OpenFrontIO/pull/3193 was done in such a different way that a new PR was needed The idea in 3193 was to not always ask for Transport Ship from buildableUnits. In such a way that very little extra data was send to the worker. This had the biggest impact on performance (the idea was months older btw, see https://github.com/openfrontio/OpenFrontIO/pull/2295). Now, we do it the other way around, by telling buildableUnits all unit types we want. Or we want them all (undefined). The downside is more data is send in the worker message. The upside is we have more options and can add more in this PR. This PR implements some of the leftovers in 3193 on top of 3213 and adds further improvements. (Some unrelated refactor/perf changes where moved out of this PR and into already merged https://github.com/openfrontio/OpenFrontIO/pull/3233, https://github.com/openfrontio/OpenFrontIO/pull/3234, https://github.com/openfrontio/OpenFrontIO/pull/3235, https://github.com/openfrontio/OpenFrontIO/pull/3236, https://github.com/openfrontio/OpenFrontIO/pull/3237, https://github.com/openfrontio/OpenFrontIO/pull/3238, https://github.com/openfrontio/OpenFrontIO/pull/3239) - **GameRunner**, **WorkerMessages**: _playerActions_ and _PlayerActionsMessage ._ Option to ask for no buildable units (null). It now has 3 modes: get all actions and all buildings (units undefined), get all actions and no buildings (units null), or get all actions and specific building (units contains Unit Types). - **GameRunner**: _playerActions_. fixes wrong assumption in PR 3213: that only if units was undefined, we have to know canAttack. ClientGameRunner wants to know both, in case of a click on non-bordering land, to decide if it should auto-boat using a Transport Ship. So units is not undefined (we only ask for Transport Ship now which has a positive effect on performance for each click/tap) but we need canAttack still. Solved by removing the unit === undefined check before _canAttack_ in _playerActions_. - **GameRunner**, **GameView**, **WorkerClient**, **WorkerMessages**, **Worker.worker**: added _playerBuildables_ / _buildables_ next to existing _playerActions_ / _actions_. With above solved, there was still no option to only get buildable units when the actions are not needed. While **StructureIconsLayer**, **NukeTrajectoryPreviewLayer**, **BuildMenu** and **UnitDisplay** need only that. To not make playerActions more convoluted with more params or so, i've added a new function _playerBuildables_ in **GameView** to only get buildable units (**GameRunner** _playerBuildables_). _playerBuildables_ has 2 modes: get all buildings (units undefined) or get specific buildings (units contains Unit Types). Also update some comments that mentioned .actions in **NukeTrajectoryPreviewLayer**. - **ClientGameRunner**, **PlayerPanel**, **BuildMenu**, **UnitDisplay**, **StructureIconsLayer** and **NukeTrajectoryPreviewLayer**: Since PR 3213, **StructureIconsLayer** and **NukeTrajectoryPreviewLayer** ask for specific types of units from **GameView** _actions_ (**GameRunner** playerActions). Now have the other files do the same. For example **BuildMenu** asks for the new _BuildMenuTypes_ when it calls ._buildables_ and **ClientGameRunner** asks for UnitType.TransportShip when sending a boat - **ClientGameRunner**: canBoatAttack now accepts BuildableUnit[] instead of PlayerActions so we can send it either actions.buildableUnits or just buildables. Have functions call myPlayer.buildables(tileRef, [UnitType.TransportShip]) when we only need a buildable unit and no actions. Or myPlayer.actions(tileRef, null) when we need actions but no buildable units. Or myPlayer.actions(tileRef, [UnitType.TransportShip]) when we need both actions, like canAttack, and a buildable unit. Then if needed send either actions.buildableUnits or buildables to to _canAutoBoat_ / _canBoatAttack_. - **MainRadialMenu**: needs all player buildable unit types including Transport Ship, so the _actions_ call argument for unit types can stay undefined (unchanged) there. - **MainRadialMenu**: now that **BuildMenu** uses _playerBuildables_ instead of _playerActions_, we must put data in _this.buildMenu.playerBuildables_. And since we're not putting the (unneeded) full _actions_ in there anymore, we can now put only the needed and expected _actions._buildableUnits_ in it. - **Game**, **PlayerImpl**, **StructureIconsLayer**: Typesafety and some added perf: new type _PlayerBuildableUnitType_ (see also the below point for how it is formed). So callers of _buildableUnits_ can never ask for the wrong type like e.g. UnitType.Train because it doesn't return data for that type. This type is now used in **PlayerImpl**, **BuildMenu**, **RadialMenuElements**, **StructureDrawingUtils** and **UnitDisplay** for that reason. And **InputHandler**, **StructureIconsLayer** and **UIState** (little more on that in point below). - **InputHandler**, **StructureIconsLayer**, **UIState**: In order to make type safety work for GhostUnit.buildableUnit.type too (line ~217 of StructureIconsLayer), changed type of interface _BuildableUnit_ to _PlayerBuildableType_. Which is only more accurate. Same for and this.structures and uiState.ghostStructure and with the latter, _renderUnitItem_ in **UnitDisplay** and _setGhostStructure_ in **InputHandler**. All Structures are of PlayerBuildableType (there are even some in PlayerBuildables that aren't Structures, but it is much more confined than UnitType). - **Game**: Typesafety and some added perf: added _BuildMenus_ and _BuildableAttacks_ in the same fashion that the existing StructureTypes was already used (simplified it a bit too, with it renamed _StructureTypes_ to _Structures_ and removed _isStructureType_). They can be used with .types or .has(). _BuildableAttacks_.has() is used in **RadialMenuElements**. _BuildableAttacks_ and existing _Structures_ now make up _BuildMenus_. Which is used in **BuildMenu**, **StructureIconsLayer** and **UnitDisplay**. Then _BuildMenus_ together with UnitType.TransportShip make up the _PlayerBuildables_. Which is used in **PlayerImpl** _buildableUnits_ (see point below). And with _PlayerBuildableUnits_ we get the new _PlayerBuildableUnitType_ (see above point on Game / PlayerImpl). - **RadialMenuElements**: replace non-central ATTACK_UNIT_TYPES in **RadialMenuElements** with centralized _BuildableAttackTypes_ too. Use _PlayerBuildableUnitType_ for more type safety (can't by mistake add UnitType.Train to its build menu). Make use of _BuildableAttackTypes_ instead of adding items hardcoded line by line in _getAllEnabledUnits_, just like we already did since PR 3239 with _StructureTypes_. And use _BuildableAttacks.types_ in the same fashion that existing _isStructureTypes_ (now Structures.types) was already used elsewhere. - **PlayerImpl**: _buildableUnits_ -- would do Object.values(UnitTypes) on every call. Now for better perf directly loop over player buildable units by using _PlayerBuildables_ (see above point). In this way we also exclude MIRVWarhead, TradeShip, Train, SamMissile and Shell so there are less unit types to loop through by default. Since a player doesn't build those by themselves, they are only build by Executions which use _canBuild_ directly and not _buildableUnits_. -- for more performance, do for loop instead of using .map and .filter, no intermediate array needed nor callback overhead. We just loop over the given units (which if undefined will contain _PlayerBuildables_). Also pre-allocate the results array to get the most out of it, even if V8 might already be very good at this. -- cache config, railNetwork and inSpawnPhase so they can be re-used inside the for loop. -- cache cost inside the loop -- it would check twice for tile!==null to decide to call findUnitToUpgrade and canBuild. Now once. -- eliminated double/triple checks for the same thing. It called _findUnitToUpgrade_ (and with that _canUpgradeUnit_) and then _canBuild_ which both check if player has enough gold for the cost of the unit type. And they both check if the unit type is disabled. Now we call private functions _canBuildUnitType_, _canUpgradeUnitType_ to first do checks on unit type level for early returns, and _findExistingUnitToUpgrade_ to find existing unit without doing anything extra. in a specific order to check everything only once. The public functions _findUnitToUpgrade_ and _canBuild_ have an unchanged functionality and we don't call them from _buildableUnits_ anymore. -- would get _overlappingRailRoads_ and _computeGhostRailPaths_ when canBuild was true. But this data is only meant for **StructureIconsLayer** and it logically only uses it when placing a new unit, not when upgrading one. Which is also commented on line 351 of **StructureIconsLayer**. So, we now only get overlapping railroads and ghost rails if we're not hovering to upgrade an existing unit. - **PlayerImpl**: _findUnitToUpgrade_: unchanged functionality, but have it call new private function _findExistingUnitToUpgrade_ to find existing unit. - **PlayerImpl**: _canBuild_: unchanged functionality, but have it call new private function _canBuildUnitType_ to do the checks it first did itself. And then new private function _canSpawnUnitType_ for the rest of the checks. This way we can call _canBuildUnitType_ and _canSpawnUnitType_ from _buildableUnits_ in a specific order to prevent double/triple checks. - **PlayerImpl**: _canBuildUnitType_: new private function to be shared by _buildableUnits_, _canBuild_ and _canUpgradeUnit_ to be able do unit type level checks in a specific order to prevent double/triple checks. Via parameter knownCost, _buildableUnits_ can send it the cost it already fetched so that it doesn't have to be fetched again. For caller _canUpgradeUnit_, the isAlive() check (which was previously only done in canBuild) is new but harmless, maybe even better to have also check isAlive() on upgrade now that Nations are also upgrading which might prevent some edge case bugs. - **PlayerImpl**: _canUpgradeUnitType_: new private function to be shared by _buildableUnits_ and _canUpgradeUnit_ to be able do unit type level checks in a specific order to prevent double/triple checks. - **PlayerImpl**: _canSpawnUnitType_: new private function to be shared by _buildableUnits_ and _canBuildUnit_ to be able do unit type level checks in a specific order to prevent double/triple checks. - **PlayerImpl**: _findExistingUnitToUpgrade_: new private function to be shared by _buildableUnits_ and _findUnitToUpgrade_ to be able do unit level checks in a specific order to prevent double/triple checks. - **PlayerImpl**: _isUnitValidToUpgrade_: new private function to be shared by _buildableUnits_ and _canUpgradeUnit_ to be able do unit level checks in a specific order to prevent double/triple checks. - **PlayerImpl.test.ts**: because of the isAlive() check in which is new for _canUpgradeUnit_ (see above at _canBuildUnitType_), the tests needed to have the players be alive at the start, in order to pass. - **BuildMenu**: use .find instead of .filter in canBuildOrUpgrade, a function we already needed to change. This is faster and prevents an allocation. **PERFORMANCE** As for calling ._buildables_ instead of unnecessarily getting ._actions_, there is an obvious win because there's less to send calculate and recieve. Also asking for only the needed buildings helps a lot (especially if TradeShip isn't needed, see the difference in benchmark in original #3193). But the real-world impact is hard to measure. gave it a try in #3193 and those results should be even better now. Now testing only _buildableUnits_ performance in a synthetic benchmark, we get these results. This is after other performance improvments so the base is already better than it was in original #3193: **BEFORE** (only buildableUnits itself) <img width="602" height="96" alt="image" src="https://github.com/user-attachments/assets/7770c0fa-a35e-42fc-90de-1de83242ec23" /> **AFTER** (only buildableUnits itself) <img width="603" height="91" alt="image" src="https://github.com/user-attachments/assets/a1578382-7010-4160-937c-7117bad18beb" /> ## 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 --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> |
||
|
|
2a0b0f890d | fix build 'cannot find RankedType' in ApiSchemas.ts | ||
|
|
0976c02326 | bugfix: add 'Basic' to the otel auth header | ||
|
|
c701ddbdcc | Merge branch 'v29' | ||
|
|
799da9d1b7 |
Migrate to a new prod machine: falk2 (#3346)
## Description: Migrate to a beefier machine ## 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 |
||
|
|
d828ecfabf |
Add traefik with tls to startup script (#3343)
## Description: We are migrating to traefik and away from CF tunnels due to reliability issues. This PR sets up traefik with tls configured. ## 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 |
||
|
|
8524afed65 |
Bugfix: Update PlayerGameSchema.map from GameMapType enum to string
Same issue as the users/@me response: a user played a map that doesn't exist on production |
||
|
|
2139fbf1d8 |
bugfix: change SingleplayerMapAchievementSchema.mapName schema to be a string
A player got an achievement on the beta deployment for a map that doesn't exist in prod. Now they can't log in on prod because the map doesn't exist. |
||
|
|
0b9d43cb46 |
Configurable nation count 🤖 (#3338)
## Description: I hope we can get this into v30? The nation count is configurable now, just like the bot count. Replaced the "Disable Nations" toggle with a nations slider (0–400) in SinglePlayer and Host Lobby modals. <img width="710" height="121" alt="Screenshot 2026-03-03 021952" src="https://github.com/user-attachments/assets/c8d0f0c3-db51-4303-95fa-dbc770460ec2" /> Public games are staying exactly the same, this is just for singleplayer and private lobby fun. Youtubers could play HvN against 400 nations, for example. Singleplayer enjoyers no longer have to play against 1 nation in HvN, they can freely choose. `GameConfig.disableNations: boolean` got replaced by `nations: number (0-400, optional)` `undefined` = map default, `0` = disabled, number = custom count Nations slider defaults to the map's nation count, shows "(MAP DEFAULT)" label when unchanged Compact map toggle reduces nations to 25% when at default, restores when toggled off (just like we already do with bots) The nation count for HvN no longer automatically matches the human count in singleplayer and private games, only in public games. **What if there aren't enough nations configured for the map?** We just use the HvN logic (Generate random nations) ### Warning **This infra PR also needs to get merged: https://github.com/openfrontio/infra/pull/263 Otherwise players can set 0 nations and get achievements.** ## 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 |
||
|
|
40a7b49b89 |
Bugfix: Update PlayerGameSchema.map from GameMapType enum to string
Same issue as the users/@me response: a user played a map that doesn't exist on productionv0.29.19 |
||
|
|
c77f579969 |
bugfix: change SingleplayerMapAchievementSchema.mapName schema to be a string
A player got an achievement on the beta deployment for a map that doesn't exist in prod. Now they can't log in on prod because the map doesn't exist. |
||
|
|
28bbd933a4 |
Revert "fix: resolve drawImage scaling penalty on non-square sprite height" (#3337)
Reverts openfrontio/OpenFrontIO#3320 doesnt do what it says The #3320 description claimed it “resolves a performance parsing penalty” and fixes “non-square sprite” scaling/ghosting issues. In reality, the code change was limited to: * **clearRect**: switched from clearing a `clearsize x clearsize` square (`clearsize = sprite.width + 1`) around `lastX/lastY` to clearing a **(sprite.width+2) x (sprite.height+2)** rect around **rounded** `clearX/clearY` (with an extra 1px pad via `-1/+2`). * **drawImage**: changed a single call’s destination height from `sprite.width` → `sprite.height`. ### Why revert For unit rendering, sprites are square, so the drawImage change is a no-op in practice, and the main effect was **clearing more pixels per frame**. Any theoretical gain from rounding coordinates is speculative, and is outweighed by the increased clear area/overdraw. |
||
|
|
1d1b076672 |
Rename/fix: change Bots to Tribes (#3290)
## Description: Resolves #3285. As discussed on Discord. However, in at least one instance "Tribes" feels a bit off: in Humans vs Nations, team "Tribes" feels as human too while they are just bots. This PR changes Bots to Tribes outwardly by - Changing default EN translation. - Changing (untranslated) alt text in PlayerPanel. - To change "Team Bot" into "Team Tribes" too in PlayerInfoOverlay and TeamStats (team leaderboard in-game), translate team names in there from now on too. - This way we also fix a bug where team names were not translated yet in there. To add to that fix, also translate team names in LobbyPlayerView in the same way. For this we re-use the existing getTranslatedPlayerTeamLabel function from GameLeftSideBar by moving it to Utils. - No translation key was present yet for Humans and Nations teams, so added those to now be used in PlayerInfoOverlay, LobbyPlayerView and TeamStats for completeness. - No internal code changes so nothing breaks. **BEFORE (showing old team name Bot and also that team names weren't translated yet in TeamStats)**   **AFTER** (translations in Dutch only shown as proof here, did not include nl.json in the PR)      ## 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 |
||
|
|
29e1ca2bda |
new homepage (#3332)
## Description: updated homepage to make ffa the primary focus. closes https://github.com/openfrontio/OpenFrontIO/issues/3288 and closes https://github.com/openfrontio/OpenFrontIO/pull/3328 <img width="1911" height="924" alt="image" src="https://github.com/user-attachments/assets/f81a3471-6a24-44a5-baf9-c2fdc5a3cbc3" /> <img width="416" height="846" alt="image" src="https://github.com/user-attachments/assets/0456423b-4418-4719-9236-d12cb3aa1c37" /> ## 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 |
||
|
|
17c0dde45f |
ui polish (#3333)
## Description: - disabled dragging in many places, select skin, select flag, select lang, and footer stuff - removed shadow from flags in flag selector - added bounce to the lang selector ## 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 --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> |
||
|
|
60f69a6408 |
perf: remove O(n) StructureIconsLayer render lookups (#3305)
Begins work on #3207 ## Description: This PR is the first optimization slice for #3207: it removes O(n) render lookups in `StructureIconsLayer` by replacing array-first render state with a unit-id keyed map, and tightens hot-path execution to reduce per-tick allocations. ### What changed - Refactored render state from array-first to `rendersByUnitId: Map<number, StructureRenderInfo>`. - Replaced O(n) lookup/delete paths with O(1) `Map#get` / `Map#delete`. - Replaced `seenUnits` object-identity tracking with `seenUnitIds: Set<number>`. - Removed `tick()` array/closure chain (`map(...).forEach(...)`) and switched to index-based loop. - Reduced ghost-path allocation pressure by reusing a layer-level `Set` for connected ally IDs instead of allocating `filter` + `map` + `new Set` per ghost query. - Added dirty-flag caching for structure visibility focus (`visibilityStateDirty`) so expensive visibility-state scans recompute only when toggles change. ### Performance validation (before/after) Benchmark added: `tests/perf/StructureIconsLayerLookupPerf.ts` Command: `npm run perf` Observed result: - `StructureIconsLayer BEFORE (array O(n) lookup/delete) x 0.33 ops/sec ±13.28%` - `StructureIconsLayer AFTER (unit-id map O(1) lookup/delete) x 95.65 ops/sec ±2.46%` - Fastest implementation: AFTER (unit-id map) #### Profiler screenshots are too noisy to be useful for such a focused change ### Verification - `npx tsc --noEmit` ✅ - `npx eslint src/client/graphics/layers/StructureIconsLayer.ts tests/perf/StructureIconsLayerLookupPerf.ts` ✅ - `npm run perf` ✅ ## 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~~ - [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: skigim |
||
|
|
c238af389a |
Feat: Passage Map 🚢 (#3304)
## Description: Introduces Passage, an island filled thin map (like Amazon River but inverted) which is a long, thin stretch of islands that makes for some really fun gameplay. I playtested with 3 friends a number of times and it's great in pretty much all the modes. Naval gameplay on this map is particularly fun since some islands in the center basically hold the choke points on trade ships passing from one side to another, making them hotly contested territory. <img width="6000" height="400" alt="long map" src="https://github.com/user-attachments/assets/7904d6f8-e7b8-437d-852e-68a2f006d200" /> Describe the PR. ## 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: bijx |
||
|
|
17f32a590c |
fix: resolve drawImage scaling penalty on non-square sprite height (#3320)
## Description: This PR resolves a performance parsing penalty in the `UnitLayer` rendering loop by fixing two issues with non-square sprites: 1. `drawImage` was incorrectly using `sprite.width` for both width and height, causing aspect ratio squashing and forcing the browser to perform a scaling operation on the image instead of hitting the canvas fast-path. It now correctly uses `sprite.height` for the vertical dimension. 2. `clearUnitsCells` was previously configured to only clear a square grid (`clearsize`) based solely on width, meaning taller sprites would leave visual artifact "ghosts" on the map. The clearing bounds have been corrected to leverage discrete `sprite.width` and `sprite.height`. Additionally, these values are wrapped in `Math.round()` prior to offset calculation to prevent subpixel anti-aliasing CPU penalties during `clearRect`. ## Please complete the following: - [x] I have added screenshots for all UI updates (not needed) - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file (no new text) - [x] I have added relevant tests to the test directory (existing tests suffice, change was minuscule and non-breaking) - [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: skigim |
||
|
|
98e3cd364c |
mls (v4.16) (#3321)
If this PR fixes an issue, link it below. If not, delete these two lines. Resolves #(issue number) ## Description: mls for v30 Version identifier within MLS: 4.16 ## 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: aotumuri |
||
|
|
af251395bb |
More 2 team games on Baikal, more 4 team games on Four Islands 🎉 (#3323)
## Description: I promised something to a redditor: <img width="640" height="304" alt="image" src="https://github.com/user-attachments/assets/fa319f15-f67f-486f-a5ad-598aeef7779a" /> ### Changes - **Map-specific team count overrides** with 75% probability: - **Baikal**: 2 teams (plays into the natural two-sided geography) - **Four Islands**: 4 teams (one team per island) - Remaining 25% falls through to the normal weighted random team selection - **Doubled playlist frequency** for Baikal (5→10) and Four Islands (4→8) in the team game playlist, making them appear twice as often ## 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 |
||
|
|
49b69b6fa1 |
[Bugfix] Force end 170mins (#3326)
## Description: instead of just killing the server, lets save 10m before, then kill the server at 3hr mark, so at least we have a proper savegame. ## 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 |
||
|
|
f7598369ed |
refactor: consolidate platform detection across client components (#3325)
## Description: This PR consolidates ad hoc platform/environment/viewport detection into a single shared utility. It is scoped to this refactor only, and serves as groundwork for the mobile-focused feature work planned for the v31 milestone. ### What changed - Introduced a shared `Platform` utility centralising: - OS detection (with `userAgentData` + UA fallback) - Electron environment detection - Viewport breakpoint helpers (`isMobileWidth`, `isTabletWidth`, `isDesktopWidth`) - Replaced duplicated inline checks across client files with the shared API. - Normalised Mac detection to derive from the consolidated OS logic rather than a separate regex. ### Why - Multiple client files each independently ran `navigator.userAgent` regexes or copy-pasted `isElectron` logic — this unifies all of that. - Puts a stable, tested abstraction in place before v31 mobile work lands, so mobile feature branches have a consistent surface to build against. ## Please complete the following: - [x] I have added screenshots for all UI updates (N/A: refactor only, no visible UI changes) - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file (N/A: no new user-facing strings) - [x] I have added relevant tests to the test directory (N/A: refactor only) - [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: skigim |
||
|
|
15f4f5e20a |
Bump rollup from 4.54.0 to 4.59.0 in the npm_and_yarn group across 1 directory (#3319)
Bumps the npm_and_yarn group with 1 update in the / directory: [rollup](https://github.com/rollup/rollup). Updates `rollup` from 4.54.0 to 4.59.0 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/rollup/rollup/releases">rollup's releases</a>.</em></p> <blockquote> <h2>v4.59.0</h2> <h2>4.59.0</h2> <p><em>2026-02-22</em></p> <h3>Features</h3> <ul> <li>Throw when the generated bundle contains paths that would leave the output directory (<a href="https://redirect.github.com/rollup/rollup/issues/6276">#6276</a>)</li> </ul> <h3>Pull Requests</h3> <ul> <li><a href="https://redirect.github.com/rollup/rollup/pull/6275">#6275</a>: Validate bundle stays within output dir (<a href="https://github.com/lukastaegert"><code>@lukastaegert</code></a>)</li> </ul> <h2>v4.58.0</h2> <h2>4.58.0</h2> <p><em>2026-02-20</em></p> <h3>Features</h3> <ul> <li>Also support <code>__NO_SIDE_EFFECTS__</code> annotation before variable declarations declaring function expressions (<a href="https://redirect.github.com/rollup/rollup/issues/6272">#6272</a>)</li> </ul> <h3>Pull Requests</h3> <ul> <li><a href="https://redirect.github.com/rollup/rollup/pull/6256">#6256</a>: docs: document PreRenderedChunk properties including isDynamicEntry and isImplicitEntry (<a href="https://github.com/njg7194"><code>@njg7194</code></a>, <a href="https://github.com/lukastaegert"><code>@lukastaegert</code></a>)</li> <li><a href="https://redirect.github.com/rollup/rollup/pull/6259">#6259</a>: docs: Correct typo and improve sentence structure in docs for <code>output.experimentalMinChunkSize</code> (<a href="https://github.com/millerick"><code>@millerick</code></a>, <a href="https://github.com/lukastaegert"><code>@lukastaegert</code></a>)</li> <li><a href="https://redirect.github.com/rollup/rollup/pull/6260">#6260</a>: fix(deps): update rust crate swc_compiler_base to v47 (<a href="https://github.com/renovate"><code>@renovate</code></a>[bot], <a href="https://github.com/lukastaegert"><code>@lukastaegert</code></a>)</li> <li><a href="https://redirect.github.com/rollup/rollup/pull/6261">#6261</a>: fix(deps): lock file maintenance minor/patch updates (<a href="https://github.com/renovate"><code>@renovate</code></a>[bot], <a href="https://github.com/lukastaegert"><code>@lukastaegert</code></a>)</li> <li><a href="https://redirect.github.com/rollup/rollup/pull/6262">#6262</a>: Avoid unnecessary cloning of the code string (<a href="https://github.com/lukastaegert"><code>@lukastaegert</code></a>)</li> <li><a href="https://redirect.github.com/rollup/rollup/pull/6263">#6263</a>: fix(deps): update minor/patch updates (<a href="https://github.com/renovate"><code>@renovate</code></a>[bot], <a href="https://github.com/lukastaegert"><code>@lukastaegert</code></a>)</li> <li><a href="https://redirect.github.com/rollup/rollup/pull/6265">#6265</a>: chore(deps): lock file maintenance (<a href="https://github.com/renovate"><code>@renovate</code></a>[bot])</li> <li><a href="https://redirect.github.com/rollup/rollup/pull/6267">#6267</a>: fix(deps): update minor/patch updates (<a href="https://github.com/renovate"><code>@renovate</code></a>[bot])</li> <li><a href="https://redirect.github.com/rollup/rollup/pull/6268">#6268</a>: chore(deps): update dependency eslint-plugin-unicorn to v63 (<a href="https://github.com/renovate"><code>@renovate</code></a>[bot], <a href="https://github.com/lukastaegert"><code>@lukastaegert</code></a>)</li> <li><a href="https://redirect.github.com/rollup/rollup/pull/6269">#6269</a>: chore(deps): update dependency lru-cache to v11 (<a href="https://github.com/renovate"><code>@renovate</code></a>[bot])</li> <li><a href="https://redirect.github.com/rollup/rollup/pull/6270">#6270</a>: chore(deps): lock file maintenance (<a href="https://github.com/renovate"><code>@renovate</code></a>[bot])</li> <li><a href="https://redirect.github.com/rollup/rollup/pull/6272">#6272</a>: forward NO_SIDE_EFFECTS annotations to function expressions in variable declarations (<a href="https://github.com/lukastaegert"><code>@lukastaegert</code></a>)</li> </ul> <h2>v4.57.1</h2> <h2>4.57.1</h2> <p><em>2026-01-30</em></p> <h3>Bug Fixes</h3> <ul> <li>Fix heap corruption issue in Windows (<a href="https://redirect.github.com/rollup/rollup/issues/6251">#6251</a>)</li> <li>Ensure exports of a dynamic import are fully included when called from a try...catch (<a href="https://redirect.github.com/rollup/rollup/issues/6254">#6254</a>)</li> </ul> <h3>Pull Requests</h3> <ul> <li><a href="https://redirect.github.com/rollup/rollup/pull/6251">#6251</a>: fix: Isolate and cache <code>process.report.getReport()</code> calls in a child process for robust environment detection (<a href="https://github.com/alan-agius4"><code>@alan-agius4</code></a>, <a href="https://github.com/lukastaegert"><code>@lukastaegert</code></a>)</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/rollup/rollup/blob/master/CHANGELOG.md">rollup's changelog</a>.</em></p> <blockquote> <h2>4.59.0</h2> <p><em>2026-02-22</em></p> <h3>Features</h3> <ul> <li>Throw when the generated bundle contains paths that would leave the output directory (<a href="https://redirect.github.com/rollup/rollup/issues/6276">#6276</a>)</li> </ul> <h3>Pull Requests</h3> <ul> <li><a href="https://redirect.github.com/rollup/rollup/pull/6275">#6275</a>: Validate bundle stays within output dir (<a href="https://github.com/lukastaegert"><code>@lukastaegert</code></a>)</li> </ul> <h2>4.58.0</h2> <p><em>2026-02-20</em></p> <h3>Features</h3> <ul> <li>Also support <code>__NO_SIDE_EFFECTS__</code> annotation before variable declarations declaring function expressions (<a href="https://redirect.github.com/rollup/rollup/issues/6272">#6272</a>)</li> </ul> <h3>Pull Requests</h3> <ul> <li><a href="https://redirect.github.com/rollup/rollup/pull/6256">#6256</a>: docs: document PreRenderedChunk properties including isDynamicEntry and isImplicitEntry (<a href="https://github.com/njg7194"><code>@njg7194</code></a>, <a href="https://github.com/lukastaegert"><code>@lukastaegert</code></a>)</li> <li><a href="https://redirect.github.com/rollup/rollup/pull/6259">#6259</a>: docs: Correct typo and improve sentence structure in docs for <code>output.experimentalMinChunkSize</code> (<a href="https://github.com/millerick"><code>@millerick</code></a>, <a href="https://github.com/lukastaegert"><code>@lukastaegert</code></a>)</li> <li><a href="https://redirect.github.com/rollup/rollup/pull/6260">#6260</a>: fix(deps): update rust crate swc_compiler_base to v47 (<a href="https://github.com/renovate"><code>@renovate</code></a>[bot], <a href="https://github.com/lukastaegert"><code>@lukastaegert</code></a>)</li> <li><a href="https://redirect.github.com/rollup/rollup/pull/6261">#6261</a>: fix(deps): lock file maintenance minor/patch updates (<a href="https://github.com/renovate"><code>@renovate</code></a>[bot], <a href="https://github.com/lukastaegert"><code>@lukastaegert</code></a>)</li> <li><a href="https://redirect.github.com/rollup/rollup/pull/6262">#6262</a>: Avoid unnecessary cloning of the code string (<a href="https://github.com/lukastaegert"><code>@lukastaegert</code></a>)</li> <li><a href="https://redirect.github.com/rollup/rollup/pull/6263">#6263</a>: fix(deps): update minor/patch updates (<a href="https://github.com/renovate"><code>@renovate</code></a>[bot], <a href="https://github.com/lukastaegert"><code>@lukastaegert</code></a>)</li> <li><a href="https://redirect.github.com/rollup/rollup/pull/6265">#6265</a>: chore(deps): lock file maintenance (<a href="https://github.com/renovate"><code>@renovate</code></a>[bot])</li> <li><a href="https://redirect.github.com/rollup/rollup/pull/6267">#6267</a>: fix(deps): update minor/patch updates (<a href="https://github.com/renovate"><code>@renovate</code></a>[bot])</li> <li><a href="https://redirect.github.com/rollup/rollup/pull/6268">#6268</a>: chore(deps): update dependency eslint-plugin-unicorn to v63 (<a href="https://github.com/renovate"><code>@renovate</code></a>[bot], <a href="https://github.com/lukastaegert"><code>@lukastaegert</code></a>)</li> <li><a href="https://redirect.github.com/rollup/rollup/pull/6269">#6269</a>: chore(deps): update dependency lru-cache to v11 (<a href="https://github.com/renovate"><code>@renovate</code></a>[bot])</li> <li><a href="https://redirect.github.com/rollup/rollup/pull/6270">#6270</a>: chore(deps): lock file maintenance (<a href="https://github.com/renovate"><code>@renovate</code></a>[bot])</li> <li><a href="https://redirect.github.com/rollup/rollup/pull/6272">#6272</a>: forward NO_SIDE_EFFECTS annotations to function expressions in variable declarations (<a href="https://github.com/lukastaegert"><code>@lukastaegert</code></a>)</li> </ul> <h2>4.57.1</h2> <p><em>2026-01-30</em></p> <h3>Bug Fixes</h3> <ul> <li>Fix heap corruption issue in Windows (<a href="https://redirect.github.com/rollup/rollup/issues/6251">#6251</a>)</li> <li>Ensure exports of a dynamic import are fully included when called from a try...catch (<a href="https://redirect.github.com/rollup/rollup/issues/6254">#6254</a>)</li> </ul> <h3>Pull Requests</h3> <ul> <li><a href="https://redirect.github.com/rollup/rollup/pull/6251">#6251</a>: fix: Isolate and cache <code>process.report.getReport()</code> calls in a child process for robust environment detection (<a href="https://github.com/alan-agius4"><code>@alan-agius4</code></a>, <a href="https://github.com/lukastaegert"><code>@lukastaegert</code></a>)</li> <li><a href="https://redirect.github.com/rollup/rollup/pull/6252">#6252</a>: chore(deps): update dependency lru-cache to v11 (<a href="https://github.com/renovate"><code>@renovate</code></a>[bot])</li> <li><a href="https://redirect.github.com/rollup/rollup/pull/6253">#6253</a>: chore(deps): lock file maintenance minor/patch updates (<a href="https://github.com/renovate"><code>@renovate</code></a>[bot], <a href="https://github.com/lukastaegert"><code>@lukastaegert</code></a>)</li> <li><a href="https://redirect.github.com/rollup/rollup/pull/6254">#6254</a>: Fully include dynamic imports in a try-catch (<a href="https://github.com/lukastaegert"><code>@lukastaegert</code></a>)</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/rollup/rollup/commit/ae846957f109690a866cc3e4c073613c338d3476"><code>ae84695</code></a> 4.59.0</li> <li><a href="https://github.com/rollup/rollup/commit/b39616e9175b3d9fc3977c99153174c490805a93"><code>b39616e</code></a> Update audit-resolve</li> <li><a href="https://github.com/rollup/rollup/commit/c60770d7aaf750e512c1b2774989ea4596e660b2"><code>c60770d</code></a> Validate bundle stays within output dir (<a href="https://redirect.github.com/rollup/rollup/issues/6275">#6275</a>)</li> <li><a href="https://github.com/rollup/rollup/commit/33f39c1f205ea2eadaf4b589e493453e2baa3662"><code>33f39c1</code></a> 4.58.0</li> <li><a href="https://github.com/rollup/rollup/commit/b61c40803b717854c1c28937e8098e5ad3c7b8ca"><code>b61c408</code></a> forward NO_SIDE_EFFECTS annotations to function expressions in variable decla...</li> <li><a href="https://github.com/rollup/rollup/commit/7f00689ec90e2cafb11c26eefbcac62343c936f6"><code>7f00689</code></a> Extend agent instructions</li> <li><a href="https://github.com/rollup/rollup/commit/e7b2b85af0901244ecc141b9d792c6db6b527ea4"><code>e7b2b85</code></a> chore(deps): lock file maintenance (<a href="https://redirect.github.com/rollup/rollup/issues/6270">#6270</a>)</li> <li><a href="https://github.com/rollup/rollup/commit/2aa5da9baf82211b8207d268c8751630cb766970"><code>2aa5da9</code></a> fix(deps): update minor/patch updates (<a href="https://redirect.github.com/rollup/rollup/issues/6267">#6267</a>)</li> <li><a href="https://github.com/rollup/rollup/commit/4319837c5448d0c10d89e9ded118888deec2eeec"><code>4319837</code></a> chore(deps): update dependency lru-cache to v11 (<a href="https://redirect.github.com/rollup/rollup/issues/6269">#6269</a>)</li> <li><a href="https://github.com/rollup/rollup/commit/c3b6b4bdc4f2ed978fa233132a526957e6513233"><code>c3b6b4b</code></a> chore(deps): update dependency eslint-plugin-unicorn to v63 (<a href="https://redirect.github.com/rollup/rollup/issues/6268">#6268</a>)</li> <li>Additional commits viewable in <a href="https://github.com/rollup/rollup/compare/v4.54.0...v4.59.0">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore <dependency name> major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore <dependency name> minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore <dependency name>` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore <dependency name>` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore <dependency name> <ignore condition>` will remove the ignore condition of the specified dependency and ignore conditions You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/openfrontio/OpenFrontIO/network/alerts). </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
50197e7254 |
perf(PerformanceOverlay): reduce per-render overhead (#3295)
## Description: Cache translated UI labels per language/translation load Avoid per-frame layer breakdown sorting unless expanded Use rolling sums instead of array reduce Drop redundant requestUpdate() calls and object clones ## 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 |
||
|
|
9ca342e510 |
Add Nile Delta map (#3306)
## Description: Add Nile Delta as a new regional map. Features 11 nations across the delta region (Alexandria, Damietta, Faraskur, Sheremsah, El Senbellawein, Aga, Mit Ghamr, Cairo, Heliopolis, Memphis, El Mansoura). 1.36M land tiles at 1556x1280, terrain generated from real relief data. Includes the Suez Canal. Playlist frequency: 4.  ## Checklist - [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 Source: https://commons.wikimedia.org/wiki/File:Niledelta_33.svg Discord: gabigabogabu |
||
|
|
4aa0f174ad |
Bump minimatch from 3.1.3 to 3.1.5 in the npm_and_yarn group across 1 directory (#3307)
Bumps the npm_and_yarn group with 1 update in the / directory: [minimatch](https://github.com/isaacs/minimatch). Updates `minimatch` from 3.1.3 to 3.1.5 <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/isaacs/minimatch/commit/7bba97888a27a6162983056bcce2a6e28f668712"><code>7bba978</code></a> 3.1.5</li> <li><a href="https://github.com/isaacs/minimatch/commit/bd259425b2ca17b42897997f93e890314155522d"><code>bd25942</code></a> docs: add warning about ReDoS</li> <li><a href="https://github.com/isaacs/minimatch/commit/1a9c27c75725474dbde57db2995b6281b267756d"><code>1a9c27c</code></a> fix partial matching of globstar patterns</li> <li><a href="https://github.com/isaacs/minimatch/commit/1a2e084af579731af66c221214e3ca8222c9bf23"><code>1a2e084</code></a> 3.1.4</li> <li><a href="https://github.com/isaacs/minimatch/commit/ae24656237c3d58067442f790ce17eff84463a47"><code>ae24656</code></a> update lockfile</li> <li><a href="https://github.com/isaacs/minimatch/commit/b1003749228b2a79e1f237963a0d559ef7a0941e"><code>b100374</code></a> limit recursion for **, improve perf considerably</li> <li><a href="https://github.com/isaacs/minimatch/commit/26ffeaa091b9f660833e23f42e07165b33e85c13"><code>26ffeaa</code></a> lockfile update</li> <li><a href="https://github.com/isaacs/minimatch/commit/9eca892a4e5dbb20534f9f30483b85cdeee6c2eb"><code>9eca892</code></a> lock node version to 14</li> <li>See full diff in <a href="https://github.com/isaacs/minimatch/compare/v3.1.3...v3.1.5">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore <dependency name> major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore <dependency name> minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore <dependency name>` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore <dependency name>` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore <dependency name> <ignore condition>` will remove the ignore condition of the specified dependency and ignore conditions You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/openfrontio/OpenFrontIO/network/alerts). </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
417fa0fe09 |
For v30: Add new modifiers (Hard nations and 25M Starting Gold) 🙂 (#3316)
## Description: Adds two new public game modifiers for variety and improves compact map eligibility for team games. ### New Modifiers **Hard Nations (`isHardNations`)** - We need this modifier for HvN, because medium nations are easier now (will result in a much higher human winrate) - In a discord discussion we concluded that HvN should generally be easier (higher winrate than 50%, so players are less frustated) - Thats why only 20% of HvN games have the hard nations modifier (for now) - For PvPvE enjoyers, the modifier is also active in FFA games => (Only 2.5% chance, and 1 ticket in `SPECIAL_MODIFIER_POOL`) **25M Starting Gold (`startingGoldHigh`)** - Some people in the main discord wanted this modifier, and it will result in crazy games - Rare special-only modifier (1 ticket in pool); mutually exclusive with 5M starting gold via `MUTUALLY_EXCLUSIVE_MODIFIERS` - Disables nations (they lack PVP immunity, so 25M gold doesn't work well with them) - Excluded from HumansVsNations games (since it disables nations) - Spawn immunity set to **2 minutes 30 seconds** (vs 30s for 5M gold), so people can spend the gold and prepare ### Other Changes - **Improved `supportsCompactMapForTeams`**: Replaced the hard `smallest >= 50` land-tile cutoff with a per-team-config calculation that simulates worst-case compact player count and checks every team gets at least 2 players. - **HvN spawn immunity**: Always 5 seconds in both regular and special lobbies (to get rid of a confusing PVP immunity HeadsUpMessage in 5M starting gold games) - **Regular public lobby random spawn modifier probabilty**: Reduced from 10% to 5% (Because of the new modifier, so there aren't too many modifiers in non-special-lobbies, should only occur sometimes there) - Rebalanced `SPECIAL_MODIFIER_POOL` a bit ## 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 |
||
|
|
e1125e0c37 |
Fix: Nations reject alliance requests created pre-spawn (#3314)
## Description: This PR fixes an exploit that allows the player to request alliances to Nations, mostly in impossible mode, during spawn phase, with high chances for it to be accepted due to troop count parity. Nations now reject alliance requests during the spawn phase. `GameImpl.executeNextTick()` initializes ALL pending `unInitExecs` in one batch on the first post-spawn tick ( `numSpawnPhaseTurns() + 1` ). So every alliance request submitted during spawn phase is guaranteed to be created with `createdAt = numSpawnPhaseTurns() + 1` on the very first post-spawn tick. Therefore, we check for alliance requests created on the very first post-spawn tick and reject those. ## 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: deshack_82603 --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> |
||
|
|
802cc7f16d |
Revert "Fix: Nations reject alliance requests during spawn phase" (#3313)
## Description: Reverts openfrontio/OpenFrontIO#3312 ## 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 |
||
|
|
a9c89e4f15 |
Fix: Nations reject alliance requests during spawn phase (#3312)
## Description: This PR fixes an exploit that allows the player to request alliances to Nations, mostly in impossible mode, during spawn phase, with high chances for it to be accepted due to troop count parity. Nations now reject alliance requests during the spawn phase. ## 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: deshack_82603 |
||
|
|
8754f5291f |
Feat: Alphanumeric Coordinate Grid on Alternate View (#2938)
## Description: Adds a coordinate grid to the Alternate View (holding spacebar) using numbers on the X-axis, and letters on the Y-axis. No more "he's attacking you in that—well, the little peninsula thing... next to the island! which island? uhh..." moments when playing with friends. Optimally maps have letters A-J (just like in the Battleships board game) but special maps like Amazon River dynamically resize to only have 2 letters so as to not have too many number columns. This feature overall can be toggled via the settings menu. Also saw it requested on the [official discord](https://discord.com/channels/1359946986937258015/1457037351422263480) a couple times, thought it was a neat idea. ### World Map <img width="3809" height="1824" alt="image" src="https://github.com/user-attachments/assets/dab56879-a34e-48ea-a588-2907d26feb45" /> ### Scales correctly when zoomed in <img width="3798" height="1874" alt="image" src="https://github.com/user-attachments/assets/7e06a47f-d3d9-4f92-8e89-3eaf866e9b25" /> ### Amazon River <img width="3803" height="1595" alt="image" src="https://github.com/user-attachments/assets/4797c576-20b2-4aa8-8b7a-107078ab6308" /> ### Enable/Disable via settings https://github.com/user-attachments/assets/ec9f4e07-70a1-4f9d-b137-c3c3d2a2540c ## 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: bijx --------- Co-authored-by: iamlewis <lewismmmm@gmail.com> |
||
|
|
ebe1f76bbf |
improved configuration handling, including special lobby (#3224)
## Description: Special games now get a random map from a dedicated pool (which includes arcade maps that are excluded from regular FFA/team rotations), a 50/50 chance of FFA or Team mode, and are guaranteed to have at least one modifier active, compact map, random spawn, crowded, or 5m starting gold , with higher roll rates than normal games. ## 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 |
||
|
|
aa451e217f |
[BUGFIX] allow users to update username pre-game (#3298)
## Description: Fix player rename in pre-game lobby on rejoin Previously, when a player left a lobby, changed their name, and rejoined, the server reused the original Client object without updating the username. Now rejoinClient accepts the new username and applies it if the game hasn't started yet, while still preserving names mid-game for consistency. ## 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 |
||
|
|
5542ac12e1 |
Add new map: Bosphorus Straits (#2927)
## Description: Adds a new Bosphorus Map (Turkey). One of the key strategic locations in the world and control access to the Black Sea. Smaller map that most to facilitate smaller FFA and Team games. Added are a selection of nations that correspond to the location. <img width="1000" height="612" alt="image" src="https://github.com/user-attachments/assets/27a6debc-a33b-4b54-b522-69ab814c39f0" />   ## 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: TSProphet --------- Co-authored-by: Ryan <7389646+ryanbarlow97@users.noreply.github.com> Co-authored-by: iamlewis <lewismmmm@gmail.com> |
||
|
|
11d3228608 |
Adds Bering Strait map. (#2924)
## Description: PR to add Bering Strait map. Produced using TOPO data from real world location, rivers and lakes correct to real world location. The map is slightly smaller than most so facilitates smaller FFA games or 2 team game modes. The centre island has been increased in size to enable better warfare to capture the strategic location. <img width="1500" height="918" alt="image" src="https://github.com/user-attachments/assets/bc9b2e69-cef1-4f21-92b5-4ffdce5812e1" />  ## 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: TSProphet --------- Co-authored-by: Ryan <7389646+ryanbarlow97@users.noreply.github.com> |
||
|
|
9fc11b7b9a |
perf(worker): remove heartbeat; batch game updates (#3308)
## Description: Removes the client-driven heartbeat loop and switches worker tick execution to a worker-owned drain scheduler with batched game update delivery. ## Why The previous flow required the client to send a `heartbeat` every animation frame just to keep the worker progressing turns. That had two costs: 1. Simulation progress was coupled to browser frame cadence. 2. Catch-up periods produced many single `game_update` messages, increasing message overhead and main-thread wakeups. ## What Changed ### 1) Remove heartbeat protocol - Deleted `heartbeat` from `WorkerMessageType`. - Removed `HeartbeatMessage` from `MainThreadMessage`. - Removed `sendHeartbeat()` from `WorkerClient`. - Removed the `requestAnimationFrame` keep-alive loop in `ClientGameRunner`. Files: - `src/client/ClientGameRunner.ts` - `src/core/worker/WorkerClient.ts` - `src/core/worker/WorkerMessages.ts` - `src/core/worker/Worker.worker.ts` ### 2) Add batched worker-to-client updates - Added `game_update_batch` message type and `GameUpdateBatchMessage`. - Worker now emits one batch message containing multiple tick updates. - `WorkerClient` handles `game_update_batch` by replaying updates to the existing callback in order. Files: - `src/core/worker/WorkerMessages.ts` - `src/core/worker/WorkerClient.ts` ### 3) Move tick draining into worker - Added a scheduler (`scheduleDrain`) and drain loop (`drain`) in `Worker.worker.ts`. - On each `turn` message, worker enqueues turn and schedules drain. - Drain executes up to `MAX_TICKS_BEFORE_YIELD = 4` ticks per cycle, then yields with `setTimeout(..., 0)`. - Tick updates are collected into a batch and sent once with transferables: - `packedTileUpdates.buffer` - `packedMotionPlans.buffer` (when present) - If backlog remains, drain reschedules itself. File: - `src/core/worker/Worker.worker.ts` ## Behavioral Notes - No server protocol changes. - Ggame update callback contract remains the same (still receives one `GameUpdateViewData` at a time in order). - Ordering is preserved: `WorkerClient` iterates batch entries in sequence. - Error updates are still filtered from update delivery in the worker batch path (same effective behavior as before for normal update flow). ## Expected Impact - Fewer `postMessage` calls during backlog and burst turn delivery. - Lower message overhead and fewer main-thread interrupts. - Less dependence on UI frame timing for worker progress. - Better catch-up stability due to explicit periodic yielding. ## Risk Areas - Drain scheduling edge cases (re-entrancy / lost wake-ups). - Mitigated with `drainScheduled`, `draining`, and `drainRequested` flags. - Larger per-message payloads due to batching. - Bounded by `MAX_TICKS_BEFORE_YIELD`. - Any assumptions in downstream code about receiving only `game_update`. - Handled by adding `game_update_batch` support in `WorkerClient`. ## 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 |
||
|
|
c911bfb2d8 |
Packed unit updates / MotionPlans (#3292)
## Description: Reduce per-step `Unit` update traffic by shipping packed motion plans and letting the client advance plan-driven units locally. Changes: - Add packed motion plan records (`packedMotionPlans?: Uint32Array`) to game updates and transfer the buffer worker -> main. - Introduce `src/core/game/MotionPlans.ts` (schema + pack/unpack) for grid + train motion plans. - Extend `Game` with `recordMotionPlan(...)` and `drainPackedMotionPlans()`, and implement buffering/packing in `GameImpl`. - Treat units with motion plans as “plan-driven”: suppress per-tile `Unit` updates on `move()` and advance positions client-side. - Emit motion plans from executions: - `TradeShipExecution`: record/update grid motion plans and `touch()` when changing target after capture. - `TransportShipExecution`: record initial plan and update it when destination changes. - `TrainExecution`: record a train plan on init (engine + cars). - Client: apply motion plans in `GameView` and ensure `UnitLayer` updates sprites for motion-planned units even when no `Unit` updates arrived. ## 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 |
||
|
|
1cafc6bc25 |
perf(translateText): speed up translateText (#3296)
## Description: Cache lang-selector lookup Avoid per-call empty params allocation Add fast-path for non-ICU strings ## 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 |
||
|
|
f09177f8fe | Merge branch 'v29' | ||
|
|
1f05e22277 |
Add Traefik integration to deployment script (#3302)
## Description:
Connects deployed containers to Traefik for automatic reverse proxy
routing, replacing the previous Cloudflare Tunnel approach.
```
docker inspect openfront-staging-traefik --format '{{json .Config.Labels}}' | jq
{
"traefik.enable": "true",
"traefik.http.routers.openfront-staging-traefik.entrypoints": "web",
"traefik.http.routers.openfront-staging-traefik.rule": "Host(`traefik.openfront.dev`)",
"traefik.http.services.openfront-staging-traefik.loadbalancer.server.port": "80"
}
```
## 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
v0.29.18
|