Added about 10 or so cities to the new montreal map.
## Description:
Very minor change, only changed the info.json file for the montreal map,
so that the map now comes with more NPCs. This should make the map more
challenging and fun in offline mode. There is now 13 nations, spread
evenly (as best i could) across the map.
## Please complete the following:
- [x] I have added screenshots for all UI updates - there is no ui
changes
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file - there is no text displayed
change, only new nations.
- [x] I have added relevant tests to the test directory - No tests
relevant
- [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:
Lionhyde
---------
Co-authored-by: jrouillard <jon@rouillard.org>
## Description:
Have AFK player's Warships not attack team members ships, like Transport
Ships boating in. If team mate conquers the AFK player, transfer over
Warships and Transport Ships to conqueror. The transfered Transport
ships attack in the name of the new owner when landing, and when they
are retreated they move back to a new owner shore tile if they have any.
Added tests. Expectation is this PR will be merged in v26 as the real
solution for the temporary workaround of deleting warships.
**Currently:**
- An AFK player can be attacked without troop loss by their team
members. For this purpose, isFriendly now returns false if the other
player isDisconnected
- But that meant Warships would get False from isFriendly too, and
attack the ships and boats of their team members.
- [Temporary workaround was to delete
warships](https://github.com/openfrontio/OpenFrontIO/commit/eea8db7a06aed50c005db35ad55ece026f7a3643)
as soon as the player was deemed AFK. But this is a disadvantage to the
team. For example the AFK player could have 6 warships in the waters,
either defending team land or helping the team cross over to the enemy
team.
- Transport Ships that were on the way to attack, were still deleted
after the AFK player was conquered. But this is also a disadvantage, if
say a transport ship has just managed to breach through to the enemy
lands despite warships all around. That could have made the win for the
team.
(Left to think about: do we want to transfer part of the defender troops
to the isOnSameTeam attacker? Defender looses less troops in the attack
from their team mate. You'd expect troops to lay down their arms mostly,
if the attacker is on the same team and doesn't loose troops themselves.
Those troops that they loose less than normal, are then added to the
attacker once they've been deemed conqueror. The enemy team can still
attack and do normal damage, and can still also be the conqueror so the
team members have to be fast.)
**Changes in this PR:**
- GameImpl > conquerPlayer: Transfer ownership of the warships to the
conquerer of their lands. If the conqueror is not a team member (other
team can still attack, in their case with troop loss), they won't get
the warships and the ships will be deleted like normal. If the conqueror
is a team member, have them capture the warships.
(Captures need to happen in conquerPlayer since this is right before the
last tiles are conquered and PlayerExecution finds out the player is
dead and deletes its units. Captures will be recorded in the stats just
like normal. Things like this add an extra incentive to be the fastest
to conquer the AFK player, next to getting their gold which is also
recorded in stats. The normal Event Box messages are also displayed.)
- GameImpl > conquerPlayer: Also transfer Transport Ships. As a note:
the limit of 3 transport ships concurrently out on water for one player,
can be exceeded in this specific case (the boatMaxNumber is only checked
for canBuild via TransportShipUtils, and in the init of a
TransportShipExecution, not for an existing TransportShipExecution with
a changing owner). This keeps the situation even for the team in terms
of ships that are already out to attack, which is fair.
captureUnit/setOwner won't do the full job here though, so changes in
TransportShipExecution are needed.
- TransportShipExecution: Added originalOwner. So we can check within
the execution itself if the Original owner disconnected, and if so if
the new owner is on the same team. Only in that case change private
this.attacker. This.attacker can still not be changed from the outside
in this way. Find new src of new owner to retreat boat to if needed, and
if new owner has no shore set it to null so the boat will be deleted
upon retreat. To find new src tile of new owner, use
bestTransportShipSpawn instead of canBuild because canBuild checks for
max boats = 3 etcera but the boat is already on its way so those checks
don't apply (we could get false back from canBuild because there's 3
ships out, while we only need to find the source tile so use
bestTransportShipSpawn).
- TransportShipUtils: to use bestTransportShipSpawn to find new owner
source tile to retreat to, we need to make sure it can handle a new
owner without shore tiles. When the new owner has no shore tiles
(candidates.length === 0), return false. This way it won't go on to call
MiniAStar which would have SerialAStar error on an empty this.sources
array.
- WarshipExecution: Changed isFriendly. This makes sure we have the
wanted behavior: allied/team ships should not attack each other once one
of their owners goes AFK.
- AttackExecution: added one more test specifically to check if attack
on AFK teammate is still witthout troop loss "Player can attack
disconnected team mate without troop loss". Also a bugfix that I left in
after removing a related change from this PR: Add a check for
removeTroops === false in the retreat() function, so at the end of the
attack we don't add troops back to owner troops if they were never
removed in the init. This check in retreat() is actually a bug fix
because removeTroops is in the constructor and can be set to True, but
in retreat() troops would then have been given back after not being
removed at init.
- DefaultConfig: small addition to comment.
- Disconnected.test.ts: added tests. Added useRealAttackLogic because at
least "Player can attack disconnected team mate without troop loss"
needs to use the real attackLogic.
- TestConfig: new class useRealAttackLogic extends TestConfig class, so
a test setup can use the real attackLogic from DefaultConfig instead of
the mock function in TestConfig.
- Setup.ts: for the test setup, add parameter to accept
useRealAttackLogic extension class. Defaults to TestConfig.
## Please complete the following:
- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
tryout33
---------
Co-authored-by: Evan <evanpelle@gmail.com>
## Description:
- Move the Delete button to where the Boat button is otherwise. The Boat
and Delete button already mutually exclude eachother anyway; boat button
is only visible on other's tiles, delete button is only visible on your
own tiles. Evan agreed to this new position:
https://discord.com/channels/1359946986937258015/1381293863712591872/1429147325049077860
- Increase the cooldown between deletions from 5 to 15 seconds. PR #2216
introduced a destruction time (deletionMarkDuration) making it take 15s
to delete a building. With the cooldown of 15s between clicking the
Delete button (deleteUnitCooldown) on top of that, you can actually only
delete a building every 15 seconds while it also takes that same time to
destruct it. Players have voiced between 10s to 30s or more so 15s is
still a reasonable time, keeping deletion of mistakenly placed buildings
still possible, while also keeping a small 'scorched earth' option
during an attack but probably only being able to delete 1-2 units in an
attack. Evan and Vivacious Box agreed with the mentioned 10-15s cooldown
too:
https://discord.com/channels/1359946986937258015/1381293863712591872/1429103999088459897
**Video: Delete button new location and 15s cooldown:**
https://github.com/user-attachments/assets/b0b13fc1-1e50-4a7a-8f32-55f7891f9945
**Delete button new location disabled:**
<img width="310" height="316" alt="Delete button disabled new location
radial menu"
src="https://github.com/user-attachments/assets/f65b88ad-5859-4982-be53-8f2f693f5767"
/>
**Delete button new location enabled:**
<img width="332" height="305" alt="Delete button enabled new location
radial menu"
src="https://github.com/user-attachments/assets/037f07c5-622a-4857-9ab8-fc20981de816"
/>
**Radial menu unchanged on others' tiles:**
<img width="346" height="307" alt="Radial menu unchanged on other
territory"
src="https://github.com/user-attachments/assets/085b2043-096f-4c44-8917-467adb8a7213"
/>
## Please complete the following:
- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
tryout33
---------
Co-authored-by: Vivacious Box <jon@rouillard.org>
## Description:
Change Colour/Thickness and Add Rotation to SAM Radius
https://github.com/user-attachments/assets/c701c877-4b71-4266-ad86-bf8e8d61756ahttps://github.com/user-attachments/assets/2ea24df7-ae8f-425e-bb07-19c731529ab6
## Please complete the following:
- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
w.o.n
## Description:
There was a small bug when ownership was updated (annexed territory) and
it wasn't redrawing the radiuses. Complements #2307
## Please complete the following:
- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
w.o.n
## Description:
Betrayal count in PlayerUpdates came from stats. But stats are only kept
for players with ClientID aka real humans. So betrayals stayed 0 for
Nations even after betraying others. This PR fixes it by keeping a
seperate betrayal count for PlayerUpdates while stats are still being
kept to go in the database.
See bug report
https://discord.com/channels/1284581928254701718/1432759837560799403
After:
<img width="642" height="337" alt="image"
src="https://github.com/user-attachments/assets/1b8bcfa1-aadd-4bea-8a5f-7fa9f2c9111f"
/>
## Please complete the following:
- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
tryout33
## Description:
Removed unused code.
PR https://github.com/openfrontio/OpenFrontIO/pull/2044 introduced
function "maybeConsiderBetrayal" in FakeHumanExecution. It was later
replaced by "betray" in BotBehavior, called in a chain of functions
resulting in the behavior that "maybeConsiderBetrayal" originally
intended:
https://github.com/openfrontio/OpenFrontIO/commit/b03f9778dbcada54e0f47232af4cd511a8629980.
## Please complete the following:
- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
tryout33
Co-authored-by: Vivacious Box <jon@rouillard.org>
## Description:
Use a rational function to strongly nerf short trades. At 50 tiles the
reward is halved.
To compensate, increase gold given by trains by 20%.
## Please complete the following:
- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
evan
## Description:
* Create CREDITS.md
* add all link to it on loading page
<img width="338" height="254" alt="Screenshot 2025-10-30 at 6 24 07 PM"
src="https://github.com/user-attachments/assets/5e89c846-f672-44e1-9add-3d03608c849e"
/>
## Please complete the following:
- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
evan
## Description:
On the homepage, the Patterns modal now is titled Skins
(territory_pattern > title). This PR changes the other EN translation
strings to use the word skins, too.
## Please complete the following:
- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
tryout33
---------
Co-authored-by: jrouillard <jon@rouillard.org>
## Description:
Currently not an issue, but this is a code smell in case we ever decide
to have it editable, current implementation will make the default
overwrite the custom setting
Pointed out by #1804
## 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
## Description:
This PR adds the Nuke Wars Baikal map (more balanced out than the
original). This is made for the upcoming Nuke Wars gamemode.
## 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:
> [!IMPORTANT]
> Try here: https://mirv-test.openfront.dev/
> [!NOTE]
> Blocks PRs:
> - #2244
> - #2263
### Summary
Implements intelligent MIRV usage for fakehuman players, enabling them
to make strategic nuclear strikes based on game state analysis.
### Changes
#### Core FakeHuman Strategy (`FakeHumanExecution.ts`)
- **MIRV Decision System**: Added `considerMIRV()` method that evaluates
game state and determines optimal MIRV usage
- **Three Strategic Targeting Modes**:
1. **Counter-MIRV**: Retaliatory strikes against players actively
launching MIRVs at the fakehuman
2. **Victory Denial**: Preemptive strikes against players approaching
win conditions
- Team threshold: n% of total land (configurable)
- Individual threshold: n% of total land (configurable)
3. **Steamroll Prevention**: Strikes against players with dominant city
counts (n% ahead of next competitor)
#### FakeHuman Behavior Tuning
- **Cooldown System**: n-minute cooldown between MIRV attempts
(configurable)
- **Failure Rate**: ~n% chance of cooldown trigger without launch
(simulates human hesitation/resource management; configurable)
- **Territory Targeting**: Centers MIRV strikes on enemy territory
center-of-mass for maximum impact
#### Technical Improvements
- **Type Safety**: Updated `UnitParamsMap` to include `targetTile`
parameter for MIRV units
- **Execution Flow**: Integrated MIRV consideration into fakehuman tick
cycle outside of standard attack logic, due to its holistic strategic
nature
### Game Balance Impact
- **FakeHuman Threat Level**: Increases late-game fakehuman
competitiveness
- **Endgame Dynamics**: Prevents runaway victories, extends game tension
### Breaking Changes
None - purely additive feature
### Related GitHub Issues:
- #2205
------
## Other
- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
Discord Username: samsammiliah
---------
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Evan <evanpelle@gmail.com>
## Description:
Fixes#2257 (well, a part of it)
This PR implements a new async helper function in client Utils.ts (
getSvgAspectRatio), which caches and then retrieves aspect ratios for
Svg files. (I am not married to it being in Utils.ts, I just couldn't
find a better place to put it, and it seemed like something that should
be accessible to many files).
It then implements this helper in RadialMenu.ts to fix incorrect aspect
ratios. It uses the default value for the smaller side, and the computed
value for the larger side.
Before fixing the stretching in EventsDisplay.ts, this PR first
consolidates the hard coded html for toggle buttons into a helper
function (renderToggleButton). Afterwards, it adds width calculation to
this helper function using getSvgAspectRatio.
## Potential flaws
- getSvgAspectRatio might potentially be in the wrong file
- EventsDisplay.ts consolidation may be out of scope, but it seemed
necessary to make clean changes. It also introduces a slight delay
before toggle buttons are loaded once a player enters the match
- If the icon is not cached yet, the RadialMenu implementation shows the
old stretched icon for a split second. In regular gameplay this should
probably not be noticeable,
- For some reason (I guess because of slightly too many characters)
prettier split up exactly one of the renderToggleButton calls which
makes it ugly, but thats what prettier wants lol
- Not sure if I should add any tests? If so feel free to tell me, but I
didn't so far.
## Screenshots
Before
<img width="323" height="416" alt="image"
src="https://github.com/user-attachments/assets/709493c8-c8d6-48c1-9d44-4d6608d7da93"
/>
After
<img width="323" height="390" alt="image"
src="https://github.com/user-attachments/assets/a786c83e-2ef9-47d6-9858-1aeaa4ae548a"
/>
## 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:
Lavodan
---------
Co-authored-by: Evan <evanpelle@gmail.com>
## Description:
This PR addresses issue #2302: where there is no obvious information
about the self-player's team during the spawn phase of the game.
Currently, during TEAM games (where there is a set number of teams
defined), the self player's spawn highlight color is white, while all
other players are shown with a team-based spawn highlight color. This
makes it difficult to discern who is a teammate, especially since the
current live version (v0.26.7) uses green/yellow for other players to
depict teammate/other team, respectively.
Technically, the same is true for Duos, Trios, and Quads games, although
this has been addressed separately with PR #2298 by reverting to
green/yellow for teammate/other team players.
This PR changes the color of the self player's breathing spawn highlight
ring to match their assigned team color (with `alpha=0.5` for
transparency). The breathing ring is semi transparent on top of the
existing white static semi-transparent ring, giving the breathing ring a
**tint** of the team color instead of the exact team color.
This allows a player to immediately identify their assigned team and
maintains overall consistency with FFA, Duos, Trios, and Quads game
modes.
See below for example implementation. In this screenshot, the self
player is on the red team as shown by the red tint to the breathing
spawn highlight ring. The screenshot also shows some of the static white
semi-transparent ring around the spawn location. The self player's
teammate is to the top left of the image with a solid red spawn
highlight. The non-player (nation) opponent on the blue team is shown to
the bottom left. In online games, nations are not present in team games.
In single player or private lobby games they are shown as here, without
a spawn color highlight and only a territory color.
<img width="402" height="292" alt="Team Spawn Color Tint"
src="https://github.com/user-attachments/assets/5696a408-a633-4ec8-bf93-c8afa8e2e121"
/>
## 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:
GlacialDrift
## Description:
New FX played to preview the nuke explosion area (follow up of
https://github.com/openfrontio/OpenFrontIO/pull/2309)
Will prevent over-nuking the same area in team games

Visuals inspired from
https://github.com/openfrontio/OpenFrontIO/pull/1814 (@ryanbarlow97)
## 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: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
## Description:
PR https://github.com/openfrontio/OpenFrontIO/pull/1676 introduced a
duplicate line of code in ControlPanel. Resulting in _troops being set
twice in a row. Remove one to keep only the oldest one.
## Please complete the following:
- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
tryout33
## Description:
Fill the range indicators
<img width="287" height="200" alt="image"
src="https://github.com/user-attachments/assets/2c75cb13-0574-40c9-be48-2f28cf77734e"
/>
## 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
## Description:
Fixes: #676
This PR adds Players Vs Nations as a game mode in the menu.
For this change I have added two mutually exclusive option for this
mode:
1. Match number of nations to number of players who have joined
2. Set the number of nations to a fixed value
### Screenshots:
#### Options in Single player mode
<img width="1025" height="790" alt="image"
src="https://github.com/user-attachments/assets/c0685ea5-94f5-43c7-a9e5-390835fc94e9"
/>
<img width="1005" height="795" alt="image"
src="https://github.com/user-attachments/assets/dddba015-a424-40dd-a0fe-2571fd7b0fba"
/>
#### Options in lobby mode
<img width="1015" height="888" alt="image"
src="https://github.com/user-attachments/assets/45bc865b-c6a8-4b6a-9062-4eb499c1ea36"
/>
#### Example gameplay (1 Human Vs 90 Nations)
<img width="1888" height="912" alt="image"
src="https://github.com/user-attachments/assets/38faec75-171f-4358-a3be-93630cca1587"
/>
## 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:
saphereye
---------
Co-authored-by: Evan <evanpelle@gmail.com>
## Description:
Added logic to hydro/atom bombs - using same FX as the boat invasion
(keeping PR smaller, can add more UX for hydro/atoms later)
Only you & teammates can see the target.
<img width="747" height="356" alt="image"
src="https://github.com/user-attachments/assets/bc1aaec0-8b41-4def-92ee-9f076a8cd550"
/>
Viewpoint from two players:
<img width="1667" height="680" alt="image"
src="https://github.com/user-attachments/assets/76e96ad1-af09-4584-a71a-823c85b6e26b"
/>
## Please complete the following:
- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
w.o.n
## Description:
This will be used to determine clan winners in the api layer.
## 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:
**This PR expands clan name possibilities available to players.**
**Suggested Label:** Feature
**Suggested Milestone:** v26 or v27
The current clan name logic does not allow for all alphanumeric
characters (e.g. 0-9). Instead it only allows for uppercase and
lowercase letters (e.g. a-z and A-Z). This PR updates the logic to
include 0-9 in the allowable character set. This is in line with how
many other games utilize clan names.
Secondarily, the requirement for the clan name to occur at the start of
the player name has been relaxed. Now, the requirement is that the clan
name is matched with `\[([a-zA-Z0-9]{2,5})\]`. The pre-requisites for
clan regex matching have been updated so that both `[` and `]` must be
*included* in the player name (whereas previously the `[` was required
to appear at the start of the player name). This allows the clan name to
occur anywhere in the player name.
Finally, clan names (once matched by RegEx) are converted to Uppercase
so that clan names such as `[un]`, `[UN]`, `[Un]`, and `[uN]` are all
recognized as the *same* clan.
As a result, all existing clan names remain valid, but new clan names
are now possible. For example `[3M]MeanMrMustard` now has `3M`
recognized as the clan name and `T[UN]able` now has `UN` recognized as
the clan name. Test cases within the `tests/PlayerInfo.tests.ts` file
have been updated accordingly to accurately represent the full
alphanumeric character set.
This addresses issue #2267.
## 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:
GlacialDrift (GlacialDrift_)
## Description:
Fixes#2135.
Adds an owner check to canUpgradeUnit to prevent enemy units from
seemingly being able to be upgraded when Ctrl+clicked on
## 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:
Lavodan
## Description:
This PR aims to (quickly, not definitely) address
https://github.com/openfrontio/OpenFrontIO/issues/2274 as I believe
that's an urgent DDOS problem with the frontend design.
I am looking at the backend to understand the underlying issue.
## How was this tested:
I added a 2 seconds "sleep" to the endpoint `public_lobbies` to simulate
loads.
The frontend would do request every seconds, which kept piling up on the
server and decreased performances, cf screenshot, instead of resolving
every 2 seconds, each subsequent request would take longer than the
previous one.
<img width="849" height="263" alt="Screenshot 2025-10-23 at 23 36 37"
src="https://github.com/user-attachments/assets/31ded504-a72e-4794-9c5e-b9b0c675dd33"
/>
After adding the fix to the frontend (which can only trigger 1 request
at a time, waiting for the previous one), all request completed in
approximatively 2 seconds as expected, cf screenshot.
<img width="849" height="263" alt="Screenshot 2025-10-23 at 23 36 54"
src="https://github.com/user-attachments/assets/bc680642-407a-4a55-aeed-6a03bad35327"
/>
## 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:
sorikairo
Co-authored-by: Vivacious Box <jon@rouillard.org>
## Description:
Reduce halloween sprites size so they don't leave pixel behinds when
deleted
## 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:
Remove some lines of code that do nothing in surroundedBySamePlayer,
gain a small bit of performance back. The code says "if it is an ocean
shore tile but not an ocean shore tile" which can never be true.
(Why where the lines there and why can they be removed:
Before you were able to boat on a lake, you had no escape from your land
if it bordered a lake and no ocean. So it was logical, if you bordered a
lake with your cluster, to still treat it as fully surrounded annexable
land.
This is why this code was added in [this
commit](https://github.com/openfrontio/OpenFrontIO/commit/ee56d687484131c092599434247b3a036e0e9668)
back then:
`const isOceanShore = this.mg.isOceanShore(tile); if
(this.mg.isShore(tile) && !isOceanShore) { continue; }`
But [this newer
commit](https://github.com/openfrontio/OpenFrontIO/commit/c1383d76f1f76c5e5f9be3a6f30b8f3010258540#diff-fb1101a2b50dd7c353d082ff7a3351cff5469b8249b3ebca91c10573a3dfaaf1)
made it so you could from then on boat on lakes. So you have an escape
from your cluster since then. And just like being on the edge of the map
or when bordering the ocean, this means your cluster won't get annexed.
However, while the updated code for PlayerExecution in the last commit
does its work as intended (it does not exclude lake shore tiles
anymore)... The code contradicts itself:
`const isOceanShore = this.mg.isOceanShore(tile); if
(this.mg.isOceanShore(tile) && !isOceanShore) { continue;}`
Conclusion: the code on lines 136-138 can be deleted because it
literally says "if it is an ocean shore tile but not an ocean shore
tile" which can never be true. Also remove the const and check
isOceanShore directly in the if statement.)
## Please complete the following:
- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
tryout33
fixes#2275
Added global Start/Stop trading; use your **player panel** to trigger
it.
<img width="370" height="540" alt="Screenshot 2025-10-23 184447"
src="https://github.com/user-attachments/assets/c3b7967e-ffdd-4f37-ba67-b60a602278ce"
/>
- [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:
abodcraft1
## Description:
This PR addresses issue #2297 - Spawn Color Overload in DUOS, TRIOS, and
QUADS game modes. This PR reverts the spawn highlight color behavior for
these game modes so that the player can identify their teammates more
easily in these modes.
See below for example fix. The "self" player and their teammate in this
DUOS mode game are the same `light blue` color as shown in issue #2297
and their opponent is still the same `brown` color as shown in that
issue.
However, now the player's teammate has a green spawn highlight color
(same as v0.26.7 and earlier) and the players on other teams have a
yellow spawn highlight color (same as v0.26.7 and earlier).
<img width="605" height="657" alt="Duos Teammate ID Resolution"
src="https://github.com/user-attachments/assets/6e62830a-31bb-4d3d-ae5a-34b809ea4e13"
/>
The "self" player's spawn highlight color remains a breathing white
ring, consistent with other game modes.
## 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:
GlacialDrift
## Description:
This PR fixes layout issues in the User Settings → Keybind section where
the “Unbind” button text would overflow in languages with long
translations (e.g., Italian).
before
<img width="372" height="477" alt="スクリーンショット 2025-10-25 15 42 09"
src="https://github.com/user-attachments/assets/ce31e116-1848-4350-a6da-011b10a42668"
/>
after
<img width="383" height="168" alt="スクリーンショット 2025-10-25 15 41 47"
src="https://github.com/user-attachments/assets/8133ed56-f920-42a8-9477-78561fdd477a"
/>
## 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: Evan <evanpelle@gmail.com>
## Description:
Describe the PR.
Adds the Halloween Special Map - Achiran. It has 4 nations and will be
playable in game for a period of around 2 weeks during the Halloween
event.
## 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:
Replaced Array.shift() in boat path iteration with an index-based loop
to avoid O(n) shifts per step. This reduces per-move cost and keeps
memory usage unchanged. I validated the change by running locally and
confirming behaviour is unchanged.
### Summary
This PR improves pathfinding performance by replacing Array.shift() with
an index-based iteration to get the next boat position.
Shifting the array for each move is O(n) per operation, whereas using an
index is O(1).
JavaScript does not free the memory of the shifted elements immediately,
so there’s no memory benefit to shift() in this context. Using an index
improves performance without additional memory cost.
### Testing & Caveats
- I attempted to test the performance gain by increasing the trade cap
to 5000, but on my system, neither method could be stressed enough to
produce measurable differences.
- I am unfamiliar with JavaScript profiling tools, so I do not have
exact performance numbers.
- Based on the change, there is no risk of decreased performance.
- In my minor testing, the boat pathfinding felt faster when a single
player was set to max speed as the game would slow down less.
### Notes
- This is primarily an optimization for future scalability and clean
performance improvements.
- With this change, the max boat cap can potentially be increased.
- The behavioural logic remains unchanged; the boats still navigate the
same paths as before.
### 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
## Description:
fixes#2275
Added global Start/Stop trading; use your **player panel** to trigger
it.
<img width="370" height="540" alt="Screenshot 2025-10-23 184447"
src="https://github.com/user-attachments/assets/c3b7967e-ffdd-4f37-ba67-b60a602278ce"
/>
## 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
## Description:
Updated the stale comment, removed issue write permissions, updated the
orphaned comment
## 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:
loymdayddaud
## Description:
This PR adds the missing string for the MIRV keybind action in the User
Settings menu.
<img width="383" height="137" alt="スクリーンショット 2025-10-25 16 03 21"
src="https://github.com/user-attachments/assets/1a436fff-76a3-428a-bf14-c836ef9faf40"
/>
## 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
## Description:
**This PR expands clan name possibilities available to players.**
**Suggested Label:** Feature
**Suggested Milestone:** v26 or v27
The current clan name logic does not allow for all alphanumeric
characters (e.g. 0-9). Instead it only allows for uppercase and
lowercase letters (e.g. a-z and A-Z). This PR updates the logic to
include 0-9 in the allowable character set. This is in line with how
many other games utilize clan names.
Secondarily, the requirement for the clan name to occur at the start of
the player name has been relaxed. Now, the requirement is that the clan
name is matched with `\[([a-zA-Z0-9]{2,5})\]`. The pre-requisites for
clan regex matching have been updated so that both `[` and `]` must be
*included* in the player name (whereas previously the `[` was required
to appear at the start of the player name). This allows the clan name to
occur anywhere in the player name.
Finally, clan names (once matched by RegEx) are converted to Uppercase
so that clan names such as `[un]`, `[UN]`, `[Un]`, and `[uN]` are all
recognized as the *same* clan.
As a result, all existing clan names remain valid, but new clan names
are now possible. For example `[3M]MeanMrMustard` now has `3M`
recognized as the clan name and `T[UN]able` now has `UN` recognized as
the clan name. Test cases within the `tests/PlayerInfo.tests.ts` file
have been updated accordingly to accurately represent the full
alphanumeric character set.
This addresses issue #2267.
## 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:
GlacialDrift (GlacialDrift_)
## Description:
Describe the PR.
Adds the Halloween Special Map - Achiran. It has 4 nations and will be
playable in game for a period of around 2 weeks during the Halloween
event.
## 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:
Fixes Issue #2177, land border required to send boat. And fixes boat not
being sent for longer distances.
- Boat Hotkey (B) (PR #1060) was implemented seemingly with a wrong
assumption. Namely that it should do the same checks as the AUTO BOAT
functionality (PR #540) before sending a transport ship. But it should
have done the same checks as when sending a MANUAL transport ship, as if
the Radial Menu was used. Basically the same checks as in
RadialMenuElements line 508-532.
Because of this it wrongly required:
- there to be no land border with the other player
(while boat from radial menu gets sent without bothering about this)
- the tile clicked to be a Land tile
(only makes sense in the context of auto-boating where user clicks to
attack an enemy on their land, and only if there's no border will it
then send a boat to that land if possible)
- the distance to be short
(since auto-boat was mainly meant to automatically cross rivers)
Fixed this by removing canAttack check (for the unwanted land border
requirement) and splitting up the auto boat and the manual boat checks.
- canBoatAttack: moved out the parts which where only meant for
auto-boating
- shouldBoat: moved in the parts from canBoatAttack that where only
meant for auto-boating. Renamed it to canAutoBoat for better
discernability. Gave it early returns for tad better performance and
consolidated returns in the bottom, while keeping the same
functionality.
## Please complete the following:
- [ ] I have added screenshots for all UI updates
- [ ] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [ ] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
tryout33
**This PR improves spawn highlighting to identify self and friend/foe.
Suggested Label: Feature
Suggested Milestone: v26 or v27**
## Description:
**This PR changes the behavior for spawn color highlighting and
addresses issue #2270.**
Currently, the user's spawn highlight color is the same as all other
players in FFA and the same as all enemies in Team games. Although
"breathing" rings were added recently for the user's spawn highlight,
this can still be difficult to find on the map, especially with large
player counts.
This PR modifies how spawn highlights are drawn for the user and for
allies and enemies in Team games.
### User Spawn Color Updates
First, an additional spawn highlight color was added for the user in
`src/core/configuration/PastelTheme.ts`: `_spawnHighlightSelfColor`.
This is defined to be white (0xFFFFFF).
Second, the breathing ring was modified to improve visibility (all in
`src/client/graphics/layers/TerritoryLayer.ts`) :
- A radial-gradient transparent ring in the spawn color (white) is drawn
at all times
- The ring is transparent for `radius = 8` pixels from the player's
center point
- The gradient extends from `8` to `24` pixels from the player's center
point
- The first 10% of the ring (~ 1 pixel) is solid
- The remaining ring fades to transparent at `24` pixels
- A solid, "breathing" ring is drawn on top of the transparent ring
- The solid ring is also transparent for `radius = 8` pixels from the
center point
- The outer radius of the solid ring is a function of "time" in the same
way that the current breathing ring is implemented.
- The solid ring therefore grows and shrinks to cover the transparent
ring
### Other Player Spawn Color Updates
In FFA games, no change is made to the spawn color highlight of other
players. It remains `rgb(255,213,79)`.
In team games, the spawn color highlight of other players is updated to
use their team colors. For example, a player on the red team will have a
red spawn highlight, while a player on the purple team will have a
purple spawn highlight.
Both of these changes are handled with a simple update in
`src/client/graphics/layers/TerritoryLayer.ts` within the
`spawnHighlight()` method:
```typescript
const myPlayer = this.game.myPlayer();
if (myPlayer !== null && myPlayer !== human && myPlayer.team() === null) {
// In FFA games (when team === null), use default yellow spawn highlight color
color = this.theme.spawnHighlightColor();
} else if (myPlayer !== null && myPlayer !== human) {
// In Team games, the spawn highlight color becomes that player's team color
// Optionally, this could be broken down to teammate or enemy and simplified to green and red, respectively
const team = human.team();
if (team !== null) color = this.theme.teamColor(team);
}
```
### Attached Images
Three images have been attached. The three images show a progression of
the "breathing" user highlight. They also show the team-specific
highlights of players on other teams. (Note that Nations in the private
game were assigned teams but do not have spawn highlights).
<img width="1161" height="895" alt="Screenshot 2025-10-22 211929"
src="https://github.com/user-attachments/assets/71d466b8-61e4-4e30-83e5-06efdfc706ce"
/>
<img width="1322" height="934" alt="Screenshot 2025-10-22 212003"
src="https://github.com/user-attachments/assets/4e6c18b7-7f9e-436d-afb9-85a08a11c40b"
/>
<img width="1340" height="954" alt="Screenshot 2025-10-22 212028"
src="https://github.com/user-attachments/assets/597d0ed5-5519-4cf7-bc60-9963da3f7d7f"
/>
### Misc.
- I added `.idea/` to `.gitignore` because I use JetBrains IDEs
- I expanded the `fallbackColors` list. Right now it has a lot of green
colors, so I added equivalents for red, blue, cyan, magenta, and yellow.
## 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:
GlacialDrift
## Description:
Closes#2201
Remove CSS transition from SVG element that was causing the radial menu
to animate from its previous position to the new clicked position. This
was creating delays of up to 2 seconds for mobile players, making the
game unplayable on mobile devices.
The viewport clamping functionality (from PR #1817) is preserved - the
menu now appears instantly at the correct clamped position instead of
animating to it.
I wasn't sure if this should only apply for mobile players, but making
it so sounded too much trouble for what it's worth so its removed
entirely
## 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:
stackk.