## Description:
Changes a few small UI issues:
- Player info text transparency made it less legible:
<img width="367" height="445" alt="image"
src="https://github.com/user-attachments/assets/a08b2808-74a5-4783-93f3-182d97b36055"
/>
- Fix naval invasion target end fade which didn't work previously

- Rename rendering function since the UI layer doesn't only handle
target
## 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
## Description:
Discussed that with Lewis.
Fuze liked the Didier map without the real france more...
So here it is. It won't get added to the playlist, the france version
stays in the playlist.
(Unrelated: Also quickly changed "Europe (classic)" to Europe (Classic)"
to match with "Britannia (Classic)")
<img width="934" height="839" alt="Screenshot 2026-01-10 005646"
src="https://github.com/user-attachments/assets/64925635-c15a-4167-a5bc-5cf7b3b140f8"
/>
<img width="1064" height="961" alt="Screenshot 2026-01-10 003335"
src="https://github.com/user-attachments/assets/9b6aa936-2c33-4a24-8076-a74a4704adc4"
/>
<img width="635" height="427" alt="Screenshot 2026-01-10 003316"
src="https://github.com/user-attachments/assets/e2b46db8-ef0b-4b45-8ea7-711b9b8f7524"
/>
## 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:
Overhauls the Main Menu UI, visit https://menu.openfront.dev to see
everything.
## 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
Resolves#2837
## Description:
This PR aligns the "Owned" percentage format in TeamStats to the same
data in Leaderboard, fixing the issue that currently happens when team
reaches 100%, and the percentage is displayed as "1.0e+2%".
Previous implementation to avoid this problem involved checking for the
"100" value, but we all know how floating point arithmetic works in
JS...
Before:
<img width="912" height="450" alt="image"
src="https://github.com/user-attachments/assets/a3ce03ab-53c6-4b7b-b3fd-7073a6095252"
/>
After:
<img width="441" height="233" alt="image"
src="https://github.com/user-attachments/assets/21b07834-e3ec-44c3-bd6f-3d5a5d6c851c"
/>
## 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:
Some FX animations were previously used as UI elements (e.g. nuke area,
naval invasion target, gold text).
This PR moves those animations to a dedicated UI layer.
Those UI elements handle correctly the current zoom level and remain
sharply rendered at all zoom levels.
The new UI layer can be disabled using the same setting that disables
the FX layer.
Performance-wise, this layer is equivalent to the FX layer, as it reuses
the same animations.
### Naval target
Don't scale with the zoom level, but has a minimum zoom level so the
targeted tile can still be easily highlighted by zooming

### Nukes
Has to scale because the size is set, but the border radius is not so
the area is more visible from afar.

### Popup text
Scale with zoom level, and stop showing when zoomed-out:

