Commit Graph

3133 Commits

Author SHA1 Message Date
FloPinguin 6407dc418a Adblockers blocked OUR OWN source files 🔧 (#3085)
## Description:

Renamed ad files because adblockers blocked them because of their name. 
When ES modules fail to import, the entire application breaks.

## 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
2026-02-01 16:57:33 +00:00
evanpelle 986d509a1c Merge branch 'v29' 2026-01-31 14:43:00 -08:00
FloPinguin 2e609fd858 Move betrayal button, remove betrayal confirmation 🔧 (#3076)
## Description:

- Move betrayal button to the boat-sending-button-location (you can't
send boats to allies) to prevent missclicks
- Remove betrayal confirmation

<img width="260" height="248" alt="image"
src="https://github.com/user-attachments/assets/0a25fc9c-c8a0-4ba9-a8c8-971d6a7a0511"
/>

## 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
2026-01-31 13:53:24 -08:00
FloPinguin 0286224299 Move betrayal button, remove betrayal confirmation 🔧 (#3076)
## Description:

- Move betrayal button to the boat-sending-button-location (you can't
send boats to allies) to prevent missclicks
- Remove betrayal confirmation

<img width="260" height="248" alt="image"
src="https://github.com/user-attachments/assets/0a25fc9c-c8a0-4ba9-a8c8-971d6a7a0511"
/>

## 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
2026-01-31 13:52:58 -08:00
Evan 5452ede38a Ad video ad during spawn (#3078)
## Description:

Ads a small video on the bottom left of the screen during spawn phase.

## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced

## Please put your Discord username so you can be contacted if a bug or
regression is found:

evan
2026-01-31 12:45:20 -08:00
Evan 3388fd728c Create Video ad lit component (#3074)
## Description:

Creates an embedded Playwire video ad with status callbacks

## 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
2026-01-31 12:25:34 -08:00
evanpelle 19d0376532 better error & logging when client sends invalid intent, don't close the connection eithehr 2026-01-31 09:17:53 -08:00
DenelDuck b6b74befa0 add colored borders to player's quickchat option buttons (#2821)
Resolves #2820

## Description:

Add colored borders to the `chat-option-button` corresponding to each
players territory color.

<img width="630" height="565" alt="Image"
src="https://github.com/user-attachments/assets/91a99230-0581-4d83-a470-9a02ba43c045"
/>

## 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:

denelduck

---------

Co-authored-by: VariableVince <24507472+VariableVince@users.noreply.github.com>
2026-01-30 19:58:34 -08:00
Evan 6c2e0d1528 Fix matchmaking double join bug (#3065)
## Description:

There were several issues with the matchmaking modal:

1. It was defined twice (once before login, and once after login), so
players would sometimes join the matchmaking queue twice.
2. When clicking away from the modal (not clicking the back button), the
"onClose" callback was not triggered. So if a person closed & reopened
the modal, they would join twice'
3. Cache the userMe response so it can be called multiple times

## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced

## Please put your Discord username so you can be contacted if a bug or
regression is found:

evan
v0.29.11
2026-01-30 15:27:34 -08:00
Evan 02dc5fc153 Add glowing red dot on store when skins change (#3066)
## Description:

Hash the pattern + is for sale and store it in local storage. then check
if the new cosmetics hash is different from the one we last saw. If it's
different, add a glowing red dot on the store. After user clicks it,
then update the hash and remove the dot.
<img width="1030" height="143" alt="Screenshot 2026-01-29 at 3 54 46 PM"
src="https://github.com/user-attachments/assets/e5727764-40e4-45e1-b651-65816e657067"
/>

## 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
2026-01-30 14:24:55 -08:00
FloPinguin 683ba4c6c1 Make easy difficulty easier 📊 (#3072)
## Description:


https://www.reddit.com/r/Openfront/comments/1qquvdg/difficulty_scaling_in_single_player/
People seem to feel that easy is not easy enough, even after the various
nerfs in multiple places.
So let's touch DefaultConfig.

## 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
2026-01-30 13:45:19 -08:00
FloPinguin 19cdc3fe5f Make easy difficulty easier 📊 (#3072)
## Description:


https://www.reddit.com/r/Openfront/comments/1qquvdg/difficulty_scaling_in_single_player/
People seem to feel that easy is not easy enough, even after the various
nerfs in multiple places.
So let's touch DefaultConfig.

## 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
2026-01-30 13:45:00 -08:00
Sardi 13117251af Add new map “The Box” (#3054)
<img width="1670" height="200" alt="banner"
src="https://github.com/user-attachments/assets/b6561231-71dc-46dd-a521-453d4e97931f"
/>

## Description:

This proposal adds a new, completely flat map called "The Box," where
players will find themselves on a completely flat landmass and will only
be able to trade by land using trains and factories.

- Map size: 2048×2048 pixels
- Binaries generated with MapGenerator (map.bin, map4x.bin, map16x.bin)
- Integrated into arcade category and multiplayer playlist
- English and Spanish translations added
- 13 nations/bots with unique and thematic names:
 
> - **Middle Defender (located in the center)**
> - **King of the Corner (located in the top-left corner)**
> - Suspicious Ally
> - Punch Merchant
> - Nuke Thrower
> - Fullsender
> - Factory Builder
> - Front Manager
> - Box Fighter
> - Cage Liberator
> - Train Trader
> - Non-peaceful Bot
> - **Evan The Dev** (special mention)

All other bots are distributed to cover the map evenly.

<img width="838" height="835" alt="Screenshot 2026-01-28 at 17 39 45"
src="https://github.com/user-attachments/assets/4665088d-cb94-4db3-8602-8a22b63bfee2"
/>

## 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:

sardidefcon
2026-01-29 19:49:10 -08:00
evanpelle bec5b5f976 Merge branch 'v29' 2026-01-28 19:47:23 -08:00
Evan 1eed561be5 Add enzo video tutorial in the help modal (#3059)
## Description:

Add video at top of help section, also show a glowing dot for new
players.

<img width="301" height="133" alt="Screenshot 2026-01-28 at 7 25 23 PM"
src="https://github.com/user-attachments/assets/c6b01853-f066-470f-a22d-8995fd81fe0f"
/>

## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced

## Please put your Discord username so you can be contacted if a bug or
regression is found:

evan
v0.29.10
2026-01-28 19:43:25 -08:00
Ryan 80c8ddda0f Shop new tag (#3057)
adds a "tag" of NEW to the shop which pulses
<img width="159" height="83" alt="image"
src="https://github.com/user-attachments/assets/603adbaa-0699-443b-b7de-2fe383cdf759"
/>

- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced

regression is found:

w.o.n
v0.29.9
2026-01-28 16:09:11 -08:00
evanpelle c54c73d157 Merge branch 'v29' 2026-01-28 16:06:32 -08:00
Ryan 6d3d273889 Shop new tag (#3057)
## Description:

adds a "tag" of NEW to the shop which pulses
<img width="159" height="83" alt="image"
src="https://github.com/user-attachments/assets/603adbaa-0699-443b-b7de-2fe383cdf759"
/>


## 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
2026-01-28 15:56:53 -08:00
evanpelle 936b689769 bugfix: duplicate matchmaking modals causing elo to display unknown v0.29.8 2026-01-28 13:06:43 -08:00
FloPinguin f20028a2a1 Show troop count of troop transport boats (#3056)
## Description:

Troop count display for naval invasion message:

<img width="398" height="131" alt="Screenshot 2026-01-28 204213"
src="https://github.com/user-attachments/assets/d7ccf2a8-9974-4f12-9901-e603426a8e56"
/>

On hover, PlayerInfoOverlay shows the troop count now:

<img width="504" height="99" alt="Screenshot 2026-01-28 202916"
src="https://github.com/user-attachments/assets/46f7685f-8c0e-4156-8d02-8a68dbcffde0"
/>


## 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
2026-01-28 12:39:30 -08:00
evanpelle dec926c54c bugfix: usernames are reset after each game v0.29.7 2026-01-28 12:13:59 -08:00
FloPinguin a0ec1dd646 For v29.6: More team games 🧑‍🤝‍🧑 (#3051)
## Description:

Use ffa:teams ratio of 3:2

## 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
v0.29.6
2026-01-28 11:30:26 -08:00
FloPinguin 054fa91dee Changelog cache busting 🔧 (#3047)
## Description:

Added cache busting for `changelog.md`

## 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
2026-01-28 11:30:19 -08:00
FloPinguin 965dd0f482 Confirm alliance break ⚠️ (#3033)
## Description:

People accidentally clicked the betray button because it's at the same
position as the ally button.
So let's add a small confirmation step.


https://github.com/user-attachments/assets/754f2d33-7419-42fc-a732-197c3107236e

## 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
2026-01-28 11:30:09 -08:00
Evan cb3128f390 Better CrazyGames integration (#3055)
## Description:

Better integration with CrazyGames:

* Don't show login because accounts have not been integrated with
CrazyGames yet
* Integrate CG invite links & usernames
* Refactor match making logic to Matchmaking.ts
* Allow periods to support crazy game usernames
* Create a no-crazygames class that disabled elements when on crazygames

## 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
2026-01-28 11:29:27 -08:00
Aotumuri 0cc58a8f5a fix: add validation for unknown flags in manifest.json (#3044)
Resolves #3041

## Description:

- Add a test to ensure an error is thrown when manifest.json specifies a
non-existent flag.
- Fix the underlying issue by removing the invalid flag specification
(see error below).

```
resources/maps/straitofgibraltar/manifest.json -> nations[0].flag "Rif" does not exist in resources/flags
resources/maps/straitofgibraltar/manifest.json -> nations[5].flag "Shilha" does not exist in resources/flags
resources/maps/straitofgibraltar/manifest.json -> nations[6].flag "Andalusia" does not exist in resources/flags
resources/maps/italia/manifest.json -> nations[0].flag "custom:Kingdom of the Two Sicilies" does not exist in resources/flags
resources/maps/italia/manifest.json -> nations[3].flag "custom:Tuscany" does not exist in resources/flags
resources/maps/italia/manifest.json -> nations[5].flag "custom:Modena" does not exist in resources/flags
resources/maps/italia/manifest.json -> nations[6].flag "custom:Parma" does not exist in resources/flags
resources/maps/italia/manifest.json -> nations[8].flag "custom:Kingdom of Sardinia" does not exist in resources/flags
resources/maps/italia/manifest.json -> nations[11].flag "custom:Ottoman Empire2" does not exist in resources/flags
resources/maps/britannia/manifest.json -> nations[19].flag "gb-nir" does not exist in resources/flags
resources/maps/montreal/manifest.json -> nations[0].flag "quebec" does not exist in resources/flags
resources/maps/montreal/manifest.json -> nations[1].flag "quebec" does not exist in resources/flags
resources/maps/montreal/manifest.json -> nations[2].flag "quebec" does not exist in resources/flags
resources/maps/montreal/manifest.json -> nations[4].flag "quebec" does not exist in resources/flags
resources/maps/montreal/manifest.json -> nations[5].flag "quebec" does not exist in resources/flags
resources/maps/montreal/manifest.json -> nations[6].flag "quebec" does not exist in resources/flags
resources/maps/montreal/manifest.json -> nations[7].flag "quebec" does not exist in resources/flags
resources/maps/montreal/manifest.json -> nations[8].flag "quebec" does not exist in resources/flags
resources/maps/montreal/manifest.json -> nations[9].flag "quebec" does not exist in resources/flags
resources/maps/montreal/manifest.json -> nations[10].flag "quebec" does not exist in resources/flags
resources/maps/montreal/manifest.json -> nations[11].flag "quebec" does not exist in resources/flags
```

## 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
2026-01-27 15:54:01 -08:00
Aotumuri 1314115d3f Add map picker with Featured/All tabs (#3005)
Resolves #2996

## Description:

Replace map selection UI in src/client/SinglePlayerModal.ts and
src/client/HostLobbyModal.ts with the picker (Featured/All tabs + random
map card).

Also, since the html was getting quite long, I extracted the shared
parts into a separate component.

<img width="575" height="592" alt="スクリーンショット 2026-01-23 21 57 03"
src="https://github.com/user-attachments/assets/fc6bfbc3-cb66-452a-b971-436940b0fb99"
/>

<img width="633" height="648" alt="スクリーンショット 2026-01-23 21 57 12"
src="https://github.com/user-attachments/assets/1aa409a1-b801-4a60-8b26-ba20e343d66e"
/>

I separated Map.ts because the display logic looked reusable in other
places, but I’m also open to merging it back if that makes more sense.
If the review prefers it integrated, I can combine them again.

## 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
2026-01-27 15:52:48 -08:00
Vivacious Box db745dcf4a Add a troubleshooting panel (#2951)
## Description:

Add a troobleshooting panel with the most common problems, and a button
to copy the infos for better sharing

<img width="893" height="583" alt="image"
src="https://github.com/user-attachments/assets/7a37f88c-45b2-448c-86fc-6a3736bc9b25"
/>
<img width="654" height="697" alt="image"
src="https://github.com/user-attachments/assets/11dc1898-579b-42c0-953f-f8237eca2922"
/>

## 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:

Mr. Box
2026-01-27 15:51:11 -08:00
Aotumuri 6cca96b545 Anonymized/hidden names on lobby preview (#2965)
Resolves #2962

## Description:

Anonymize lobby preview player names when “Hidden names” is enabled,
using the same deterministic mapping as in-game.

<img width="864" height="618" alt="スクリーンショット 2026-01-20 21 13 19"
src="https://github.com/user-attachments/assets/30ebe155-c66e-49a5-8957-f8ec0a1ccd76"
/>

<img width="668" height="341" alt="スクリーンショット 2026-01-20 21 13 27"
src="https://github.com/user-attachments/assets/6ef74d98-ea2f-4156-a321-306acf012672"
/>


## 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: Ryan <7389646+ryanbarlow97@users.noreply.github.com>
2026-01-27 15:49:06 -08:00
Ryan da4b8aa5e1 Spectate catchup (#3012)
## Description:


https://github.com/user-attachments/assets/dc118d5f-3b7f-4ccb-8579-5b0d8c73fe8e

Catchup mechanic for live games and changes replays to have a backlog
for more "max" speed

## 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
2026-01-27 15:15:35 -08:00
FloPinguin 1dac7bd2e8 Confirm alliance break ⚠️ (#3033)
## Description:

People accidentally clicked the betray button because it's at the same
position as the ally button.
So let's add a small confirmation step.


https://github.com/user-attachments/assets/754f2d33-7419-42fc-a732-197c3107236e

## 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
2026-01-27 15:00:18 -08:00
FloPinguin 4176944639 Changelog cache busting 🔧 (#3047)
## Description:

Added cache busting for `changelog.md`

## 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
2026-01-27 14:11:03 -08:00
FloPinguin 476fa37379 For v29.6: More team games 🧑‍🤝‍🧑 (#3051)
## Description:

Use ffa:teams ratio of 3:2

## 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
2026-01-27 14:10:14 -08:00
FloPinguin 7942990037 Crowded modifier 😄 (#3023)
## Description:

To increase variety a bit more I present: The "crowded" public game
modifier :)
It basically simulates a crazy youtuber lobby. Cramp a lot of players on
a small map 😄
I think its fun, exciting and you actually need skill to manage the
chaos.
5% of public games get this modifier, but because we remove the modifier
for big maps its more like 2.5% (should be something special)

| <img width="321" height="269" alt="Screenshot 2026-01-25 200427"
src="https://github.com/user-attachments/assets/7d2e90c1-e6bc-40a8-a19e-a0849612f472"
/> | <img width="317" height="264" alt="Screenshot 2026-01-25 200554"
src="https://github.com/user-attachments/assets/8b4bd5da-bed1-4743-a107-9ce07fce3040"
/> | <img width="317" height="244" alt="Screenshot 2026-01-25 200521"
src="https://github.com/user-attachments/assets/16293de3-0fc4-431f-8151-31b4e11040fe"
/> |
|---|---|---|






## 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
2026-01-27 00:29:52 +00:00
Aotumuri 71c5102981 mls (v4.15) (#3019)
## Description:

mls for v29
Version identifier within MLS: 4.14

This is the last mls for v29.

## 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>
2026-01-26 21:56:10 +00:00
Simon Schaarschmidt 2984bec4d1 Fix: Extended spawn immunity in 1v1s (#3010) (#3028)
If this PR fixes an issue, link it below. If not, delete these two
lines.
Resolves #3010 

## Description:

Extended the spawn immunity in 1v1s from 5 to 30 seconds, to prevent
spawn killing.

## 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:

@xtonai

Co-authored-by: Ryan <7389646+ryanbarlow97@users.noreply.github.com>
v0.29.5
2026-01-26 13:51:02 -08:00
Evan 9aed372425 Added afterEach cleanup to call inputHandler.destroy(), which clears the setInterval before jsdom tears down and removes window. (#3030)
## Description:

Fixes the failing test:coverage ci.

## 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
2026-01-26 13:50:58 -08:00
Evan 3d9f0aec6c Migrate from publift to playwire ads (#3039)
## Description:

Use playwire ad integration

## 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
2026-01-26 13:34:04 -08:00
Simon Schaarschmidt bc479af5c9 Fix: Extended spawn immunity in 1v1s (#3010) (#3028)
If this PR fixes an issue, link it below. If not, delete these two
lines.
Resolves #3010 

## Description:

Extended the spawn immunity in 1v1s from 5 to 30 seconds, to prevent
spawn killing.

## 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:

@xtonai

Co-authored-by: Ryan <7389646+ryanbarlow97@users.noreply.github.com>
2026-01-26 17:30:08 +00:00
Mattia Migliorini a72c87baa0 Change join-changed event listener to fix Game Replay functionality (#2968)
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
2026-01-25 20:40:44 -08:00
FloPinguin 3f95a45eaf Nations donate troops now 💀 (In team games) (#2984)
## Description:

For v29, balances the HvN winrate.

In team games, nations now donate troops to their weakest team members
(if they have no attack options available).
How often they donate depends on the difficulty.

This PR also has some other little fixes:
- For HvN games, always return true in `shouldAttack()` (make nations a
bit more aggressive).
- Early exit in `attackWithRandomBoat()` for performance
- Early exit in `findNearestIslandEnemy()` for performance AND to make
sure nations which are encircled by friends don't run into this method
(=> no donation happening!)

## 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
2026-01-25 20:40:13 -08:00
Evan ed9900e313 Added afterEach cleanup to call inputHandler.destroy(), which clears the setInterval before jsdom tears down and removes window. (#3030)
## Description:

Fixes the failing test:coverage ci.

## 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
2026-01-25 20:34:48 -08:00
scamiv 0bfad91c04 perf(ui): switch UI layers to wall-time tick intervals (#3025)
## Description:

Preparatory change for the upcoming “unbounded worker” work: 
decouple expensive UI layer updates from game tick frequency by moving
UI ticking to wall-clock intervals. This reduces redundant UI work when
the simulation runs faster than real time (notably replays /
singleplayer at speed > 1) while keeping the UI responsive and
predictable.

## Changes:

- Add optional `Layer.getTickIntervalMs()` and enforce it in
`GameRenderer.tick()` using wall-clock time.
- Convert key UI layers from tick-modulus gating to fixed intervals:
  - `ControlPanel`: 100ms
  - `GameRightSidebar`: 250ms
  - `MainRadialMenu`: 500ms
  - `Leaderboard`, `NameLayer`, `ReplayPanel`, `TeamStats`: 1000ms


## 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
2026-01-25 20:14:55 -08:00
Mitchell Zinck de3794313d feat: Kick player in game (#2969)
If this PR fixes an issue, link it below. If not, delete these two
lines.
Resolves #2686 

## Description:
- Implemented feature for lobby creator to kick players in game.
- Added new moderation option for lobby creator, with a kick player
option if they aren't the creator, a bot, and exist in game.
- Includes a confirm kick option, and keeps track of kicked players so
that the kick option changes to "Already Kicked" if the kicked player
panel is opened again on the kicked player.

Screenshot order:
1) Open player panel
2) Click on moderation
3) Click on kick player and confirm kick
4) Player is kicked, open same player panel again and observe change in
kick status
5) Receiving player kick message

<img width="1470" height="776" alt="Screenshot 2026-01-20 at 12 33
55 PM"
src="https://github.com/user-attachments/assets/7c47b5a2-a0f8-4e92-833c-7b9732f751a8"
/>
<img width="1470" height="776" alt="Screenshot 2026-01-20 at 11 58
58 AM"
src="https://github.com/user-attachments/assets/3aa026af-9a42-4512-91b8-916f146849a6"
/>
<img width="1470" height="776" alt="Screenshot 2026-01-20 at 12 31
46 PM"
src="https://github.com/user-attachments/assets/5e1d271b-bf32-4335-8eb1-bcdf84aba8ce"
/>
<img width="1470" height="776" alt="Screenshot 2026-01-20 at 11 57
58 AM"
src="https://github.com/user-attachments/assets/7cbd5ea6-bcb6-4a35-a003-ea0add936925"
/>
<img width="1470" height="776" alt="Screenshot 2026-01-20 at 11 57
39 AM"
src="https://github.com/user-attachments/assets/4309b3e3-2fe6-48dd-8e0c-55036e567461"
/>



## 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:

mitchfz
2026-01-24 20:55:58 -08:00
evanpelle 87dab71e42 delay 1v1 game start from 5s=>7s to give more time for players to join the game v0.29.4 2026-01-24 15:50:54 -08:00
Mattia Migliorini dfd6a1f5f9 Replace donate buttons with attack ones for AFK friendly players in radial menu (#2987)
Resolves #2986

## Description:

Shows donate actions in radial menu only when friendly player is NOT
disconnected.
This is needed in order to let mobile/touch users attack AFK teammates.

Current behavior:
<img width="525" height="514" alt="image"
src="https://github.com/user-attachments/assets/78b95e27-443a-4dd5-934b-c8a841b4bf97"
/>

With this PR:
<img width="545" height="457" alt="image"
src="https://github.com/user-attachments/assets/e9792478-6ccd-415f-9199-cff7bfc9356f"
/>


## 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
2026-01-23 14:18:50 -08:00
dependabot[bot] d4e09644b0 Bump lodash from 4.17.21 to 4.17.23 in the npm_and_yarn group across 1 directory (#3006)
Bumps the npm_and_yarn group with 1 update in the / directory:
[lodash](https://github.com/lodash/lodash).

Updates `lodash` from 4.17.21 to 4.17.23
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/lodash/lodash/commit/dec55b7a3b382da075e2eac90089b4cd00a26cbb"><code>dec55b7</code></a>
Bump main to v4.17.23 (<a
href="https://redirect.github.com/lodash/lodash/issues/6088">#6088</a>)</li>
<li><a
href="https://github.com/lodash/lodash/commit/19c9251b3631d7cf220b43bc757eb33f1084f117"><code>19c9251</code></a>
fix: setCacheHas JSDoc return type should be boolean (<a
href="https://redirect.github.com/lodash/lodash/issues/6071">#6071</a>)</li>
<li><a
href="https://github.com/lodash/lodash/commit/b5e672995ae26929d111a6e94589f8d03fb8e578"><code>b5e6729</code></a>
jsdoc: Add -0 and BigInt zeros to _.compact falsey values list (<a
href="https://redirect.github.com/lodash/lodash/issues/6062">#6062</a>)</li>
<li><a
href="https://github.com/lodash/lodash/commit/edadd452146f7e4bad4ea684e955708931d84d81"><code>edadd45</code></a>
Prevent prototype pollution on baseUnset function</li>
<li><a
href="https://github.com/lodash/lodash/commit/4879a7a7d0a4494b0e83c7fa21bcc9fc6e7f1a6d"><code>4879a7a</code></a>
doc: fix autoLink function, conversion of source links (<a
href="https://redirect.github.com/lodash/lodash/issues/6056">#6056</a>)</li>
<li><a
href="https://github.com/lodash/lodash/commit/9648f692b0fc7c2f6a7a763d754377200126c2e8"><code>9648f69</code></a>
chore: remove <code>yarn.lock</code> file (<a
href="https://redirect.github.com/lodash/lodash/issues/6053">#6053</a>)</li>
<li><a
href="https://github.com/lodash/lodash/commit/dfa407db0bf5b200f2c7a9e4f06830ceaf074be9"><code>dfa407d</code></a>
ci: remove legacy configuration files (<a
href="https://redirect.github.com/lodash/lodash/issues/6052">#6052</a>)</li>
<li><a
href="https://github.com/lodash/lodash/commit/156e1965ae78b121a88f81178ab81632304e8d64"><code>156e196</code></a>
feat: add renovate setup (<a
href="https://redirect.github.com/lodash/lodash/issues/6039">#6039</a>)</li>
<li><a
href="https://github.com/lodash/lodash/commit/933e1061b8c344d3fc742cdc400175d5ffc99bce"><code>933e106</code></a>
ci: add pipeline for Bun (<a
href="https://redirect.github.com/lodash/lodash/issues/6023">#6023</a>)</li>
<li><a
href="https://github.com/lodash/lodash/commit/072a807ff7ad8ffc7c1d2c3097266e815d138e20"><code>072a807</code></a>
docs: update links related to Open JS Foundation (<a
href="https://redirect.github.com/lodash/lodash/issues/5968">#5968</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/lodash/lodash/compare/4.17.21...4.17.23">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=lodash&package-manager=npm_and_yarn&previous-version=4.17.21&new-version=4.17.23)](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>
2026-01-23 12:38:30 -08:00
FloPinguin f7d3c2e0bc Nations donate troops now 💀 (In team games) (#2984)
## Description:

For v29, balances the HvN winrate.

In team games, nations now donate troops to their weakest team members
(if they have no attack options available).
How often they donate depends on the difficulty.

This PR also has some other little fixes:
- For HvN games, always return true in `shouldAttack()` (make nations a
bit more aggressive).
- Early exit in `attackWithRandomBoat()` for performance
- Early exit in `findNearestIslandEnemy()` for performance AND to make
sure nations which are encircled by friends don't run into this method
(=> no donation happening!)

## 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
2026-01-23 12:33:04 -08:00
DevelopingTom 9415162f51 Split railroads when placing overlapping structures (#3003)
## Description:
Players wrongly assume that building a structure over an existing
railroad will connect it properly. What actually happens is that the
structure will connect on the network with its own railroad, even if the
new railroads are overlapping over the existing network.

To address this issue, this PR splits the overlapping railroad into two
segments when a structure is built over it, and inserts the structure as
a new node in the rail graph. It does not alter the rail network
visually because the same railroad tiles are used for the new segments.

Railroad tiles are not stored directly in the map, they exist only as
edges in the rail graph, so looking for nearby rails would be terribly
inefficient. To address that, this PR introduces a new `RailSpatialGrid`
class which indexes rails on a 4×4 grid, allowing fast spatial queries.

Alternative considered: removing overlapping rails and rebuilding them
from the new structure. It would visually modify the rail network, which
may be unexpected for the player.

It's still missing a visual indicator so the player knows that the
structures has been connected properly.

### Line placement:


![snap_line](https://github.com/user-attachments/assets/f24ddd36-1594-4316-91ff-093a5cebd576)

### Multi-railroad overlap:


![snap_cross](https://github.com/user-attachments/assets/b2cc962e-6dce-4444-b689-7e04a09de603)


## 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
2026-01-22 19:19:51 -08:00
FloPinguin be958dd6c2 Fix NewsModal design a bit 🖌️ (#3002)
## Description:

Fix \<ul> margins.
Maybe for v29, so people get less eye cancer 😄

Previous: 

<img width="788" height="651" alt="Screenshot 2026-01-22 234602"
src="https://github.com/user-attachments/assets/e1945704-c572-4617-b15c-d5053d0bddc4"
/>

Now:

<img width="781" height="652" alt="Screenshot 2026-01-22 234535"
src="https://github.com/user-attachments/assets/6179ce29-349a-4216-8530-08e767bf645a"
/>

## 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
2026-01-22 15:20:20 -08:00