Commit Graph

2802 Commits

Author SHA1 Message Date
FloPinguin dfe33a05e9 Improved the nation alliance request logic 🤝 Massive upgrade to singleplayer fun (#2606)
## Response to alliance requests

Previously the way nations responded to alliance requests was quite
simple / boring / exploitable. Basically you couldn't ally them if you
had a bad relation with them, or if you had too many alliances.
Otherwise they would just take it.

Now there is a **complete decision tree which is based on the
difficulty**. The nations should also feel more human now.

For example, just like humans, nations will now consider to take an
alliance even if you have a bad relation with them (If you are a
threat).

Also, nations no longer check if YOU have too many alliances. Now they
do what humans do: Check if THEY have too many alliances (they want to
be able to attack somebody).

Another big change is the default case: Previously it was just `return
true`. Now it's `return isAlliancePartnerSimilarlyStrong`. So they do
what humans do: Take a quick look at their troop count before allying
them.

## Sending alliance requests

Previously alliance requests were sent randomly. Quite boring.

Now we use the same decision tree as for responding.

## Alliance extension requests

They also use the same decision tree.

## Tests

Tested it a lot in singleplayer.
I have planned to add unit tests for all the nation/bot stuff in the
upcoming cleanup 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:

FloPinguin
2025-12-14 15:18:07 -08:00
Aotumuri 66ae8cd9bb Remove troop ratio slider and description (#2617)
## Description:

Removed unused translation strings and code.

## 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
2025-12-14 15:13:40 -08:00
Aotumuri 9d10ca71a5 Fix: GulfOfStLawrence map name not being translated (#2616)
## Description:
The map name was not translated because it contained a . character,
which caused the translation key to break.

To prevent this issue, the map name handling now strips . characters
when generating translation keys.
With this change, maps that include . in their names will no longer
cause translation issues in the future.

Before fix:
<img width="538" height="284" alt="スクリーンショット 2025-12-14 14 26 02"
src="https://github.com/user-attachments/assets/a683e3de-09df-4b43-8077-4a00bd5f1272"
/>

After fix:
<img width="494" height="176" alt="スクリーンショット 2025-12-14 14 27 19"
src="https://github.com/user-attachments/assets/f9d27e16-de70-4c43-af31-aaa30287e5cd"
/>


## 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
2025-12-13 21:51:31 -08:00
VariableVince 099337d83e Special bot names 2 (#2609)
## Description:

Second and last changes to special bot names. Sorry to anyone who might
feel left out, the list is non-exhaustive.

## 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
2025-12-13 19:36:37 -08:00
FloPinguin b4ec54113d Fixed events panel scroll position not staying at the bottom 🛠️ (#2613)
## Description:

Common issue reported by several people (many times by Enzo) now finally
fixed.
If you scroll to the bottom of the events panel the scroll position now
always stays there.
This behavior was previously implemented with CSS only, which apparently
did not work properly. Now we use javascript.

## 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
2025-12-13 19:35:55 -08:00
evanpelle ddeebefebe Merge branch 'v27' 2025-12-13 14:43:45 -08:00
Aotumuri 5392e0b9e3 Prevent keyboard shortcuts from firing while typing in quick chat search (#2528)
## Description:

Guard global keydown/keyup handlers to ignore events from
text/textarea/contenteditable targets (except Escape/active keys) so
gameplay shortcuts don’t trigger while typing in the quick chat player
search.

## 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
2025-12-13 22:15:00 +00:00
dependabot[bot] 3e8ad650e0 Bump node-forge from 1.3.1 to 1.3.2 in the npm_and_yarn group across 1 directory (#2530)
Bumps the npm_and_yarn group with 1 update in the / directory:
[node-forge](https://github.com/digitalbazaar/forge).

Updates `node-forge` from 1.3.1 to 1.3.2
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/digitalbazaar/forge/blob/main/CHANGELOG.md">node-forge's
changelog</a>.</em></p>
<blockquote>
<h2>1.3.2 - 2025-11-25</h2>
<h3>Security</h3>
<ul>
<li><strong>HIGH</strong>: ASN.1 Validator Desynchronization
<ul>
<li>An Interpretation Conflict (CWE-436) vulnerability in node-forge
versions
1.3.1 and below enables remote, unauthenticated attackers to craft ASN.1
structures to desynchronize schema validations, yielding a semantic
divergence that may bypass downstream cryptographic verifications and
security decisions.</li>
<li>Reported by Hunter Wodzenski.</li>
<li>CVE ID: <a
href="https://www.cve.org/CVERecord?id=CVE-2025-12816">CVE-2025-12816</a></li>
<li>GHSA ID: <a
href="https://github.com/digitalbazaar/forge/security/advisories/GHSA-5gfm-wpxj-wjgq">GHSA-5gfm-wpxj-wjgq</a></li>
</ul>
</li>
<li><strong>HIGH</strong>: ASN.1 Unbounded Recursion
<ul>
<li>An Uncontrolled Recursion (CWE-674) vulnerability in node-forge
versions
1.3.1 and below enables remote, unauthenticated attackers to craft deep
ASN.1 structures that trigger unbounded recursive parsing. This leads to
a
Denial-of-Service (DoS) via stack exhaustion when parsing untrusted DER
inputs.</li>
<li>Reported by Hunter Wodzenski.</li>
<li>CVE ID: <a
href="https://www.cve.org/CVERecord?id=CVE-2025-66031">CVE-2025-66031</a></li>
<li>GHSA ID: <a
href="https://github.com/digitalbazaar/forge/security/advisories/GHSA-554w-wpv2-vw27">GHSA-554w-wpv2-vw27</a></li>
</ul>
</li>
<li><strong>MODERATE</strong>: ASN.1 OID Integer Truncation
<ul>
<li>An Integer Overflow (CWE-190) vulnerability in node-forge versions
1.3.1
and below enables remote, unauthenticated attackers to craft ASN.1
structures containing OIDs with oversized arcs. These arcs may be
decoded
as smaller, trusted OIDs due to 32-bit bitwise truncation, enabling the
bypass of downstream OID-based security decisions.</li>
<li>Reported by Hunter Wodzenski.</li>
<li>CVE ID: <a
href="https://www.cve.org/CVERecord?id=CVE-2025-66030">CVE-2025-66030</a></li>
<li>GHSA ID: <a
href="https://github.com/digitalbazaar/forge/security/advisories/GHSA-65ch-62r8-g69g">GHSA-65ch-62r8-g69g</a></li>
</ul>
</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>[asn1] Fix for vulnerability identified by CVE-2025-12816 PKCS#12
MAC
verification bypass due to missing macData enforcement and improper
asn1.validate routine.</li>
<li>[asn1] Add <code>fromDer()</code> max recursion depth check.
<ul>
<li>Add a <code>asn1.maxDepth</code> global configurable maximum depth
of 256.</li>
<li>Add a <code>asn1.fromDer()</code> per-call <code>maxDepth</code>
option.</li>
<li><strong>NOTE</strong>: The default maximum is assumed to be higher
than needed for valid
data. If this assumption is false then this could be a breaking change.
Please file an issue if there are use cases that need a higher
maximum.</li>
<li><strong>NOTE</strong>: The per-call <code>maxDepth</code> parameter
has not been exposed up through
all of the API stack due to the complexities involved. Please file an
issue
if there are use cases that require this instead of changing the default
maximum.</li>
</ul>
</li>
<li>[asn1] Improve OID handling.
<ul>
<li>Error on parsed OID values larger than <code>2**32 - 1</code>.</li>
<li>Error on DER OID values larger than <code>2**53 - 1 </code>.</li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/digitalbazaar/forge/commit/235ad3e70e4fdfdca4fdeb662dfba6588e2c38bd"><code>235ad3e</code></a>
Release 1.3.2.</li>
<li><a
href="https://github.com/digitalbazaar/forge/commit/25982441171dc9815c87d3d886c5c8a1d092b334"><code>2598244</code></a>
Update changelog.</li>
<li><a
href="https://github.com/digitalbazaar/forge/commit/0032dd0be8b6fb1b1092ef754d1dde91c10a95ad"><code>0032dd0</code></a>
Fix typos.</li>
<li><a
href="https://github.com/digitalbazaar/forge/commit/d75e08d255559ae401d9368346cacefde306e6df"><code>d75e08d</code></a>
Run new security test.</li>
<li><a
href="https://github.com/digitalbazaar/forge/commit/a5ce91d03df4dcfc025b74a5b7f50389942d49c9"><code>a5ce91d</code></a>
Update changelog formatting.</li>
<li><a
href="https://github.com/digitalbazaar/forge/commit/4652de6ddd833392e52d99b37abbbda76817c0b7"><code>4652de6</code></a>
Cleanups.</li>
<li><a
href="https://github.com/digitalbazaar/forge/commit/eb932d94fbd88655f46ac7a94a8e13e7ed8597f7"><code>eb932d9</code></a>
Fix typo.</li>
<li><a
href="https://github.com/digitalbazaar/forge/commit/db6954ba4b4440831a5112dea5d37ef68a28b878"><code>db6954b</code></a>
Fix style.</li>
<li><a
href="https://github.com/digitalbazaar/forge/commit/afbf7d8e0812014da134caa5a064cf55d1f61847"><code>afbf7d8</code></a>
Align error message style.</li>
<li><a
href="https://github.com/digitalbazaar/forge/commit/6607445859637442cf586eaa7fa06e99a2a8ae0b"><code>6607445</code></a>
Revert minor changes.</li>
<li>Additional commits viewable in <a
href="https://github.com/digitalbazaar/forge/compare/v1.3.1...v1.3.2">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=node-forge&package-manager=npm_and_yarn&previous-version=1.3.1&new-version=1.3.2)](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>
Co-authored-by: Evan <evanpelle@gmail.com>
2025-12-13 12:27:08 -08:00
evanpelle 1b79d531d0 require jwts for production 2025-12-12 16:49:22 -08:00
evanpelle 04370eda17 Merge branch 'v27' 2025-12-12 16:20:43 -08:00
scamiv e290e587ea perf: Optimize cluster calculation with DFS and zero-allocation patterns (#2539)
## Description:

Replace BFS with DFS and eliminate GC pressure in calculateClusters():

- Switch from O(N) queue.shift() to O(1) stack.pop() operations
- Replace Set.has()/Set.add() with Uint8Array bitfield
- Add reusable buffer management to avoid repeated allocations
- Implement callback-based neighbor iteration to eliminate array
allocations
- Add forEachNeighborWithDiag() method to Game interface and GameImpl
- Remove now unused GameImpl import from PlayerExecution

Describe the PR.

## Please complete the following:

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

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

DISCORD_USERNAME
2025-12-12 14:19:37 -08:00
evanpelle 2e52c0aa41 better logging for auth/account fetch failures v0.27.10 2025-12-12 10:25:26 -08:00
evanpelle b832da308a reduce gold from trains by ~10% v0.27.9 2025-12-11 20:37:06 -08:00
Evan dab04eddb4 bugfix: user receives unauthorized on reconnection (#2601)
## Description:
When rejoining, the client did not refresh the play token, so the jwt
could be expired, causing the server to reject it.

Also improved the error log when token fails

## 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.27.8
2025-12-11 20:00:53 -08:00
evanpelle ef0aff12e2 update tranlation key in account_modal v0.27.7 2025-12-11 16:23:59 -08:00
FloPinguin 427e462fe5 Revamp nation/bot enemy selection 🗡️ (#2550)
## Description:

I closed my previous PR #2533 which was already reviewed by evan (but
not yet merged) because I noticed some issues.
Which led me to changing the enemy selection entirely. 

Nations / Bots previously had a fixed enemy which they kept for 100
ticks (10 seconds). This could make them react too late and feel slow.
Now they are a bit more responsive.

But the main benefit: Without a fixed enemy we can do multiple
sendAttack() on the same tick, which allowed me to give impossible
nations extremely efficient parallel bot attacks:


https://github.com/user-attachments/assets/38f65623-fbf0-4e98-a833-5fcba2ee6eee

Previously nations were so slow in taking out bots that you could even
encircle them on the Archiran map...
Now they are like 200% faster (but only on the impossible difficulty)

## Nuke enemy selection

Previously, the enemy for troop attacks and nukes was identical. Now, as
we no longer have a fixed enemy in BotBehaviour, I added
findBestNukeTarget() to select better nuke-targets. I will probably open
a PR soon which makes nations nuke the crown :)

## Betrayal logic

While revamping the attack logic I had to work on the betrayal logic,
which was quite confusing, with many negations. And the betrayals were
just random.
So I made it easier to understand with maybeBetrayAndAttack().
Now it does betray friends if we have 10 times more troops than them. I
will improve that method in a future PR, but already now it should be
better than just betraying randomly.

## Attack order

Previously, nations attacked in this order:

- TerraNullius (Untaken land and nuked territory)
- Bots
- Retaliate against incoming attacks

Now its in this order:

- TerraNullius (Untaken land)
- Retaliate against incoming attacks
- Bots
- TerraNullius (Nuked territory)

So the changes are these:

- After throwing a nuke onto a nation, they will no longer ignore
incoming attacks. Previously they attacked the nuked territory first.
Very common singleplayer problem.
- Nations now retaliate against incoming attacks before attacking bots.
Previously you could attack a nation but they did not care because there
were still bots left.

I also changed the attack order of bots a bit (retaliate before
attacking randoms), but that isn't even noticeable.

## Big bug fixed

Additionally, I fixed a big bug: selectEnemy() oftentimes returned null
(because of enemySanityCheck) and therefore no attack happened.
This was especially visible in games where nations are surrounded by
friends (Team games and nations vs humans).
This was also the reason why Enzo could play nations vs humans in
singleplayer and NO NATION of the much bigger nation team would try to
attack him.

## 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
2025-12-11 13:57:15 -08:00
Duwibi 1f8adb4849 Add Svalmel (#2600)
## Description:
This PR adds the Christmas map Svalmel with 5 nations.

Describe the PR.

## Please complete the following:

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

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

DISCORD_USERNAME
Nikola123
2025-12-11 21:53:05 +00:00
evanpelle af17fb85dd update ratio of ffa:team games to 2:1 2025-12-11 13:52:04 -08:00
evanpelle 01e5aaa832 If user has no linked account, ensure that their skin is set to default 2025-12-11 12:18:06 -08:00
Evan a09f0c67f1 Update auth & login to follow best practices (#2559)
## Description:

The previous login system used long lived jwts which could be stolen by
XSS. The current system uses long lived refresh tokens that are stored
as http-only cookies. Then the client calls /refresh to get a short
lived jwt using the refresh token. The jwt is stored in memory only so
it's discarded on page close. This way a XSS can only steal the
short-lived jwt.

It also updates how accounts work: players get an account automatically
when they join the webpage. They can see their stats even if not logged
in. If a player wants to keep their account, they can tie it to their
Discord or email, allowing them to log in if cookies are lost.

## 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
2025-12-11 11:25:27 -08:00
Roan 8dde30ebb6 Update game timer UI (#2577)
## Description:

- use hh:mm:ss for timer format or mm:ss if no hours are present
- refactor classes and code to be simpler
- move timer inline with the buttons so the whole ui is smaller for more
game space
- update fast forward icon to better represent what it does
- move replay controls below game time ui

### Before:

<img width="218" height="155" alt="image"
src="https://github.com/user-attachments/assets/bfdbe571-3ec5-4c02-840b-112e8e3caab1"
/>
<img width="360" height="171" alt="image"
src="https://github.com/user-attachments/assets/ceee2923-fec8-4ebc-b9de-4b30a47b38a8"
/>
<img width="192" height="136" alt="image"
src="https://github.com/user-attachments/assets/8f8f464c-48e4-42c1-b378-51be2b1fc405"
/>


### After:

<img width="287" height="106" alt="image"
src="https://github.com/user-attachments/assets/30246189-9795-4822-b857-0af524cacb92"
/>
<img width="294" height="180" alt="image"
src="https://github.com/user-attachments/assets/065285ca-ae46-4481-9dd5-00d3bb4fcfb3"
/>
<img width="290" height="182" alt="image"
src="https://github.com/user-attachments/assets/c1b3da39-0785-4d50-8105-c028fa496963"
/>
<img width="213" height="88" alt="image"
src="https://github.com/user-attachments/assets/41e0a84c-2f68-4d24-9923-dd92bb70d161"
/>


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

`rovi.`
2025-12-10 14:51:14 -08:00
Aaron Tidwell ae884cb902 Add New York City Map (#2542)
## Description:

Adds New York City Map.

## Please complete the following:

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

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

tidwell

Screenshots

<img width="1700" height="1081" alt="location-select"
src="https://github.com/user-attachments/assets/06d229c1-f804-4766-bd58-35923c6696bc"
/>
<img width="1705" height="1079" alt="map-bots"
src="https://github.com/user-attachments/assets/16a677d1-da6b-4aca-9ecf-8b0fbb161019"
/>
<img width="1706" height="1082" alt="map-select"
src="https://github.com/user-attachments/assets/8adfd26b-f506-4c72-be05-a1fa638311ab"
/>
<img width="745" height="929" alt="nation-placement"
src="https://github.com/user-attachments/assets/6b5ffd0e-0b2e-4189-b118-bd04c8ac4240"
/>


Misc

Dimensions: 1500 x 1900 px
Total Area: 2,850,000 px²
New Flag Assets: None


[Inspired by this Discord
Thread](https://discord.com/channels/1284581928254701718/1440439003160641667/1440439003160641667)

Some of the water features are adjusted for playability. NYC doesn't
have a ton of elevation differences, so marshland is replicated w/
highland noise. This is roughly placed to match
[Pre-WWI](https://www.geographicus.com/P/AntiqueMap/newyorkcity-usgs-1915),
but allows maintaining the modern silhouette of the area. This 1901 map
is also the main inspiration for composition and projection. For the
Nations, British and Dutch Colonies along with Native Peoples make this
a bit of an amalgamation of the 17th - 20th centuries

Other elevation differences come from [Topographic
Map](https://en-gb.topographic-map.com/map-6sm14/New-York/?center=40.63067%2C-73.89158&zoom=11)

[Tribal Nation Names and
Info](https://en.wikipedia.org/wiki/History_of_Long_Island)
[Additional Tribal
Names/Info](https://libguides.pratt.edu/c.php?g=1088684&p=9380209)

---------

Co-authored-by: Evan <evanpelle@gmail.com>
2025-12-10 12:30:19 -08:00
Henry d4dd9ccd74 UI Improvement: Add rank to stats modal in the lobby for clarity (#2562)
## Description:

This PR adds a rank column to the stats modal on the lobby page.

## 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 (N/A)
- [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:

HardShellTurtle
<img width="2551" height="1258" alt="Screenshot 2025-12-04 232356"
src="https://github.com/user-attachments/assets/26665f3a-f9ee-44b7-a5ba-061c04101997"
/>
2025-12-10 10:33:15 -08:00
Luis Leiva 121e45d5d2 Block UI actions while GameStartingModal is visible (#2587) (#2596)
## Description:
- Original intent was to fix the bug where you could click and start the
next lobby game through the “Game is Starting…” modal, and while
testing, i've found the issue affected all action buttons behind the
modal, not just the lobby join button.
- Added a full-screen overlay that captures pointer events whenever
`GameStartingModal` is visible, preventing any background UI actions
until the start flow completes.

- Screenshot: 
<img width="1918" height="908" alt="image"
src="https://github.com/user-attachments/assets/f6358cb4-1270-4e0b-9f2e-9e57b085ca03"
/>


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

Leivadev
2025-12-10 18:22:07 +00:00
Aaron Tidwell afe072f7d0 Add map-generator --maps flag to process a subset of maps (#2595)
Resolves #2594

## Description:

- Added an optional `--maps` flag to the map-generator that allows
passing a subset of maps to process.
- Updated `README.md` w/ documentation for using the new flag

Used the [go/flag](https://pkg.go.dev/flag) package.

Running without the flag, or with no arguments matches existing behavior
of processing all the maps defined in `main.go`

`go run .`
`go run . --maps=`

New behavior is triggered to process a subset of maps by passing the
`--maps` flag. Multiple maps are defined in a comma-separated list

`go run . --maps=world,africa`

Or a single map (useful for map development)

`go run . --maps=fourislands`

If an invalid map is passed, the process aborts and renders the error

```bash
go run . --maps=invalidmapname
Error generating terrain maps: map "invalidmapname" is not defined
exit status 1
```

By using the default flag package, we get `--help` for free:

```bash
go run . --help
Usage of <path-to-exe>/exe/map-generator:
  -maps string
    	optional comma-separated list of maps to process. ex: --maps=world,eastasia,big_plains
```

I do not write GO often.  Gemini contributed to this syntax.

## Please complete the following:

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

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

tidwell
2025-12-10 10:23:39 -08:00
Aaron Tidwell 2bfe245a72 Add format:map-generator command (#2563)
I'd like to submit some PRs in the future to add additional options for
logging and debugging to the map-generator, however I don't want to
introduce any code style changes in feature requests.

## Description:

I noticed there was not any style guide or formatting being done for the
go files, and went with the simplest built-in approach w/ [go
fmt](https://go.dev/blog/gofmt)

- Adds a `format:map-generator` npm command that will run the default
`go fmt` in the `map-generator` directory to format the go code.
- Runs the formatter and commits the changes to `main.go` and
`map_generator.go`
- Updates the `map-generator` README:
  - Updated location for generated files
  - Updated Links to use markdown links
  - Add `info.json` example
  - Add in-game enabling instructions with list of files to modify
  - Add development tools section with format command

## Please complete the following:

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

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

tidwell
2025-12-09 19:46:13 -08:00
Aotumuri 089d9ab402 Fix: update renderSprites based on user settings in SpriteFactory (#2574)
Resolves #2573
 
## Description:
Fixed an issue where structure icons became smaller after upgrading a
building.
In StructureDrawingUtils.ts, renderSprites was always set to true and
never updated, which caused the code to consistently select the
scaled-down icon. This appears to have been the root cause of the
problem. Since StructureIconsLayer (the caller of StructureDrawingUtils)
updates renderSprites based on settings, I aligned the behavior
accordingly.

```ts
    if (type === "icon") {
      const s =
        scale >= ZOOM_THRESHOLD && !this.renderSprites
          ? Math.max(1, scale / ICON_SCALE_FACTOR_ZOOMED_IN)
          : Math.min(1, scale / ICON_SCALE_FACTOR_ZOOMED_OUT);
      parentContainer.scale.set(s);
    }
```

Here is the video demonstrating the behavior after the fix.
Please see the linked issue for the pre-fix behavior.


https://github.com/user-attachments/assets/24c11a39-667e-49eb-adfe-f0c400d91e54

## 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
2025-12-09 19:43:48 -08:00
Roan e104614a85 Consistent border radius and padding from edge of screen for in game UI (#2576)
## Description:

Moves all the in game ui to have a fixed padding around the edge of the
screen and also makes all the in game ui have the same border radius.


Before:

<img width="569" height="802" alt="image"
src="https://github.com/user-attachments/assets/2d51b66c-26bb-4835-abef-a646565280ba"
/>

<img width="2559" height="1238" alt="image"
src="https://github.com/user-attachments/assets/00723649-bfc7-4e92-bee9-6cff0c2d688c"
/>


After: 

<img width="2559" height="1240" alt="image"
src="https://github.com/user-attachments/assets/8dda98e3-8836-4363-8f33-5b699303ee4f"
/>

<img width="686" height="1122" alt="image"
src="https://github.com/user-attachments/assets/a3820d1c-0579-4b2b-b2a8-7eb790e3ec39"
/>




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

`rovi.`
2025-12-09 19:37:52 -08:00
bibizu 0861bbfad5 Enhance: missile silo shows SAM previews (#2578)
## Description:

Missile silos should also show SAM previews for placement consideration.

## Please complete the following:

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

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

bibizu
2025-12-09 16:26:12 -08:00
VariableVince f0feabfb13 Fix: Filter out in construction buildings for totalunitlevels (#2580)
## Description:

Fix for v28.

After PR #2378 changes, unit type Construction doesn't exist anymore.
Resulting in totalUnitLevels counting in construction buildings towards
total units in TeamStats, old and new Build Menu and Player Info
Overlay. To fix this we now need to filter out the construction phase.

totalUnitLevels is only used for displaying total count purposes, it
doesn't affect other logic.

Before PR 2378 changes:

https://github.com/user-attachments/assets/7748092a-8b7b-41bb-bc68-439ba922b479

After PR 2378 changes:

https://github.com/user-attachments/assets/bc77d7c2-be02-487a-b46a-c02367ae5ad8

After fix in this PR it is back to what is was before:

https://github.com/user-attachments/assets/8d7d14b6-7b6b-4ddb-96d1-17a0a45727f3

## 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
2025-12-09 16:14:25 -08:00
Aotumuri 9f44d990af mls (v4.10) (#2581)
If this PR fixes an issue, link it below. If not, delete these two
lines.
Resolves #(issue number)

## Description:

mls for v27
Version identifier within MLS: v4.10

## 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>
2025-12-09 16:13:29 -08:00
Aotumuri 29a895ab35 Remove unused strings from en.json (#2582)
## Description:

This PR removes several unused strings from en.json.
Leaving unused entries increases Crowdin storage usage and makes
translation management harder, so they should be cleaned up regularly.

The removed strings were originally added in the following PRs but are
not used anywhere in the codebase:
- #2146
- #2060
- #2233

## 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
2025-12-09 16:12:25 -08:00
Ahmet Dedeler 327d425fd5 Fix obvious typos (#2585)
## Summary
- fix obvious spelling typos flagged by codespell across docs, tests,
comments
- no functional changes

## Testing
- pre-commit hooks (eslint/prettier) ran during commit
2025-12-09 16:12:00 -08:00
Ahmet Dedeler 18efa4cd73 Load env vars before server config init (#2586)
## Summary
- load dotenv before constructing the server config so .env values are
available
- avoid misconfigured tunnels/host metadata when env vars were
previously undefined

## Testing
- npm test -- --runInBand
2025-12-09 16:10:53 -08:00
scamiv 5e95ba8da5 Lobby team size (#2591)
## Description:

show team size in lobby

## 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
2025-12-09 16:10:21 -08:00
evanpelle 1d7685a5bf Merge branch 'v27' 2025-12-09 15:39:49 -08:00
evanpelle 73be130916 print and alert cloudflare turnstile error callback 2025-12-09 14:30:32 -08:00
evanpelle 50fe3581cc bugfix: only prefetch turnstile token once to prevent multiple checkboxes v0.27.6 2025-12-09 07:54:22 -08:00
evanpelle afa3e70b62 Check if turnstile is defined v0.27.5 2025-12-08 18:08:23 -08:00
Evan 335a371fdb bugfix: singleplayer not starting (#2589)
#075c232 introduced a bug that prevented singplayer games from starting.

The `updateCallback` was not set for localserver, and local server
didn't send a start message when client sent a "rejoin".

## 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.27.4
2025-12-08 16:42:29 -08:00
Evan 3314ca16ce Turnstile: require token before joining a multiplayer game (#2572)
When user tries to join either a public or private multiplayer game, the
turnstile callback is triggered, and the turnstile token is passed to
the server when joining a game.

## Please complete the following:

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

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

evan
2025-12-08 16:16:31 -08:00
Evan 075c232d8a improve game websockt (re)connection (#2584)
Previously, the connection and reconnection logic were identical in
Worker.ts, so clients would need to be re-authorized for cosmetics etc
even when reconnecting. Now, on reconnect, Worker.ts only does
authentication - verifying the jwt is valid.

This will allow clients to require a valid turnstile token when first
connecting, and not when reconnecting after a broken ws connection.

## 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
2025-12-08 14:07:07 -08:00
Wraith 7658c67662 optimize(RailroadLayer): throttle color scans, cull blits, and remove (#2565)
## Description:

Render optimizations were applied for RailroadLayer: limiting color
updates, skipping off-screen work, drawing only the visible region, and
preventing O(n) ray tile removals.

## Please complete the following:

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

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

wraith4081
2025-12-07 19:35:07 +00:00
bibizu 97e6c1cd77 feat: Nuke Trajectory SAM intercept prediction (#2541)
## Description:

Overhaul to nuke previews:
- Nuke previews now show when they become invulnerable (if
invulnerability setting enabled).
- Nuke previews now show if a SAM defense could intercept it, and where
the intercept occurs.
- SAMs range is now color-coded and outlined to be able to know if
missile will be intercepted by it.

<img width="1326" height="862" alt="image"
src="https://github.com/user-attachments/assets/4cc43a0b-ebac-4707-85bb-4d422f23da28"
/>

Colors/outlines aren't meant to be final, and there are constants to
play around with at the start of both files.

I also kept the naive implementation since the performance cost isn't
too high from my testing and any improvements I can think of are small
and require a bigger rewrite.

## Please complete the following:

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

## Please put your Discord username so you can be contacted if a bug or
regression is found:
bibizu
2025-12-06 11:21:44 -08:00
evanpelle cb4cf091ff update ads v0.27.3 2025-12-05 08:47:48 -08:00
VariableVince 6ca81211ea Alert frame: add to in-game settings, orange for attack instead of red (#2561)
## Description:

The red alert frame for betrayals was added in
https://github.com/openfrontio/OpenFrontIO/pull/1195. It also flashes
red for incoming land attacks since
https://github.com/openfrontio/OpenFrontIO/pull/2358.

The same color for betrayals and attacks leads to confusion. And
possibly red alert fatigue. But when players find themselves fatigued
and want to shut it off for awhile, they can't because the setting
doesn't exist in-game. Also, the setting description on the homepage
settings didn't yet reflect that the alert frame flashes for attacks
too.

This PR fixes this by:

- making the color for land attacks orange. This is well discernable
from red for various colorblindness types, while still looking alarming.
- adding the setting to in-game SettingsModal 
- adding land attack to setting description

Reference to comments on it on Dev Discord:

https://discord.com/channels/1359946986937258015/1381347989464809664/1441232666065240064


https://discord.com/channels/1359946986937258015/1360078040222142564/1434574256704061523

Orange alert frame on being attacked over land:

https://github.com/user-attachments/assets/e0772d62-5b25-4213-a393-dd5af13e8bc9

Settings description change and addition to in-game toggles:
<img width="560" height="160" alt="Added to description what was added
in PR 2358"
src="https://github.com/user-attachments/assets/bc6e2206-b7ac-498d-9009-d2b6e302d3cf"
/>

<img width="665" height="425" alt="In SettingsModal and with attacks
added to description"
src="https://github.com/user-attachments/assets/d489830c-e359-4a5f-8eb4-3caa7d0c21b2"
/>

## 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
2025-12-04 13:26:55 -08:00
VariableVince ec0bf079ef Fix spacing in player team label display (#2560)
## Description:

Add a space after "Your team:"

Before:
<img width="237" height="117" alt="image"
src="https://github.com/user-attachments/assets/60c0821f-a188-44bc-bcd5-e810a741b297"
/>

After:
<img width="243" height="122" alt="image"
src="https://github.com/user-attachments/assets/99b3ff5a-167d-4bae-b8f6-b1b199d4946a"
/>

## 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
2025-12-03 16:37:17 -08:00
VariableVince 8f32746bb2 Special bot names (#2552)
## Description:

Special bot names. If the solution seems convoluted for such an easy
thing, that is because: not all bots find a spawn position, so only
assign a candidate name after finding a spawn. And the first few are
almost always overwritten by Nation spawns so the first 20 just get a
random name. Only then do we assign from the provided lists. For the
random names, some might get the same name but that's not an issue as
no-one will notice and they're off the map quite fast anyway.

## 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
2025-12-03 16:01:05 -08:00
Lavodan 4ff2ca3315 Fix: firefox back button not working (#2557)
## Description:

Fixes an issue on Firefox based browsers, which caused the back button
to not work when in a game.

This was caused because the renderer always appended the canvas to the
document, even when the canvas was already in the document. Chrome
handles this by moving the canvas to the end of the document, whereas
firefox refreshes the whole page. This made it lose important context,
specifically the pushed \#refresh history changes, which caused the back
button to not work properly.

Additionally, Firefox threw out all but the last instance of
history.pushState in certain cases, so using history.replaceState fixes
that issue.

Functionality is preserved for Chrome.

## 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
2025-12-03 15:41:58 -08:00
Lavodan 673b5245c5 fix failing nationNameLength test (#2556)
## Description:

Fixes the failing nationNameLength.test by usinbg the proper absolute
path glob syntax

Also switches to fast-glob because I don't see a reason to not use it.

## 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
2025-12-03 15:40:53 -08:00