## 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
references #2001
## Description:
Improve the ranked matchmaking modal. Better messages, and show 1v1 elo
<img width="450" height="210" alt="Screenshot 2026-01-08 at 7 11 20 PM"
src="https://github.com/user-attachments/assets/e4f8323c-5d98-48de-babe-b51526a6d408"
/>
<img width="622" height="614" alt="Screenshot 2026-01-08 at 7 11 14 PM"
src="https://github.com/user-attachments/assets/73d10f84-b5b5-4ba8-95bb-a181a9fd9dae"
/>
## Please complete the following:
- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
evan
## Description:
Simple PR, but adds the feature where using the hotkey to build a city
will show SAM radius layer to let user know safe areas to build.
<img width="2126" height="1398" alt="image"
src="https://github.com/user-attachments/assets/8aed5514-51c4-40f4-a446-e3c52346abc8"
/>
## 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
Resolves#2823
## Description:
When playing in single-player mode, if an NPC reaches 80% land control
before the player, the game enters a broken state where:
- The game clock stops
- Win checking stops permanently
- Even if the player later conquers 100% of land, victory is never
awarded
- The game becomes "stuck" in a zombie state.
This PR addresses this allowing Nations to be set as winners in single
mode, and in this case showing a "Nation {nation} has won" modal to the
user. This WinModal is the same as the "{player} has won", with the only
change being the title.
Nation wins in FFA, from the human player perspective:
<img width="1457" height="837" alt="image"
src="https://github.com/user-attachments/assets/1ce569bd-6616-4a23-b4a4-afedad2c64f8"
/>
## 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#2516
## Description:
Introduces a state to the Player Info Overlay which simply shows what
type of terrain the player is hovering on. This just builds on the
principles of continuous feedback when designing UX because players
react positively when the game responds to input action.
<img width="839" height="846" alt="image"
src="https://github.com/user-attachments/assets/4b2969e0-127d-4032-9c49-9cbff9bb2aeb"
/>
<img width="666" height="602" alt="image"
src="https://github.com/user-attachments/assets/5fd15ab1-98b1-472f-a83e-a1ee10338673"
/>
https://github.com/user-attachments/assets/7e39f53e-6d2e-479e-badd-b41484591b8b
## 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
## Description:
Adds a new detailed Britannia map featuring modern UK, Ireland, and
northern France regions. The previous Britannia map has been preserved
as "Britannia Classic".
<img width="4096" height="5031" alt="United Kingdom"
src="https://github.com/user-attachments/assets/8a6ca3ab-bc91-438f-8ca7-7fdf7c5260b8"
/>
<img width="4096" height="5031" alt="United Kingdom_debug"
src="https://github.com/user-attachments/assets/a9a7bcd2-1dc5-40c6-a547-a7a79e636060"
/>
Changes
Added new Britannia map with modern county/region divisions
Renamed existing Britannia map to "Britannia Classic"
Added map-generator source assets for both maps
Updated GameMapType enum with BritanniaClassic
Configured player counts: 50/30/20 for both maps
Added playlist frequencies: Britannia (5), Britannia Classic (4)
Updated language translations
New Britannia Nations (partial list)
Ireland: Mayo, Kerry, Clare, Meath, and more
Scotland: Highland, Argyll and Bute, and more
England: North Yorkshire, and more
France: Pas-de-Calais
Britannia Classic
The original Britannia map with historical kingdoms (Dumnonia, Dyfed,
Gwent, Gwynedd, Powys, Strathclyde, Dalriata, Wessex, Sussex, Kent,
etc.) is now available as "Britannia Classic".
## 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: Harry <Harry.bath94@gmail.com>
Co-authored-by: iamlewis <lewismmmm@gmail.com>
## Description:
Added a public game modifier system. It causes that
5% of public games are played on the compact version of the map
10% of public games have "Random Spawn" activated
Percentages can easily get changed via `DefaultConfig`.
We can also easily add more modifiers.
Modifiers can stack, so in rare cases you will play on a compact map
with random spawn 😄
More variety!
### "Compact Map" modifier implementation
- With the "Compact Map" modifier the lobby max player count gets
reduced to 25% and only 25% of the regular bots and only 25% of the
regular nations will spawn (because the map has only 25% of its regular
size)
- In private lobbies and singleplayer the nation reduction happens too
(When "Compact Map" is enabled).
### Restrictions
- Duos/Trios/Quads team modes do not get Random Spawn (defeats the
purpose)
- Maps with smallest player count < 50 do not get Compact Map in team
games (not enough players after the reduction to 25%). I have calculated
all the possible max player counts.
### How it looks like
Random Spawn modifier:
<img width="528" height="183" alt="Screenshot 2026-01-06 194959"
src="https://github.com/user-attachments/assets/2f729da9-80c3-4548-8205-71129da2a76a"
/>
Very rare case: Two modifiers at the same time and only 10 max players
have been chosen from `[GameMapType.FaroeIslands]: [20, 15, 10]`.
Because of the 75% reduction in player count only 3 players are allowed
(3 is the minimum). I think its funny that you can play a 1v1v1 in rare
occasions 😄
<img width="526" height="184" alt="Screenshot 2026-01-06 194938"
src="https://github.com/user-attachments/assets/834326eb-df03-41b7-b1db-1efa3f1013b5"
/>
### Funny side-effect
Team games with random spawn. That will be interesting. No more "Who is
better in donating troops to the frontline". Instead you have to heavily
coordinate with your teammates.
## 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:
We didn't have a river map and we didn't have a map with a crazy size.
So I made a "Amazon River" map with a crazy size.
280 x 5536!
21 nations based on real locations.
Should be interesting gameplay because you don't have many attack
options, your only escape is the river.
The land tiles size is similar to the achiran and iceland map.
<img width="2442" height="147" alt="Screenshot 2026-01-06 150831"
src="https://github.com/user-attachments/assets/91c4142d-c1e3-4aee-ac49-529b8d9f60c4"
/>
<img width="2324" height="139" alt="Screenshot 2026-01-06 150957"
src="https://github.com/user-attachments/assets/5e049ae5-f32a-495f-afde-9e20257b3676"
/>
Because the map is so wide, it looked really ugly stretched in the
thumbnails. So I added some CSS which removes the thumbnail stretching
of the Amazon River map. We can also use this logic for other thumbnails
which shouldn't get stretched.
In `Maps.ts`, `PublicLobby.ts` and `GameInfoModal.ts`.
## 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
Adds a pulsing highlight effect for teammates during the spawn phase in
team games. This helps colorblind players identify their teammates on
the map more easily.
- Teammates show a subtle green/team-colored pulse (5-14px radius)
- Player's own pulse remains unchanged (8-24px white pulse)
- Only activates during spawn phase in team games
- Animation stays synchronized with player's own pulse
I didn't want to come empty handed with my request so I generated the
code
I do know python and a little rust, but don't have TypeScript experience
- I know you guys are probably getting flooded with AI slop so I hope
its okay.
Please implement the feature at the very least because its SO much
better not having to hunt around.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
So the code calls drawTeammateHighlights() inside of
drawFocusedPlayerHighlight() so it can only occur where current
highlighting occurs
Then uses the existing isOnSameTeam() to find teammates
Then uses the existing drawBreathingRing() function
- [x] I have added screenshots for all UI updates
I took a video since it best captures the feature
- [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
I'm not that good at coding formally, I tested it manually by loading
into team games, but I'm going to need help with the code being tested.
(Please help)
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
I did load into multiple lobbies and made sure the feature works, its a
really simple feature so I am confident there isn't any Lovecraftian bug
lurking in it. It also uses mostly existing functions and features
within the code base.
https://github.com/user-attachments/assets/857cce43-4fb2-4c5d-bc04-1a6617570dee
Co-authored-by: Daniel <daniel@mangoit.ca>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: iamlewis <lewismmmm@gmail.com>
## Description:
migrate tailwindcss v3 to v4
## 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: iamlewis <lewismmmm@gmail.com>
Co-authored-by: Ryan <7389646+ryanbarlow97@users.noreply.github.com>
## Description:
Fixes this:
<img width="1485" height="960" alt="image"
src="https://github.com/user-attachments/assets/fa27b2da-fe2c-4423-9f25-3051b93de77b"
/>
## 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 language button to the bottom left so it takes up less space.
<img width="615" height="567" alt="Screenshot 2026-01-05 at 5 54 23 PM"
src="https://github.com/user-attachments/assets/f29d5bcb-8627-493a-8c0f-1966cb9c9be6"
/>
## 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
Contributes towards the ongoing task of adding achievements: #2706
## Description:
Introduces a concept design and API implementation for singleplayer win
achievements. New row of ~5~ 4 medals is added to the map select screen
in the Singleplayer modal, one for each difficulty:
<img width="3132" height="779" alt="image"
src="https://github.com/user-attachments/assets/da8f0314-ccad-4f45-a03f-1beb46981301"
/>
In order to achieve a medal in a particular map, you must win the
singleplayer game (multiplayer and private match games don't count) in
the selected difficulty **without tampering with the options or
settings**. If any setting is changed from the default, regardless of
the difficulty, you will ~receive a fifth "Custom" medal~ not receive
the medal for that difficulty. Team games **do not** count towards the
medal achievement.
Completion of a medal will fill in the full correct color, as defined in
our `variables.css`:
<img width="694" height="778" alt="image"
src="https://github.com/user-attachments/assets/1b2d8370-aa86-4329-9402-adf43f3ef799"
/>
Completion medals can be toggled on or off (hidden by default) with the
toggle button at the top of the section:
https://github.com/user-attachments/assets/d08a58e0-b534-430e-9e8f-559134ad8852
[API implementation PR](https://github.com/openfrontio/infra/pull/234)
## 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>
Co-authored-by: Evan <evanpelle@gmail.com>
## Description:
Didier map for the big french youtuber Fuze which already published
several OpenFront videos.
I took the real france, cut away the bordering countries and made it
look like Didier 😄
Gave it eyes, hands and feet.
Made sure we have some rivers, also put Corsica in the right bottom
corner!
It's quite large. Similar to the europe map. Has 42 nations (38 french
cities and 4 funny custom nations for the youtuber).
Made with [TsProphets map
generator](https://github.com/TsProphet94/OpenFrontMapGenerator), QGIS
and GIMP.
For public games I put a rare map frequenzy of 2 because most people
probably don't know Fuze.
@ibnhalwa from discord gave some insider knowledge about Fuze (He's
french, I'm not).
<img width="2100" height="2250" alt="image"
src="https://github.com/user-attachments/assets/5d1c3c45-4b2e-4f60-a02f-89b26f938652"
/>
<img width="1278" height="1218" alt="Screenshot 2026-01-05 184540"
src="https://github.com/user-attachments/assets/6e300bb0-6e9f-4b0f-bad8-94f031d250b1"
/>

## 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:
Describe the PR.
Modified FluentSlider(my code) to split number input handle to visual
update(NumberInput) and dispatch value(NumberComplete)
updated the event flow to match them, will fix rapid-fire updates that
seemed to glitch bots out.
## 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:
jackochess
## Description:
Resolve discussions about stalled PR
https://github.com/openfrontio/OpenFrontIO/pull/2460
<img width="724" height="348" alt="image"
src="https://github.com/user-attachments/assets/c2c9fa79-cace-431a-9ca4-b3656612fa9d"
/>
Changes:
- Added a `Player::canAttackPlayer(other)` function to determine whether
a player can be attacked.
- This function is now used in most places where a fight can occur:
- AttackExecution (land attacks)
- Naval invasion
- Warship fight
- Nukes can't be thrown during the truce
- Immunity only affect human players. Nations and bot will fight as
usual, and can be fought against.
- The immunity timer uses minutes in the modal window.
UI:
- The immunity phase is displayed with a timer bar at the top. This is
from the original PR, to be discussed if it's not deemed visible enough:
<img width="632" height="215" alt="image"
src="https://github.com/user-attachments/assets/f5ab9aa0-bd4f-4503-b8d6-b40b121fba65"
/>
## 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
---------
Co-authored-by: newyearnewphil <git@nynp.dev>
## Description:
Trains are made of a primary unit (`TrainExecution.train`) followed by 6
cars (`TrainExecution.cars`). Currently when any of the units is
destroyed, a message "Your Train was destroyed" is shown. In worst case
scenario, when all cars are blasted by a nuke, 7 messages are displayed
to the user, but the train continues.
Since the actual logic is unaffected as long as the primary unit stays
alive, displaying messages is confusing. This PR fixes it. The message
is only displayed when the primary unit is destroyed. The following cars
are only there for fancy visuals.
## Screencast
##### Current - multiple messages for single train
https://github.com/user-attachments/assets/3df04c71-d899-4f68-af83-36c9d0ffa730
First nuke was a test.
Second nuke destroyed the entire train, prompting 7 messages.
Third nuke destroyed one full train and then some. Prompting many too
many messages.
##### Fixed - one message, only if train was fully destroyed
https://github.com/user-attachments/assets/1f3840a7-6c62-487d-af3a-82de39dad9e8
First train was only partially destroyed, no message was shown, delivery
mission completed A+.
Following 2 trains had the front engine destroyed and therefore were
promptly decommissioned.
## Please complete the following:
- [x] 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:
moleole
Resolves#2739
## Description:
Introduce language metadata handling and refactor existing language
checks to validate the existence of language JSON and corresponding SVG
files. Add tests to ensure the integrity of the new metadata structure
and its references.
The lang field is intentionally kept in each language file.
This is because the files are frequently regenerated by Crowdin, and the
field also serves as a hint for management and maintenance.
## 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
---------
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
## Description:
This feature adds a troop count bar into the PlayerInfoOverlay that
visualizes how many troops a player/nation has, how big of an attack
they are sending, and in general the percentages of their overall troop
count. I originally added the toggling of this feature as a setting but
thought it might be too narrow to need it's own setting. Would
appreciate anyone's thoughts on adding it back in or not.
Inspired by [this
comment](https://discord.com/channels/1359946986937258015/1359949371956789289/1452559404401430674)
in the Dev Discord.
### Video Demo
https://github.com/user-attachments/assets/4a4397f7-c0a1-475a-867d-ef00b57661c4
## 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
## Description:
A new map where you basically have to hop from island to island :)
We don't have such a map at the moment.
There is a special center island which isn't necessary to get 80% of the
map.
This map could be very interesting in team games. One hydro will destroy
an entire island.
Size: 1976 x 1976
Nations: 8
<img width="949" height="951" alt="Screenshot 2026-01-02 214219"
src="https://github.com/user-attachments/assets/7139bcc9-6a05-414d-90c1-33cc36dd94fb"
/>
## 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:
Updates the instructions Help Menu to update the ally radial menu
screenshot to show the new gold and troop donation icons, as well as
what they do. Related to #2708
<img width="1656" height="974" alt="image"
src="https://github.com/user-attachments/assets/365e0fe5-6854-4cac-8288-039a05cf4905"
/>
## 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
## Description:
Add {team_count} to public lobby team size translations so word order
stays correct across languages.
## 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
---------
Co-authored-by: iamlewis <lewismmmm@gmail.com>
## Description:
- Renamed "Difficulty" -> "Nation difficulty" to make clear that the
"difficulty" only changes the nations
- If nations are disabled, the difficulty gets blurred now. And a
"not-allowed" cursor is shown on hover.
<img width="819" height="572" alt="Screenshot 2026-01-01 225108"
src="https://github.com/user-attachments/assets/365d0c9c-5983-44bd-887c-4ed2b8c08fd6"
/>
- Also did a small CSS fix to allow word breaks
Before:
<img width="134" height="76" alt="Screenshot 2026-01-01 231332"
src="https://github.com/user-attachments/assets/caf56bab-77e8-4453-800d-aece0840f6ad"
/>
After:
<img width="130" height="97" alt="Screenshot 2026-01-01 231306"
src="https://github.com/user-attachments/assets/bd9e0c1d-4ed7-4416-a292-ef1c7d240752"
/>
## 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
closes#2678
## Description:
Update to enable bomb flip support by mobile users too
<img width="420" height="666" alt="image"
src="https://github.com/user-attachments/assets/eb2155a4-2012-4f40-8caa-bd23ebd28521"
/>
----------------------------------------------------------------------------------------------------------------------------------------------------
Also, I slightly updated the player panel to make it more even and take
up less space;
- removed the huge header bar which took up too much space
- fixed ui divider spacing
Before:
<img width="372" height="179" alt="image"
src="https://github.com/user-attachments/assets/2cf82cda-d466-4911-be4f-36eb6e788d5b"
/>
After:
<img width="383" height="134" alt="image"
src="https://github.com/user-attachments/assets/4d827221-f456-48fe-940b-a9ba84d1f4a5"
/>
## 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
Fixes#2758
## Description:
This PR migrates lobby configuration updates from the HTTP PUT
`/game/:id` endpoint to a WebSocket-based intent flow.
The lobby creator is already authenticated via the game WebSocket, so
updating configuration through intents removes redundant authentication
and aligns with existing real-time lobby actions such as `kick_player`
and `toggle_pause`.
## Changes Made
- Added `update_game_config` WebSocket intent schema
- Wired client → transport → server intent handling
- Refactored `putGameConfig()` to emit WebSocket intent instead of HTTP
fetch
- Preserved all existing validation, partial-update semantics, and
client-side debouncing
- Left the REST endpoint untouched for backward compatibility
## Testing
- All existing automated tests pass
- Manual verification completed:
- Lobby creator can update all lobby settings
- Non-creators are rejected
- Updates are rejected after game start
- Bots slider debounce (300ms) remains intact
- No `PUT /api/game/:id` requests are made from the lobby UI
## 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
Resolves#2508
## Description:
Adds hover tooltips to the "Win Score" and "Loss Score" column headers
in the clan stats table to help players understand what these weighted
scores represent.
### Changes Made
- Added tooltip to **Win Score** column: "Weighted wins based on clan
participation and match difficulty"
- Added tooltip to **Loss Score** column: "Weighted losses based on clan
participation and match difficulty"
- Uses native HTML `title` attribute (follows existing codebase
patterns)
- Fully i18n-ready via `translateText()` - other languages will be
translated via Crowdin
### Implementation Details
- **Files Modified**: 2 files, 4 lines total
- `resources/lang/en.json`: Added 2 tooltip translation keys
- `src/client/StatsModal.ts`: Added `title` attributes to table headers
- No breaking changes
### Expected Behavior
When hovering over "Win Score" or "Loss Score" column headers, users see
a tooltip explaining the weighted scoring system based on clan
participation and match difficulty.
## 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

## Description:
Changes game lobbies into websockets instead of polling
## 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: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: iamlewis <lewismmmm@gmail.com>
## Description:
Introduces the Strait of Hormuz section in the Persian Gulf as a map!
This map is actually crazy fun to play on because of how the water
narrows to a small strait where control is necessary otherwise enemies
can transport boat to you easily. I figured a strategic map based on
modern-ish day conflicts would fit the theme, but man it's a great map
to play on.
### Full Map
<img width="2739" height="1822" alt="image"
src="https://github.com/user-attachments/assets/f35bdefa-723a-4bb2-9dc9-fb42898528ce"
/>
### In game with nations
<img width="2218" height="1502" alt="image"
src="https://github.com/user-attachments/assets/00e350cf-8654-4638-8654-178accdf6a48"
/>
## 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
## Description:
I believe this bug came after the introduction of the new donation
button in the radial menu (#2708) causing the rectangular SVGs to get
squished/skewed into square aspect ratios. This fix adds a little check
to fallback onto original image dimensions when an SVG's aspect ratio
isn't available. I tried a hardcoded fix earlier but if we ever decide
to add different scaled icons into the radial menu again, this will
automatically ensure the correct aspect ratio is used and the icon is
centered properly.
### Before Fix
<img width="1133" height="473" alt="image"
src="https://github.com/user-attachments/assets/5f06b19c-7072-4650-a1b7-4cb2bf1200dc"
/>
### After Fix
<img width="840" height="421" alt="image"
src="https://github.com/user-attachments/assets/176f1e7b-84bf-4b06-9ad6-4031e516d4ff"
/>
## 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
Resolves#2719
- [X] Ran `npm run format`
- [X] Ran `npm run lint:fix`
- [X] Ran `npm test`
- [X] Manually tested fixes
## Description:
### What problem(s) was I solving?
On Mac, `Ctrl+Click` is commonly used as a substitute for right-click to
open context menus. However, in OpenFront, `Ctrl+Click` was triggering
both the context menu, AND causing an attack.
This effectively prevented Mac users from being able to ally with
bots/nations, as trying to ally would cause you to attack them.
### What changes did I make?
- `Ctrl+Click` on Mac no longer triggers an attack, allowing players to
properly interact with the alliance system
### How I implemented it
1. Added an `isMac()` method to `InputHandler` which encapsulates the
"is mac" logic, and lets it be mocked during tests
2. In the `onPointerUp` handler, added a check: if on Mac and
`ControlLeft` is held, emit a `ContextMenuEvent`, and then return
(instead of continuing to also create a `MouseUpEvent`)
3. Extracted magic numbers for mouse button checks into descriptive
helper methods (`isMiddleMouseButton`, `isNonLeftMouseButton`) for
improved code clarity
4. Added clarifying comments throughout the pointer event handlers
Last, alphabetized the `.gitignore` file and organized it into "Folders"
and "Files" sections to make it easier to read.
### How to verify it
#### Manual Testing
- [X] On a Mac, hold `Ctrl` and left-click on another nation - verify
the context menu opens (not an attack)
- [X] On a Mac, right-click should still open the context menu as
expected
- [X] On Windows/Linux, `Ctrl+Click` continue to work as before
(modifier key for build menu if configured)
- [X] Regular left-click still triggers attacks/interactions as expected
#### Automated Testing
- [x] New unit test added: `Mac Ctrl+Click Context Menu` - verifies that
`Ctrl+Click` on Mac emits `ContextMenuEvent` instead of `MouseUpEvent`
### Description for the changelog
Fixed `Ctrl+Click` on Mac to properly open the context menu instead of
triggering an attack, restoring the ability for Mac users to form
alliances with other nations.
## 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:
Terekhov
## Description:
Happy new year!
- Atom and hydro:

- Mirv:

## 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
## Description:
Santa will be back.
Reverted all FX to the regular theme.
## 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
## Description:
validate lobby IDs and sanitize logs
## 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:
This PR adds the Two Lakes map, based on the irl area around lake Ohrid
and lake Prespa
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:
DISCORD_USERNAME
Nikola123
## Description:
When placing a nuke (Atom Bomb or Hydrogen Bomb), the range circle now
turns red to warn players when the attack would break an alliance.
<img width="456" height="333" alt="Screenshot 2025-12-28 211927"
src="https://github.com/user-attachments/assets/dfe6f874-3f8b-4662-8877-0af30aa20139"
/>
## 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:
abodcraft1
---------
Co-authored-by: iamlewis <lewismmmm@gmail.com>
## Description:
The sync-assets wasn't executing on docker-build. so instead just import
it from resources/ directory, vite logs a warning but I think that's
okay for now.
## 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