## Description:
The maintainer team name has changed, but it was still being referenced
under the old name, so I fixed that.
I’m not entirely sure how CODEOWNERS works, but I created the branch in
the upstream repository thinking it might be required for the checks. It
may not actually be necessary.
## 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
- [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
If this PR fixes an issue, link it below. If not, delete these two
lines.
Resolves #(issue number)
## Description:
Remove truncation so long language names wrap instead of ellipsizing
before
<img width="194" height="147" alt="スクリーンショット 2026-01-21 20 47 27"
src="https://github.com/user-attachments/assets/551edf13-9896-41ab-984f-aa6dab1ec2b0"
/>
after
<img width="406" height="305" alt="スクリーンショット 2026-01-21 20 47 50"
src="https://github.com/user-attachments/assets/bbd0657a-44ca-4623-8cfc-efb76ceda0c5"
/>
## 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
Resolves#2967
## Description:
The "Replay" action on recent games doesn't work anymore after the
release of v29.
The problem arises because `AccountModal.viewGame()` correctly calls
`history.pushState()` with the game URL and then dispatches the
`join-changed` event.
The `join-changed` event listener in `Main.ts` calls `onHashUpdate()`,
which first calls `JoinPrivateLobbyModal.close()` and then handles the
new URL.
The problem is that `JoinPrivateLobbyModal.onClose()` resets the modal
UI, but also replaces the history state with `/`, therefore
`handleUrl()` receives the homepage URL instead of the game URL.
This PR fixes the above by creating a dedicated callback for the
`join-changed` event (which is dispatched only by `AccountModal` ATM),
skipping the `JoinPrivateLobbyModal.close()` call.
## 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
If this PR fixes an issue, link it below. If not, delete these two
lines.
Resolves #(issue number)
#2919
In GameManager.tick(), when a game becomes active but hasn't started, a
setTimeout for game.start() is scheduled with a 2-second delay. If the
game finishes or is cancelled within those 2 seconds, game.end() is
called, which clears the existing interval. However:
1.The 2-second timeout still fires. game.start() executes.
2. A NEW setInterval is created for turn execution.
3.Since the game is already ending/finished, it's removed from
GameManager.games, but the interval continues to run forever in the
background
## 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:
codimo
Bumps the npm_and_yarn group with 1 update in the / directory:
[diff](https://github.com/kpdecker/jsdiff).
Updates `diff` from 4.0.2 to 4.0.4
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/kpdecker/jsdiff/commit/f06f3e4cacad5955caf891a8a02c5bb1c954bcb5"><code>f06f3e4</code></a>
v4.0.4</li>
<li><a
href="https://github.com/kpdecker/jsdiff/commit/0179a484ffaec7c8d5d6b69d8c3905473383de75"><code>0179a48</code></a>
v4.0.3</li>
<li><a
href="https://github.com/kpdecker/jsdiff/commit/4568cae5ae7646962bf3c5641907d1fb5af90683"><code>4568cae</code></a>
Backport <a
href="https://redirect.github.com/kpdecker/jsdiff/pull/649">kpdecker/jsdiff#649</a></li>
<li><a
href="https://github.com/kpdecker/jsdiff/commit/4de0ffa13ad51db7a27567c2b870fb4e43f0814a"><code>4de0ffa</code></a>
Backport <a
href="https://redirect.github.com/kpdecker/jsdiff/pull/647">kpdecker/jsdiff#647</a></li>
<li>See full diff in <a
href="https://github.com/kpdecker/jsdiff/compare/v4.0.2...v4.0.4">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~explodingcabbage">explodingcabbage</a>, a
new releaser for diff since your current version.</p>
</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 merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@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>
## Description:
For v29
HvN winrate is between 10 and 15%, but should be around 50%.
1. Change HvN difficulty to Medium
2. Little balance change in `NationAllianceBehavior`
## 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:
I analyzed the avg fill time of team games (past 30 days) and was able
to confirm what people in the main discord said: Duos / Trios / Quads
fill slower.
Might be something for v29.
| Game Mode | Games | Avg Fill Time |
|-----------|-------|---------------|
| **FFA** (Excluding ranked) | 53,654 | **29s** |
| Team: 2 teams | 3,379 | 33s |
| Team: 3 teams | 3,291 | 32s |
| Team: 4 teams | 3,242 | 31s |
| Team: 5 teams | 3,364 | 32s |
| Team: 6 teams | 3,381 | 31s |
| Team: 7 teams | 3,227 | 31s |
| Team: Duos | 3,295 | **43s** |
| Team: Trios | 3,300 | 39s |
| Team: Quads | 3,299 | 37s |
| Team: Humans Vs Nations | 101 | **24s** |
Therefore I propose to decrease the chance of Duos, Trios and Quads
(especially Duos).
Also, increase the chance of HumansVsNations because its special and
unlike all the other team modes.
| Team Config | Previous | New |
|-------------|----------|-----|
| 2 teams | 10% | 10% |
| 3 teams | 10% | 10% |
| 4 teams | 10% | 10% |
| 5 teams | 10% | 10% |
| 6 teams | 10% | 10% |
| 7 teams | 10% | 10% |
| **Duos** | 10% | **5%** ↓ |
| **Trios** | 10% | **7.5%** ↓ |
| **Quads** | 10% | **7.5%** ↓ |
| **HumansVsNations** | 10% | **20%** ↑ |
## 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:
move the width definition for PerformanceOverlay's layer bars into the
class
## 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:
wraith4081
Co-authored-by: Ryan <7389646+ryanbarlow97@users.noreply.github.com>
## Description:
Fixes a trailing space in the attack ratio troop count.
**Before**
<img width="257" height="96" alt="Screenshot from 2026-01-19 20-36-57"
src="https://github.com/user-attachments/assets/0941c160-97dd-43a5-a111-cc3238ebbdb0"
/>
**After**
<img width="257" height="96" alt="Screenshot from 2026-01-19 20-29-45"
src="https://github.com/user-attachments/assets/cac06654-e13c-4831-a0f7-61ba1951338a"
/>
## 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:
n/a
## Description:
### Short path for multi-source HPA*
Math was not mathing, increased the bounds to 260x260, it is a bit
slower but should work better. The short path was breaking when player
owned a lot of shores. This is because the bounding box of tiles with
less than 120 distance + 10 padding could be as big as 260x260 and the
optimized array was set to 140x140. I made mistake of calculating it as
`2 * (60 + 10)` instead of `2 * (120 + 10)`.
### LoS path refinement
Previously, we ran 2 passes of LoS smoothing on the path. However, since
we are effectively tracing the same path, the line of sight is
essentially the same. This PR makes second line of sight stop on water
tiles with magnitude `n + 1` compared to first path. Practically, this
means it'll attempt LoS exactly 1 tile after previous corner. See
screenshot.
<img width="1299" height="1151" alt="image"
src="https://github.com/user-attachments/assets/726be236-1ff8-406c-896a-02902a762ab0"
/>
### SendBoatAttackIntentEvent
The flow of sending transport ships is currently strange. This PR makes
the flow more sane.
**Old flow**
```
- Player clicks TARGET tile, it can be deep inland
- Client asks Worker for the best START tile to TARGET tile
- Worker answers `false`, since the tile is inland
- Client sends BoatAttackIntent with START=false and TARGET tiles set
- Worker accepts BoatAttackIntent, computes DESTINATION as closest shore to TARGET
- Worker re-computes best START to DESTINATION
- Worker sends boat from START to DESTINATION
```
**New flow**
```
- Player clicks TARGET tile, it can be deep inland
- Client sends BoatAttackIntent with TARGET
- Worker accepts BoatAttackIntent, computes DESTINATION as closest shore to TARGET
- Worker computes START as the best tile to DESTINATION
- Worker sends boat from START to DESTINATION
```
## 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:
moleole
## Description:
Quickfix: Disable nations in ranked and change map selection
(Lewis wanted these, Australia three times so it occurs more often)
Just a quickfix, we will probably have to improve the map selection
later on, and maybe play on non-compact maps too?
## 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:
"You can pick your spawn in random spawn games in v29. You need to open
the menu and click on the attack button. That's it."
Thats the fix for this problem.
Radial menu no longer allows to attack (pick a spawn) while random spawn
is enabled.
And SpawnExecution got a check so you cannot send malicious intents.
## 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:
As reported on Discord, warship could get stuck. This PR fixes the
issue.
## 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:
moleole
## Description:
Fixes this little i18n problem:
<img width="732" height="172" alt="Screenshot 2026-01-16 050833"
src="https://github.com/user-attachments/assets/65fe27a6-f77a-49d9-94a9-145b4e719a88"
/>
## 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
Co-authored-by: Ryan <7389646+ryanbarlow97@users.noreply.github.com>
## Description:
Nuke trajectory prediction now will show interception with allied SAMs
if the alliance will break on nuke launch.
Code was also refactored to be shared a bit more.
In addition, if an incoming alliance would break if accepted, the nuke
launch will break the alliance.
<img width="1199" height="1002" alt="nukepr"
src="https://github.com/user-attachments/assets/c31066d9-66cf-4eaa-be3c-e2fbcfe7965a"
/>
## 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:
bibizu
## Description:
When a player is conquered (has less than 100 tiles left) their gold is
transfered to the conqueror. And after that the conqueror gets the last
tiles. But if some of those last tiles are not bordered by the
conqueror, they are given to their neighbour player. However that
neighbour player can be an ally. It is percieved as a bug if an ally
conquers/annexes tiles.
This PR fixes that by adding an isFriendly check to `handleDeadDefender`
in `AttackExecution`.
Now, there are already scenarios possible currently, where a player
survives being conquered. If they have some tiles on a small island for
example. Going from that, there should be no unexpected bugs following
this change. A player can be conquered twice in a game already in the
stats too.
https://discord.com/channels/1359946986937258015/1359946989046989063/1462595261204533248
Example of this happening in an Enzo vid (with his surprised reaction)
and explanation posted here:
https://discord.com/channels/1359946986937258015/1359946989046989063/1460483209308536925
## 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:
**Describe the PR.**
This PR improves how pathfinding finds a starting water tile when
launching a transport ship from a shore.
Previously, the code simply picked the first water neighbor it found.
This caused issues where, if a boat were traveling east, it might launch
out of a northern tile from a shore.
<img width="896" height="353" alt="image"
src="https://github.com/user-attachments/assets/69d83012-3397-43b3-8ab0-9ebde6ffea97"
/>
<img width="342" height="219" alt="image"
src="https://github.com/user-attachments/assets/a191f5cf-97da-4e34-a191-55ce14c794f0"
/>
The new logic checks all water neighbors and picks the "best" one by
counting how many water tiles surround it. This ensures transport ships
launch into the main body of water instead of suboptimal positions.
If two tiles have water neighbors with the same score, they are
tie-broken through a euclidean distance check.
## 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:
Scisyph
---------
Co-authored-by: WilliamT-byte <williamt2023@tamu.edu>
Co-authored-by: Ryan <7389646+ryanbarlow97@users.noreply.github.com>
## Description:
This PR resolves a crash related to rail pathfinding reported on
Discord.
```
git checkout c179249cdd
npm run dev:staging
Replay id: kEbHPSP3
```
## 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:
moleole
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Ryan <7389646+ryanbarlow97@users.noreply.github.com>
## Description:
This PR resolves a crash related to rail pathfinding reported on
Discord.
```
git checkout c179249cdd
npm run dev:staging
Replay id: kEbHPSP3
```
## 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:
moleole
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Ryan <7389646+ryanbarlow97@users.noreply.github.com>
## Description:
**Describe the PR.**
This PR improves how pathfinding finds a starting water tile when
launching a transport ship from a shore.
Previously, the code simply picked the first water neighbor it found.
This caused issues where, if a boat were traveling east, it might launch
out of a northern tile from a shore.
<img width="896" height="353" alt="image"
src="https://github.com/user-attachments/assets/69d83012-3397-43b3-8ab0-9ebde6ffea97"
/>
<img width="342" height="219" alt="image"
src="https://github.com/user-attachments/assets/a191f5cf-97da-4e34-a191-55ce14c794f0"
/>
The new logic checks all water neighbors and picks the "best" one by
counting how many water tiles surround it. This ensures transport ships
launch into the main body of water instead of suboptimal positions.
If two tiles have water neighbors with the same score, they are
tie-broken through a euclidean distance check.
## 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:
Scisyph
---------
Co-authored-by: WilliamT-byte <williamt2023@tamu.edu>
Co-authored-by: Ryan <7389646+ryanbarlow97@users.noreply.github.com>
## Description:
If a WebSocket was "connecting", but the user un-clicks the lobby in
that time, it doesn't remove them from the lobby, and they would still
be put into the game.
@evanpelle needed for v29 imo.
It also fixes an issue where it wouldn't update your URL back to the
home url when unclicking the lobby (websocket issue or not).
This is a hotfix to fix 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:
w.o.n
## Description:
Use `this.getEffectiveNationCount()` everywhere inside of
`LobbyPlayerView`, instead of `this.nationCount`. So the team player
counts always update properly.
## 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:
1. In JoinPrivateLobbyModal the nation count loading was missing. That
caused the team preview UI to show different player counts compared to
the HostLobbyModal. For example it showed 0/0 nations for the
HumansVsNations team mode (instead of 2/2):
<img width="726" height="217" alt="Screenshot 2026-01-16 211337"
src="https://github.com/user-attachments/assets/8b4219de-e2b2-46ff-a600-c86915e5bdb3"
/>
2. Turn down HvN difficulty from Impossible to Hard.
We steamrolled over Hard nations in the playtest (at least in two of the
three games) because we donated lots of troops to each other.
But after some API data research I noticed that only 33% of players in
public team games ever use the donate functionality.
And we probably have less skilled players in public games than in the
playtest.
So its probably better to use the Hard difficulty to ensure balanced
gameplay.
I know, I'm overthinking this 😂
## 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:
Extracted the CopyButton into its own component, and now reusing it in
"Account" too.
## 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:
Refactor / Clean-up code inside Host/Solo modals.
## 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:
fix: performance overlay positioning
## 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:
wraith4081
## Description:
fix: performance overlay positioning
## 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:
wraith4081
## Description:
Use `this.getEffectiveNationCount()` everywhere inside of
`LobbyPlayerView`, instead of `this.nationCount`. So the team player
counts always update properly.
## 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:
1. In JoinPrivateLobbyModal the nation count loading was missing. That
caused the team preview UI to show different player counts compared to
the HostLobbyModal. For example it showed 0/0 nations for the
HumansVsNations team mode (instead of 2/2):
<img width="726" height="217" alt="Screenshot 2026-01-16 211337"
src="https://github.com/user-attachments/assets/8b4219de-e2b2-46ff-a600-c86915e5bdb3"
/>
2. Turn down HvN difficulty from Impossible to Hard.
We steamrolled over Hard nations in the playtest (at least in two of the
three games) because we donated lots of troops to each other.
But after some API data research I noticed that only 33% of players in
public team games ever use the donate functionality.
And we probably have less skilled players in public games than in the
playtest.
So its probably better to use the Hard difficulty to ensure balanced
gameplay.
I know, I'm overthinking this 😂
## 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:
While looking at the game rotation on my localhost page I noticed that
the cool new starting gold modifier came up veeeery rarely.
Every 33th game is just too rare, lets do "Every 20th game" 🙂
## 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
Please merge it into v29, since in that version the back navigation out
of a game is currently **broken** after switching from hash-based to
path-based routing via #2740
## Description:
Protect against players accidentally leaving an active game by pressing
the browser back button. Uses the same confirmation dialog as the game
exit button.
Partially handles issue #1877 (protects against back button, not closing
tab or editing the URL directly).
<img width="861" height="373" alt="image"
src="https://github.com/user-attachments/assets/167cc137-6df3-44a7-a594-91ffd904857d"
/>
Partial credit to PR #2141
## 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
## Description:
Extracted the CopyButton into its own component, and now reusing it in
"Account" too.
## 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
# Pathfinding pt. 4
https://pf-pt-4.openfront.dev/
## Description:
Hello again! Pathfinding. It's fast, but inaccurate. This PR makes it
more accurate and actually faster. Sadly it is _faster_ because of a
blunder in previous PR (using BucketQueue where MinHeap would be
better), not because of a new tech. More importantly, it is more
accurate. And that's what people apparently want.
## What changed?
Most of the functional changes relate to `SpatialQuery` module. This is
the thingy that answers "we know the target, which tile of my territory
is the best to launch an invasion". To make it compute a path from South
America to the deep inland China river, it has to work on a coerced map,
one with a very small resolution, so small in fact, that every 4096 map
tiles gets compressed to just one pixel. I hope you see where this is
going.
Previously we selected a random coastal tile within this big pixel
(honestly it wasn't random at all, but could very well be for the
illustrative purposes). Now, we try to be a bit more deliberate. Since
we already know the rough location of the probably best tile, we can
exclude all other tiles from the computation. Imagine a player's
territory spans both Americas on global map - that's a lot of shores.
But since we already know the best tile is somewhere close to Miami, the
problem space was greatly reduced, no need to consider all other shores.
But pathing to the target in China from Miami is still crazy expensive.
This is where second trick comes to play - instead of pathing all the
way to China, we select a _waypoint_ in the rough direction of China,
about 100 to 200 tiles away. This way we fairly cheaply select best tile
to launch an invasion towards this abstract point. And chances are, this
point is far enough, the newly computed path is very close to being
optimal. When you throw a dart from far away, the difference between
scoring 10 and missing is very small. This is why aiming in the general
direction of the board - as opposed to the ceiling - is usually good
enough.
## Okay, but what about the crazy paths when I send invasion to the
opposed bank of a river?!
Well, pathing from America to China is cool, but most players wouldn't
notice the difference on such long paths, what about the short ones? We
now try more accurate pathing first and defer to hierarchy only if it
fails. This produces much better paths for short invasions. While the
fix described above ensures the accuracy is improved also on
medium-to-long routes.
## Playground
Yes.
https://github.com/user-attachments/assets/9cf9586f-c99a-416d-b856-8cf0a21c35ed
## CodeRabbit
Grab a 🥕. Remember `tests/pathfinding/playground` is mostly generated
code and go easy on it. It's enough for it to work and do it's job of
visualizing the paths. No need for throughout review of these files.
## 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:
moleole
# Pathfinding pt. 4
https://pf-pt-4.openfront.dev/
## Description:
Hello again! Pathfinding. It's fast, but inaccurate. This PR makes it
more accurate and actually faster. Sadly it is _faster_ because of a
blunder in previous PR (using BucketQueue where MinHeap would be
better), not because of a new tech. More importantly, it is more
accurate. And that's what people apparently want.
## What changed?
Most of the functional changes relate to `SpatialQuery` module. This is
the thingy that answers "we know the target, which tile of my territory
is the best to launch an invasion". To make it compute a path from South
America to the deep inland China river, it has to work on a coerced map,
one with a very small resolution, so small in fact, that every 4096 map
tiles gets compressed to just one pixel. I hope you see where this is
going.
Previously we selected a random coastal tile within this big pixel
(honestly it wasn't random at all, but could very well be for the
illustrative purposes). Now, we try to be a bit more deliberate. Since
we already know the rough location of the probably best tile, we can
exclude all other tiles from the computation. Imagine a player's
territory spans both Americas on global map - that's a lot of shores.
But since we already know the best tile is somewhere close to Miami, the
problem space was greatly reduced, no need to consider all other shores.
But pathing to the target in China from Miami is still crazy expensive.
This is where second trick comes to play - instead of pathing all the
way to China, we select a _waypoint_ in the rough direction of China,
about 100 to 200 tiles away. This way we fairly cheaply select best tile
to launch an invasion towards this abstract point. And chances are, this
point is far enough, the newly computed path is very close to being
optimal. When you throw a dart from far away, the difference between
scoring 10 and missing is very small. This is why aiming in the general
direction of the board - as opposed to the ceiling - is usually good
enough.
## Okay, but what about the crazy paths when I send invasion to the
opposed bank of a river?!
Well, pathing from America to China is cool, but most players wouldn't
notice the difference on such long paths, what about the short ones? We
now try more accurate pathing first and defer to hierarchy only if it
fails. This produces much better paths for short invasions. While the
fix described above ensures the accuracy is improved also on
medium-to-long routes.
## Playground
Yes.
https://github.com/user-attachments/assets/9cf9586f-c99a-416d-b856-8cf0a21c35ed
## CodeRabbit
Grab a 🥕. Remember `tests/pathfinding/playground` is mostly generated
code and go easy on it. It's enough for it to work and do it's job of
visualizing the paths. No need for throughout review of these files.
## 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:
moleole
## Description:
We might want to add this to v29 to have a third possible public game
modifier from the beginning on 😄 Would be fun
- Add starting gold option (0 to 1_000_000_000 allowed, also applies to
nations)
- Add gold multiplier option (0.1 to 1000 allowed, also applies to
nations and bots)
- Add third public game modifier (3% chance of starting with 5M gold)
- Why 5M? It's enough gold to massively change the game start but not
enough to insta-hydro someone (launcher + hydro is 6M)
<img width="357" height="140" alt="image"
src="https://github.com/user-attachments/assets/72acc15c-e788-4e04-8590-ac72dd9657c7"
/>
## 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
If this PR fixes an issue, link it below. If not, delete these two
lines.
Resolves#2704
## Description:
Merges together easy + medium difficulties.
Before:
<img width="1500" height="580" alt="image"
src="https://github.com/user-attachments/assets/26199d52-8ef2-4feb-ae87-bbfff35e3115"
/>
After:
(dont have one to show oop)
(btw that win ratio in the first screenshot is not mine.. 💀)
## 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:
We might want to add this to v29 to have a third possible public game
modifier from the beginning on 😄 Would be fun
- Add starting gold option (0 to 1_000_000_000 allowed, also applies to
nations)
- Add gold multiplier option (0.1 to 1000 allowed, also applies to
nations and bots)
- Add third public game modifier (3% chance of starting with 5M gold)
- Why 5M? It's enough gold to massively change the game start but not
enough to insta-hydro someone (launcher + hydro is 6M)
<img width="357" height="140" alt="image"
src="https://github.com/user-attachments/assets/72acc15c-e788-4e04-8590-ac72dd9657c7"
/>
## 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 game rank modal was still using the old style, which clashes
strongly with the new one.
This PR changes changes the modal style to be consistent with the new
one:
### Old
<img width="894" height="451" alt="image"
src="https://github.com/user-attachments/assets/c83177cf-a1ed-4ee5-9e12-7d2a9d8004cf"
/>
### New

Tagged as `v29` to have a consistent style in the same version.
## 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:
IngloriousTom
Resolves#2484
## Description:
- When an alliance is created between two players, any incoming nukes
between them are destroyed mid-air.
This prevents the traitor debuff from being applied on impact, even if
the nukes were launched before the alliance was formed.
- If a player has launched nukes at multiple nations, only the nukes
targeting the newly allied nation are destroyed.
This is what the players will see after the alliance is created (in case
they have launched nukes at each other):
<img width="423" height="125" alt="Screenshot 2026-01-04 092907"
src="https://github.com/user-attachments/assets/6544fb7a-7623-4fc3-b799-89ef8fe897d6"
/>
## 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:
assessin.
Resolves#2718
## Description:
Adds go-style error log levels, with an additional ALL log level.
- WARN/ERROR - Only success output
- INFO - Existing output
- DEBUG - New output
- ALL - New output (includes the logs from when removal/performance is
enabled)
In addition
- Add `-verbose` (`-v`), `-log-level`, `-log-removal`, and
`-log-performance` flags to map generator
- No changes to default behavior of `go run .` without the new flags
- excludes test maps from performance warnings (test maps already skip
the removal steps)
- updates readme with the different flags and how they impact the logger
Default run (matches existing)
`go run . >> output.txt 2>&1`
[output.txt](https://github.com/user-attachments/files/24365745/output.txt)
Default run w/ `-verbose` (log level DEBUG)
`go run . -v >> output.txt 2>&1`
[output.txt](https://github.com/user-attachments/files/24365812/output.txt)
Default run w/ `-log-performance`
`go run . -log-performance >> output.txt 2>&1`
[output.txt](https://github.com/user-attachments/files/24365971/output.txt)
Run of just africa w/ all new logging enabled
`go run . -maps=africa -log-level=all >> output.txt 2>&1`
[output.txt](https://github.com/user-attachments/files/24365724/output.txt)
## 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:
tidwell
---------
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Reverts openfrontio/OpenFrontIO#2911
## Description:
Reverts confusing "billion"
## 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
If this PR fixes an issue, link it below. If not, delete these two
lines.
Resolves#2704
## Description:
Merges together easy + medium difficulties.
Before:
<img width="1500" height="580" alt="image"
src="https://github.com/user-attachments/assets/26199d52-8ef2-4feb-ae87-bbfff35e3115"
/>
After:
(dont have one to show oop)
(btw that win ratio in the first screenshot is not mine.. 💀)
## 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:
The game info panel was missing the gold generated with trains, which
was recently added into the recorded stats.
This PR adds the gold train ranking, grouped with the naval trade.
Visually the game info panel is not matching the new visual identity,
but this PR only focuses on the missing data.
<img width="898" height="482" alt="image"
src="https://github.com/user-attachments/assets/6366e5d2-23b6-40b0-b4d4-1227b5a2f811"
/>
## 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:
IngloriousTom