## Description:
This PR readds the Yenisei map, with it being about 3 times smaller than
before. I haven't updated the en.json file, as it still has the string
for the map, which was probably forgotten when the map got removed from
the repo.
## 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:
Adds a "Play Again" requeue button to the victory/defeat modal for
Ranked 1v1 games. When clicked, it navigates the player back to the
homepage and automatically opens the matchmaking modal to queue for
another ranked match.
Changes:
- WinModal.ts: Added isRankedGame state, purple "Play Again" button
(only shown for ranked 1v1), and _handleRequeue() method
- Main.ts: Added ?requeue URL parameter handling to trigger matchmaking
modal on page load
- en.json: Added "requeue": "Play Again" translation string
- added tests to WinModal.test.ts
Note: temporarily set isRanked flag to true to get the modal to pop in a
solo match on dev server and confirmed that ?requeue URL parameter
called _handleRequeue() correctly, which opened the sign in process
since actually signing in and queuing for a ranked match isn't possible
on dev server.
<img width="771" height="364" alt="play-again"
src="https://github.com/user-attachments/assets/6e3f5a02-f1ae-465a-9b28-656126c11d3d"
/>
## 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:
skigim
## Description:
Like Atom and H-bombs, MIRV warheads should still land after the
launching player died. PlayerExecution already makes sure to skip nukes
when deleting a dead player's units. But MIRVexecution separate()
creates NukeExecutions which check canBuild, which returns false for a
dead player.
Fix: Skip alive and cost check for MIRV warheads. canBuild is only
applicable when creating the MIRV itself, not at the seperation stage
mid-flight. There's no cost involved either.
Note: this bug has been there since MIRVs were added to the game. But
the bug wasn't noticed often in all that time. Still the fix may have
some impact on gameplay.
## 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: Ryan <7389646+ryanbarlow97@users.noreply.github.com>
## Description:
Changes the leaderboard + / - buttons to follow the styling of other
buttons.
Suggested by @FloPinguin
## 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
***
Screenshots:
Example with previous (above) and new style (below):
<img width="539" height="186" alt="image"
src="https://github.com/user-attachments/assets/896e3fba-4dfb-4e12-a6bf-f2c363faf485"
/>
Example with previous (above) and new style (below) with onhover effect:
<img width="555" height="307" alt="image"
src="https://github.com/user-attachments/assets/b76aaa80-2839-4e6c-b244-9af6ce569a9a"
/>
##Discord username: martoi
***
Signed-off-by: MartinIvovIv <https://github.com/martinIvovIv>
## Description:
This PR resolves issue #3058 where the "win modal" incorrectly
displayed a **"Keep Playing"** button instead of **"Spectate"** when a
player's team won but the player themselves was already dead.
### The Problem
In WinModal.ts, the button text logic only checked `this.isWin`
(whether the team won) but didn't verify if the player was still alive.
This caused dead players on winning teams to see "Keep Playing"
instead of "Spectate".
### The Solution
Updated the button rendering logic in
`src/client/graphics/layers/WinModal.ts:82` to check both the win
condition AND the player's alive status:
```typescript
// Before
${this.isWin
? translateText("win_modal.keep")
: translateText("win_modal.spectate")}
// After
${this.isWin && this.game.myPlayer()?.isAlive()
? translateText("win_modal.keep")
: translateText("win_modal.spectate")}
```
This approach maintains clean separation of concerns:
- this.isWin continues to represent whether the player's team won
(true/false)
- The button text logic now checks both team victory and player alive
status
- This ensures the correct button appears based on the player's actual
state
Behavior After Fix
- Alive players on the winning team → "Keep Playing"
- Dead players on the winning team → "Spectate"
- Any player on the losing team → "Spectate"
Testing Performed
1. Code Audit: Verified myPlayer().isAlive() correctly reflects the
eliminated state in Teams mode.
2. Build Verification: Ran npm run build and npm run build-prod to
ensure no regressions in the UI layer.
3. Type Safety: Ran tsc --noEmit to confirm the fix is fully compliant
with the project's TypeScript strictness.
---
Closes#3058
## 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:
ghadi8097
---------
Co-authored-by: iamlewis <lewismmmm@gmail.com>
## Description:
Train spawning hot-path optimization (trade destination selection)
## Summary
This PR reduces per-tick overhead in train spawning by removing
temporary allocations and reducing work in the
destination-selection path.
The change focuses on `Cluster` trade destination lookup and how
`TrainStationExecution` picks a destination.
## What changed
### 1) Maintain a “trade-capable” station subset per cluster
`src/core/game/TrainStation.ts`
- `Cluster` now maintains:
- `stations`: all stations in the cluster (unchanged)
- `tradeStations`: maintained subset of stations that can act as trade
endpoints (`City` or `Port`)
- `tradeStations` is kept in sync in:
- `addStation()`
- `removeStation()`
- `clear()`
Impact:
- Trade queries no longer scan every station in the cluster; they only
scan `tradeStations`.
### 2) Add cheap eligibility helpers
`src/core/game/TrainStation.ts`
- `hasAnyTradeDestination(player)`:
- Fast early-exit check: returns as soon as it finds any eligible trade
destination.
- `randomTradeDestination(player, random)`:
- Picks a random eligible trade destination directly without
materializing an intermediate `Set`.
### 3) Use reservoir sampling for single-pass random choice
`src/core/game/TrainStation.ts`
`Cluster.randomTradeDestination()` uses reservoir sampling:
- Iterates `tradeStations` once.
- Maintains a running count of eligible stations (`eligibleSeen`).
- Replaces the selected station with probability `1/eligibleSeen`.
Properties:
- Uniform selection among eligible stations.
- One pass instead of “count then pick by index” (two pass).
- Allocation-free.
- Returns `null` when no eligible destination exists.
### 4) Update train spawning to avoid temporary sets
`src/core/execution/TrainStationExecution.ts`
- Previously: `spawnTrain()` called `cluster.availableForTrade()` and
then `random.randFromSet(...)`.
- This built a new `Set` on the hot path.
- Now:
- Early-exit via `cluster.hasAnyTradeDestination(owner)`.
- Destination via `cluster.randomTradeDestination(owner, random)`.
Net effect:
- Less per-tick work and no per-spawn temporary `Set` allocations.
## Why this helps
Train spawning happens frequently and can become a hot path in large
games / large rail clusters.
Avoiding repeated allocations and reducing work inside `tick()` helps
keep frame/update time predictable.
## notes
- Trade rules are unchanged (`tradeAvailable(player)` still gates
eligibility).
- Destination selection remains random-uniform over eligible
`City`/`Port` stations that satisfy `tradeAvailable(player)`.
- `TrainStationExecution` now avoids calling `spawnTrain()` entirely
when `spawnTrains` is falsy (it was already guarded inside).
## 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
- [ ] 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
If this PR fixes an issue, link it below. If not, delete these two
lines.
Resolves#3126
## Description:
update & move reached_limit check
## Please complete the following:
- [X] I have added screenshots for all UI updates
- [X] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [X] I have added relevant tests to the test directory
- [X] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
wraith4081
---------
Co-authored-by: Ryan <7389646+ryanbarlow97@users.noreply.github.com>
## Description:
This PR reduces server/client tick CPU spent on territory cluster
maintenance by:
- Cutting redundant work in `PlayerExecution.removeClusters()`
(largest-cluster bounding box reuse, fewer allocations in
`isSurrounded()` and `removeCluster()`).
- Making `calculateBoundingBox()` allocation-free per tile by switching
from `gm.cell(tile)` to `gm.x(tile)`/`gm.y(tile)` (it now only allocates
the two result `Cell`s, instead of 1 per tile).
## Commits
- `51de0a1b` core: reduce PlayerExecution cluster overhead
- `6d9d85c5` core: avoid Cell allocations in PlayerExecution
isSurrounded
- `346f6a8c` core(util): speed up calculateBoundingBox by avoiding Cell
allocations
## Notes
- This PR is intended to be behavior-preserving; changes are limited to
hot-path micro-optimizations.
- Follow-up opportunity: `calculateClusters`/flood-fill is now the top
hotspot; further wins likely come from reducing traversal work or
caching.
## 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
- [ ] 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
## Description
Optimize border-tile maintenance in `GameImpl` to reduce per-conquest
overhead.
Border tiles are updated whenever ownership changes; this PR trims
allocations and avoids unnecessary iteration in the hot path.
## Changes
- `src/core/game/GameImpl.ts`
- `updateBorders(tile)` no longer allocates an array of tiles; it
updates the changed tile and its 4-neighbors directly via
`forEachNeighbor`.
- `calcIsBorder(tile)` no longer calls `neighbors(tile)` / loops an
array; it checks the four cardinal neighbors via `x/y` bounds and
`ownerID`.
## Affected Functions
- `GameImpl.updateBorders(tile: TileRef)`
- `GameImpl.calcIsBorder(tile: TileRef): boolean`
- Call sites impacted by behavior/perf:
- `GameImpl.conquer(owner, tile)`
- `GameImpl.relinquish(tile)`
## 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
- [ ] 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
## Description:
Reduce FX layer rendering cost by:
- Updating the offscreen FX buffer only when needed (and clearing it
once when FX ends).
- Drawing only the visible portion of the FX buffer to the main canvas
(viewport culling).
- Reusing `TransformHandler.screenBoundingRect()` as the single source
of truth for viewport bounds.
-
## Changes
- `FxLayer`:
- Track buffered frames and skip work when there are no active FX.
- Use `performance.now()` for refresh timing.
- Draw only the visible map rect (clamp + small pad) instead of blitting
the full map-sized FX canvas.
- Compute the visible rect via `TransformHandler.screenBoundingRect()`.
- `GameRenderer`:
- Thread `TransformHandler` into `FxLayer` construction.
## 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
- [ ] 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
## Description:
Maybe for v29.
In the 5M starting gold modifier games you can conquer a inactive player
(spawned but didn't do anything) and get their 5M gold.
Huge unfair advantage.
I think that even without the starting gold modifier you should not get
the gold of inactive players because its unfair.
I identify inactive players (spawned but didn't do anything) by checking
the attack stats.
I added a translation for the displayMessage "Conquered {name}, received
{gold} gold". Why was that not translated?
I added a new message "Conquered {name} (Inactive player, received no
gold)".
## Please complete the following:
- [X] I have added screenshots for all UI updates
- [X] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [X] I have added relevant tests to the test directory
- [X] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
FloPinguin
---------
Co-authored-by: Ryan <7389646+ryanbarlow97@users.noreply.github.com>
## Description:
Added source for join context
## 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:
Explanation of the bot farming strategy in the discord:
https://discord.com/channels/1359946986937258015/1359949371956789289/1460928540575928478
"the result is that a player can build unlimited factories for 125 000
gold discount, trade with themselves with each train being worth 50 000
gold. First the 25 000 for neutral trade and then another 25 000 when
the bot is harvested."
"If you have a minute and ally people around you it should be trivial to
get 10 of both cities and factories for 1.25mil"
It's debatable if we want to let people do that (close this PR) or see
it as an abusive mechanic.
Here is the fix, bots try to delete all structures now. You can simply
retake them to stop the deletion:
https://github.com/user-attachments/assets/ac1ca846-50bd-42fa-8e25-5ac25a6d627e
## Please complete the following:
- [X] I have added screenshots for all UI updates
- [X] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [X] I have added relevant tests to the test directory
- [X] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
FloPinguin
Co-authored-by: Ryan <7389646+ryanbarlow97@users.noreply.github.com>
## Description:
It is possible to hit your teammates while throwing a nuke onto water or
enemies.
This PR blocks the nuking entirely if you would hit a teammates
structure. Because they are valuable.
Feature requested by Wonder :)
https://github.com/user-attachments/assets/448a3444-cc3d-4e76-acaf-595decab1634
## Please complete the following:
- [X] I have added screenshots for all UI updates
- [X] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [X] I have added relevant tests to the test directory
- [X] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
FloPinguin
---------
Co-authored-by: Ryan <7389646+ryanbarlow97@users.noreply.github.com>
## Description:
Currently only the master process sends public lobby updates to clients.
This is not scalable since it could overload the master process.
In this PR, the master uses IPC to send public lobby info to all
workers. Then clients connect to a random worker to get public lobby
updates via websocket. This way clients never connect directly to the
master websocket.
The flow looks like this:
Every 100ms:
1. Master schedules a public game on a random worker if new games are
needed
2. Master broadcasts public lobby info to all workers (all public games
& num clients connected to each game)
3. Each worker responds to that update with the number of clients
connected to its own public games
4. Master then updates its public lobby state so it knows how many
clients are connected to each public 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
If this PR fixes an issue, link it below. If not, delete these two
lines.
Resolves #(issue number)
## Description:
add import, somehow missing??
## 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:
- Add getClientIDForGame function to Auth.ts that generates and stores a
consistent clientID per gameID using sessionStorage
- Update HostLobbyModal to use getClientIDForGame for lobby creation
- Update Matchmaking to use getClientIDForGame when joining games
- Update PublicLobby to use getClientIDForGame when joining lobbies
This enables reconnection support by ensuring the same clientID is used
when rejoining a game session.
## Please complete the following:
- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
w.o.n
---------
Co-authored-by: Evan <evanpelle@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
## Description:
Prevents translated button text from overflowing its container by
constraining layout and clipping excess content.
before
<img width="234" height="133" alt="スクリーンショット 2026-02-04 6 46 35"
src="https://github.com/user-attachments/assets/2cfe4f3e-ac5c-42d0-8175-76ca53fa3b1b"
/>
after
<img width="189" height="135" alt="スクリーンショット 2026-02-04 6 46 46"
src="https://github.com/user-attachments/assets/e2fd2439-6cd3-4831-86b2-28a374bc7ba4"
/>
## 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:
fix: validate base username length separately from clan tag)
## 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:
Hide the host badge when joining public lobbies
before
<img width="802" height="635" alt="スクリーンショット 2026-02-03 21 45 45"
src="https://github.com/user-attachments/assets/2b8bd5a0-3023-4bd3-9042-1bbd0649e499"
/>
after
<img width="668" height="702" alt="スクリーンショット 2026-02-03 21 44 00"
src="https://github.com/user-attachments/assets/65eb9b66-99b0-46ce-a786-55974a443010"
/>
## 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:
Flag selector country names no longer truncate with ellipses; they wrap
normally for readability.
before
<img width="561" height="182" alt="スクリーンショット 2026-02-03 22 21 01"
src="https://github.com/user-attachments/assets/965ab93e-e10f-42a0-8771-84f042c31e22"
/>
after
<img width="582" height="217" alt="スクリーンショット 2026-02-03 22 21 11"
src="https://github.com/user-attachments/assets/9c6aa840-5af7-46a7-9f54-58d78e021304"
/>
## Please complete the following:
- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
aotumuri
Co-authored-by: Ryan <7389646+ryanbarlow97@users.noreply.github.com>
## Description:
Aligned the LeaderboardModal background styling with other modals (e.g.,
HelpModal). Uses the same inline background/blur/border treatment to
improve visual consistency.
before
leaderboard
<img width="848" height="657" alt="スクリーンショット 2026-02-03 22 07 58"
src="https://github.com/user-attachments/assets/b31c0754-00e0-4248-9e2d-97869df99acb"
/>
other
<img width="921" height="686" alt="スクリーンショット 2026-02-03 22 08 07"
src="https://github.com/user-attachments/assets/e84ab4e0-64b1-490f-8d93-d745f4eabbbb"
/>
after
leaderboard
<img width="852" height="650" alt="スクリーンショット 2026-02-03 22 08 20"
src="https://github.com/user-attachments/assets/6f4a4073-4d6e-4ca8-8ef1-fb08240a5e6b"
/>
other
<img width="857" height="685" alt="スクリーンショット 2026-02-03 22 08 35"
src="https://github.com/user-attachments/assets/367607f7-f665-4e1e-9c34-4566d2b68570"
/>
## 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:
Join Lobby Modal will show:
Crowded modifier
Enabled
## Please complete the following:
- [X] I have added screenshots for all UI updates
- [X] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [X] I have added relevant tests to the test directory
- [X] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
FloPinguin
## Description:
Replaced the src/client/JoinPrivateLobbyModal.ts with a new
src/client/JoinLobbyModal.ts which handles both public + private
lobbies.
<img width="771" height="714" alt="image"
src="https://github.com/user-attachments/assets/7ac55d91-3f0c-4f99-b960-cea9e617538d"
/>
also made a "connecting" to the lobby
<img width="772" height="708" alt="image"
src="https://github.com/user-attachments/assets/a2812462-c5f4-459a-b63a-49d93bb2a6a2"
/>
It also needed to be updated to address the issue with the modal using
both polling + websockets
## 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
Relates to #2260
## Description:
Redo the control panel to be more mobile friendly and take up less space
![Uploading Screenshot 2026-02-02 at 8.09.13 PM.png…]()
<img width="584" height="236" alt="Screenshot 2026-02-02 at 8 09 34 PM"
src="https://github.com/user-attachments/assets/d48906d5-3653-499c-9b08-b661d5e7d4a4"
/>
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:
evan
related to #2260
## Description:
* Moves the player info panel from the right to the top of the screen
* Disable the header ad for now because it would cover up the player
info, we'll find a better place for it in the future
* Remove the collapsable button/functionality. It's hard to even click
the button because the panel disappears when you move away from a
player, and I think the info is too valuable to ever need to be
collapsed.
* Removed the "land" and "irradiated land" since it didn't add much
value
* Remove all alt text & translation, you can't hover over the player
overlay so it's irrelevant.
* put troop info inside the troop bar to reduce amount of text
<img width="479" height="88" alt="Screenshot 2026-02-01 at 8 57 33 PM"
src="https://github.com/user-attachments/assets/3b72eb16-2efa-4c00-a4d0-5e085548fa78"
/>
<img width="438" height="136" alt="Screenshot 2026-02-01 at 8 58 06 PM"
src="https://github.com/user-attachments/assets/285bb2c9-6deb-4ee8-bcc8-743cccd6b77e"
/>
## 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:
Currently, when you send an alliance request to another player and it
gets rejected, but the same player sends you an alliance request back
during your alliance request cooldown, you cannot accept it via the
radial menu, you need to do that via the notification on the bottom
right.
This is not consistent with when you receive an alliance request outside
of the cooldown.
This PR checks for incoming alliance request for the same player before
checking the outgoing request cooldown, therefore allowing you to accept
incoming alliance requests via the radial menu button even during
cooldown.
## Please complete the following:
- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
deshack_82603
## Description:
- Add warning for custom games (you won't get achievements)
- Remove medal display for maps without nations (Baikal nuke wars)
<img width="813" height="572" alt="image"
src="https://github.com/user-attachments/assets/fb80a160-a175-4a24-8706-ddaa07d0bde5"
/>
<img width="720" height="555" alt="Screenshot 2026-02-01 162436"
src="https://github.com/user-attachments/assets/d4c28d71-364c-4255-8ecc-31703a5659bf"
/>
## Please complete the following:
- [X] I have added screenshots for all UI updates
- [X] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [X] I have added relevant tests to the test directory
- [X] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
FloPinguin
## Description:
- Maybe greet nearby players with a 👋 emoji in the earlygame (make
nations feel a little bit more lively)
- Destroying a transport ship / capturing a trade ship of a nation now
updates the relation (mainly on higher difficulties)
- On hard difficulty: Only lift embargos if we have a friendly relation.
On impossible difficulty: Don't lift embargos
- Improve totalPlayers calculation and return value of
`hasTooManyAlliances` in `NationAllianceBehavior`
## Please complete the following:
- [X] I have added screenshots for all UI updates
- [X] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [X] I have added relevant tests to the test directory
- [X] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
FloPinguin
If this PR fixes an issue, link it below. If not, delete these two
lines.
Resolves #(issue number)
## Description:
@wraith4081 's pr
updates the stats modal to show both 1v1 and clan stats
## Please complete the following:
- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
w.o.n
---------
Co-authored-by: Wraith <54374743+wraith4081@users.noreply.github.com>
Co-authored-by: iamlewis <lewismmmm@gmail.com>
## Description:
Renamed ad files because adblockers blocked them because of their name.
When ES modules fail to import, the entire application breaks.
## Please complete the following:
- [X] I have added screenshots for all UI updates
- [X] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [X] I have added relevant tests to the test directory
- [X] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
FloPinguin
## Description:
- Move betrayal button to the boat-sending-button-location (you can't
send boats to allies) to prevent missclicks
- Remove betrayal confirmation
<img width="260" height="248" alt="image"
src="https://github.com/user-attachments/assets/0a25fc9c-c8a0-4ba9-a8c8-971d6a7a0511"
/>
## Please complete the following:
- [X] I have added screenshots for all UI updates
- [X] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [X] I have added relevant tests to the test directory
- [X] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
FloPinguin
## Description:
- Move betrayal button to the boat-sending-button-location (you can't
send boats to allies) to prevent missclicks
- Remove betrayal confirmation
<img width="260" height="248" alt="image"
src="https://github.com/user-attachments/assets/0a25fc9c-c8a0-4ba9-a8c8-971d6a7a0511"
/>
## Please complete the following:
- [X] I have added screenshots for all UI updates
- [X] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [X] I have added relevant tests to the test directory
- [X] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
FloPinguin
## Description:
Ads a small video on the bottom left of the screen during spawn phase.
## Please complete the following:
- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
evan
## Description:
Creates an embedded Playwire video ad with status callbacks
## Please complete the following:
- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
evan
Resolves#2820
## Description:
Add colored borders to the `chat-option-button` corresponding to each
players territory color.
<img width="630" height="565" alt="Image"
src="https://github.com/user-attachments/assets/91a99230-0581-4d83-a470-9a02ba43c045"
/>
## Please complete the following:
- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
denelduck
---------
Co-authored-by: VariableVince <24507472+VariableVince@users.noreply.github.com>
## Description:
There were several issues with the matchmaking modal:
1. It was defined twice (once before login, and once after login), so
players would sometimes join the matchmaking queue twice.
2. When clicking away from the modal (not clicking the back button), the
"onClose" callback was not triggered. So if a person closed & reopened
the modal, they would join twice'
3. Cache the userMe response so it can be called multiple times
## Please complete the following:
- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
evan
## Description:
Hash the pattern + is for sale and store it in local storage. then check
if the new cosmetics hash is different from the one we last saw. If it's
different, add a glowing red dot on the store. After user clicks it,
then update the hash and remove the dot.
<img width="1030" height="143" alt="Screenshot 2026-01-29 at 3 54 46 PM"
src="https://github.com/user-attachments/assets/e5727764-40e4-45e1-b651-65816e657067"
/>
## Please complete the following:
- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
evan
## Description:
https://www.reddit.com/r/Openfront/comments/1qquvdg/difficulty_scaling_in_single_player/
People seem to feel that easy is not easy enough, even after the various
nerfs in multiple places.
So let's touch DefaultConfig.
## Please complete the following:
- [X] I have added screenshots for all UI updates
- [X] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [X] I have added relevant tests to the test directory
- [X] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
FloPinguin
## Description:
https://www.reddit.com/r/Openfront/comments/1qquvdg/difficulty_scaling_in_single_player/
People seem to feel that easy is not easy enough, even after the various
nerfs in multiple places.
So let's touch DefaultConfig.
## Please complete the following:
- [X] I have added screenshots for all UI updates
- [X] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [X] I have added relevant tests to the test directory
- [X] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
FloPinguin
<img width="1670" height="200" alt="banner"
src="https://github.com/user-attachments/assets/b6561231-71dc-46dd-a521-453d4e97931f"
/>
## Description:
This proposal adds a new, completely flat map called "The Box," where
players will find themselves on a completely flat landmass and will only
be able to trade by land using trains and factories.
- Map size: 2048×2048 pixels
- Binaries generated with MapGenerator (map.bin, map4x.bin, map16x.bin)
- Integrated into arcade category and multiplayer playlist
- English and Spanish translations added
- 13 nations/bots with unique and thematic names:
> - **Middle Defender (located in the center)**
> - **King of the Corner (located in the top-left corner)**
> - Suspicious Ally
> - Punch Merchant
> - Nuke Thrower
> - Fullsender
> - Factory Builder
> - Front Manager
> - Box Fighter
> - Cage Liberator
> - Train Trader
> - Non-peaceful Bot
> - **Evan The Dev** (special mention)
All other bots are distributed to cover the map evenly.
<img width="838" height="835" alt="Screenshot 2026-01-28 at 17 39 45"
src="https://github.com/user-attachments/assets/4665088d-cb94-4db3-8602-8a22b63bfee2"
/>
## Please complete the following:
- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
sardidefcon