- Modified ExclamationMarkIcon.svg to have a transparent background with a white outline and a white exclamation mark inside, providing a clearer alert visual.
## Description:
Made a type of map we don't already have: Small square map, one Island
in each corner. Could be great for boat gameplay or maybe even nuke
wars.
The special thing is: **All islands are exactly 25% of the territory!**
Was a lot of work drawing that in GIMP...
<img width="1164" height="1168" alt="Screenshot 2025-11-20 000839"
src="https://github.com/user-attachments/assets/ad8345c7-562d-49e8-b367-12be9274f3e4"
/>
<img width="1227" height="1222" alt="Screenshot 2025-11-20 000633"
src="https://github.com/user-attachments/assets/f7e2c58a-fcb3-4e07-91f2-aead5f497fad"
/>
<img width="361" height="288" alt="Screenshot 2025-11-20 000655"
src="https://github.com/user-attachments/assets/120f82ef-2d19-497b-8a31-819e30013c89"
/>
<img width="756" height="282" alt="Screenshot 2025-11-20 005949"
src="https://github.com/user-attachments/assets/8ee04da3-d5fa-4ec9-9e99-9e30ebda2b78"
/>
## 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: Evan <evanpelle@gmail.com>
Resolves#1092
## Description:
Added a team preview to the Host Lobby: players listed on the left,
teams on the right in two scrollable columns with color dots matching
in-game colors. Implemented accurate server-parity team assignment
(including clan grouping).
Screenshots:
<img width="817" height="519" alt="Screenshot 2025-11-13 173721"
src="https://github.com/user-attachments/assets/ec646238-7efa-4c8f-9c0a-171b61fd3f20"
/>
<img width="762" height="425" alt="Screenshot 2025-11-13 175400"
src="https://github.com/user-attachments/assets/ebdccb80-4c07-41d5-8f69-3ea983d4b243"
/>
## Please complete the following:
- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
abodcraft1
---------
Co-authored-by: Evan <evanpelle@gmail.com>
Description:
There is a boating exploit where players could repeatedly send and
retreat boats to effectively increase troop regeneration and maintain
almost double the max troop cap. This PR fixes#2388.
Summary
This pr adds a troop penalty to the boat retreats in
src/core/execution/TransportShipExecution.ts of 25 percent (currently
the same as land attacks, but may require fine tuning). this prevents,
to some degree, the ability to stockpile large amounts of troops above
your max cap.
Testing
I tested the change locally and confirmed that the troop penalty is
applied at the correct times and under the correct conditions, i.e. it
is only applied on successful retreat (applying on reteat initiation may
be confusing if you are told you have lost troops if the transport ship
never arrives anyway). The boating exploit is far less effective with
this fix in place.
Notes
- This is a exploit and does not introduce any new features.
- Existing game behavior outside the retreat penalty remains unchanged.
- The attack message is the same as the land attack, so the translation
should already be present.
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
---------
Co-authored-by: Evan <evanpelle@gmail.com>
## Description:
Add dynamic alliance icon with time-based fill and extension request
indicator
- Implement bottom-up green fill on alliance icon proportional to
remaining time
- Use AllianceIconFaded.svg as base layer with green overlay clipped
from top
- Add 20-82.40% clip range to account for icon vertical offset
## 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
<img width="1132" height="631" alt="Screenshot 2025-11-18 205205"
src="https://github.com/user-attachments/assets/4af71ddc-f847-4460-9046-167275efc773"
/>
<img width="1387" height="792" alt="Screenshot 2025-11-18 205532"
src="https://github.com/user-attachments/assets/9dd0e018-323f-4de1-bae8-2633c09fe867"
/>
## Please put your Discord username so you can be contacted if a bug or
regression is found:
hauke4707
---------
Co-authored-by: Evan <evanpelle@gmail.com>
Resolves#2452
## Description:
Created a Clan Stats PR to show top clans. In another PR we can show the
player leaderboard to show top players.
Based on PR from https://github.com/Geekyhobo
<img width="659" height="792" alt="Screenshot 2025-11-19 at 10 00 40 AM"
src="https://github.com/user-attachments/assets/9333b7e2-2357-47a6-a7c8-788cf81e9be3"
/>
## 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
Co-authored-by: Geekyhobo <geekyhobo@users.noreply.github.com>
## Description:
After the v27 playtest, some players experienced instant death on spawn.
The issue was that the human random spawn occasionally coincided with a
bot’s spawn. Previously, bot spawns didn’t account for human spawn
locations and could appear on the same tile, now they don’t.
## Please complete the following:
- [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:
nikolaj_mykola
---------
Co-authored-by: Evan <evanpelle@gmail.com>
Resolves#1686
## Description:
Above or behind the player names on the map, there are icons (images
and/or emojis).
This PR also adds these icons to the PlayerInfoOverlay (on the right
side of the player name).
To share the logic, a new file PlayerIcons.ts has been created.
<img width="215" height="355" alt="Screenshot 2025-11-14 024435"
src="https://github.com/user-attachments/assets/2e581ef9-0330-4c9d-9c52-5f943a58e64b"
/>
<img width="203" height="337" alt="Screenshot 2025-11-14 024731"
src="https://github.com/user-attachments/assets/0c2bf278-b8ca-43c2-b466-ea7a83577b25"
/>
<img width="193" height="288" alt="Screenshot 2025-11-14 024639"
src="https://github.com/user-attachments/assets/be114bc6-f3a8-4b8d-b267-025587c9eafe"
/>
The alliance icon is NOT shown because it's already on the left side of
the alliance timer.
### Why is this change needed?
Sometimes you can't quickly find the nametag of a player on the map.
Especially if a player's territory is scattered around the map, maybe
even on several small islands.
But you still want to know if the player is AFK, has a traitor debuff,
etc.
So it's very useful to get this information by just hovering over a
player instead of needing to search for the floating nametag.
## 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: Evan <evanpelle@gmail.com>
## Description:
See PR https://github.com/openfrontio/OpenFrontIO/pull/2203
It was reverted. This unreverts it, with an added fix for boat troops
not getting returned to owner. And small comment updates. And a const
for boatOwner to re-use.
The added bugfix is check for this.sourceTile === null in the retreat()
function in AttackExecution. A boat attack always sets removeTroops to
false because the troops were already removed from owner troops when the
boat departed. They don't have to be removed again in AttackExecution
init, when the boat lands and the attack starts. But at the end of the
attack, in retreat() in AttackExecution, the starting/boat troops still
need to be returned to the owner. That's why even if removeTroops is
false, when sourceTile is not null (only when it's a boat attack) we add
back the troops to the owner.
## 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: Fx Morin <28154542+FxMorin@users.noreply.github.com>
Co-authored-by: Ryan <7389646+ryanbarlow97@users.noreply.github.com>
If this PR fixes an issue, link it below. If not, delete these two
lines.
Resolves #(issue number)
## Description:
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
If this PR fixes an issue, link it below. If not, delete these two
lines.
Resolves#2447
## Description:
This PR updates the logic used to generate structure fill and border
colors. Currently, (v0.26.16 and earlier), some light territory colors
have structures that are difficult to see and identify. This PR ensures
that all territory colors have structures that are easily visible.
Instead of using `Colord.lighten()` and `Colord.darken()` to generate
structure colors, the logic now:
- queries the territory color and border color of the structure owner
- Converts these colors to the [LAB color
space](https://en.wikipedia.org/wiki/CIELAB_color_space) (which is a
human-perception-uniform color space).
- Darkens the border color (by decreasing LAB luminance) and sometimes
lightens the territory color (by increasing LAB luminance) until a
specific `Color Delta` is achieved (currently `delta > 0.5`)
- This ensures contrast between the structure and the territory
background.
Additionally, this PR re-organizes colors in the `Colors.ts` file for
better visibility and removes redundant colors from the `nationColors`
list.
This PR is an implementation of the proposed mock-up posted on imgur in
issue #2447. Screenshots of the original, final, and side-by-side
comparison of structure colors (for all available player colors) are in
the [imgur
album](https://imgur.com/a/openfront-color-playground-4cxSbbj).
I'd recommend inclusion as a feature/fix for v27.
## 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:
Adds a reusable FrameProfiler utility, and a way to export profiling
data for offline analysis.
### What this PR changes in the existing performance monitor
This PR enhances the performance monitor by:
- **Introducing a reusable `FrameProfiler` utility**
- New `FrameProfiler` singleton in
`src/client/graphics/FrameProfiler.ts`.
- Profiling is only active when the performance overlay is visible
(toggled via user settings), to avoid unnecessary overhead.
- **Per-layer and span-level timing integration**
- `GameRenderer.renderGame` now:
- Clears the profiler at the start of each frame.
- Wraps each `layer.renderLayer?.(this.context)` call with
`FrameProfiler.start()/end()`, keyed by the layer’s constructor name.
- Consumes the recorded timings at the end of the frame and passes them
into `PerformanceOverlay.updateFrameMetrics(frameDuration,
layerDurations)`.
- `TerritoryLayer` instruments key operations:
- `renderTerritory`
- `putImageData`
- Drawing the main canvas
- Drawing the highlight canvas during spawn
- These show up in the performance overlay as additional entries (e.g.
`TerritoryLayer:renderTerritory`).
- **JSON export of performance snapshots**
- `PerformanceOverlay` can now build a full performance snapshot
(`buildPerformanceSnapshot`) containing:
- FPS and frame time stats (current, 60s average, 60s history).
- Tick metrics (avg/max execution and delay, plus raw samples).
- Layer breakdown (EMA-smoothed avg, max, total time per layer/span).
- A new “Copy JSON” button:
- Uses `navigator.clipboard.writeText` when available and falls back to
a hidden `<textarea>` + `document.execCommand("copy")`.
- Provides user feedback via a transient status ("Copy JSON" → "Copied!"
or "Failed to copy").
- **Enable/disable functionality hooked into the UI**
- `FrameProfiler.setEnabled(visible)` is invoked:
- When the overlay visibility is toggled (`init` → `setVisible`).
- When the overlay re-checks visibility in `updateFrameMetrics`, so the
profiler state stays in sync with user settings.
- When disabled, `FrameProfiler` becomes a no-op (returns `0` from
`start`, ignores `record`/`end`, and `consume` returns an empty object),
ensuring minimal overhead when performance monitoring is off.
- **Performance overlay UX and i18n improvements**
- New controls:
- **Reset** button to clear all FPS/tick/layer stats.
- **Copy JSON** button with a tooltip and transient status text.
- Visual enhancements:
- Wider overlay (`min-width: 420px`) and extra padding for readability.
- Layer breakdown section with:
- A list that is now sorted by total accumulated time.
- A horizontal bar per entry, scaled by average cost.
- Avg / max time display per layer/span.
- All new text is routed through `translateText` and backed by
`en.json`:
- `performance_overlay.reset`
- `performance_overlay.copy_json_title`
- `performance_overlay.copy_clipboard`
- `performance_overlay.copied`
- `performance_overlay.failed_copy`
- `performance_overlay.fps`
- `performance_overlay.avg_60s`
- `performance_overlay.frame`
- `performance_overlay.tick_exec`
- `performance_overlay.tick_delay`
- `performance_overlay.layers_header`
---
### How to set up profiling for new functions / code paths
For any function or code block you want to profile during a frame:
```ts
import { FrameProfiler } from "../FrameProfiler";
function heavyOperation() {
const spanStart = FrameProfiler.start();
// ... your existing work ...
FrameProfiler.end("MyFeature:heavyOperation", spanStart);
}
```
Guidelines:
- Use descriptive, stable names:
- Prefix with the component or layer name, e.g.:
- `"TerritoryLayer:prepareTiles"`
- `"GameRenderer:resolveVisibility"`
- `"FooFeature:fetchData"`
- The same name can be called multiple times per frame; the profiler
accumulates the durations in that frame.
- The accumulated values will appear:
- In `layerDurations` consumed at the end of the frame.
- In the overlay “Layers (avg / max, sorted by total time)” section.
- In the exported JSON under `layers` with `avg`, `max`, and `total`.
**3. Record pre-computed durations (optional)**
If you already have a measured duration and just want to attach it:
```ts
FrameProfiler.record("MyFeature:step1", someDurationInMs);
```
- This is equivalent to calling `start`/`end` but with your own timing
logic.
- Again, multiple calls with the same name in one frame will be summed.
---
<img width="466" height="823" alt="image"
src="https://github.com/user-attachments/assets/354b249a-25eb-4c3f-bd2e-9906372f761b"
/>
## 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
- [ ] 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
---------
Co-authored-by: Evan <evanpelle@gmail.com>
## Description:
I haven't been able to play openfront for a while now, so today I took
some time to fix the performance issue.
It turns out its `backdrop-filter: blur(5px);` being used on a
background element, causing the entire website to re-paint on nearly
every change.
This causes the game to run at 8 fps on my computer, with chrome
reporting 700ms of INP presentation delay.
The solution here was simply to pre-blur the background image.
<details>
<summary>Here's the instructions on how to pre-blur exactly like it
currently does</summary>
Install sharp
`npm install sharp`
Run blur
```ts
sharp(`./resources/images/EuropeBackground.webp`)
.blur(5)
.toFile(`./resources/images/EuropeBackgroundBlurred.webp`);
```
This could be automated if you plan to do more backgrounds.
</details>
The surprising part is that I'm running a A5000 with a Ryzen 9 5950X. So
I usually never lag from anything, which is what made this kinda
interesting. I assume the issue is caused by my 4K display or Kubuntu.
## Video:
This video showcases the 700+ms of delay on the main menu buttons. Video
is in real-time.
https://github.com/user-attachments/assets/ad5ff509-6bc7-48ff-8cba-85409be774f0
## 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
<details>
<summary>Discord Username</summary>
fx.morin
</details>
Simplify the login flow.
## 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#2431
## Description:
Adds a button in the pattern menu to hide non owned skins
<img width="1264" height="976" alt="image"
src="https://github.com/user-attachments/assets/70a27c99-82f2-4414-b218-59deed723177"
/>
## 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:
notifxy (1379678982676676639)
## Description:
This PR is intended to increase singleplayer fun.
This is a follow-up to my previous PR #2161, which made the
"Hiding-Strategy on small islands" harder.
But its still possible. You can easily warship-infest the map and get
rich from the trade, even though you are playing on impossible
difficulty.
Also you can easily hinder the nations to, for example, get from the
left to the right side of the world map. So you are always in full
control of the game.
This PR makes nations send a warship if their troop transport boat got
destroyed. The warship will travel to the location where the boat got
destroyed.
Because the nations send more boats now (previous PR), this actual has
an impact and there is more action on the map now :)
The chance of retaliation is based on the game difficulty.
### COMPARISON
[Youtube Video](https://www.youtube.com/watch?v=F4_iP54LGNU) of me
playing the infestation-strat without this PR.
[Youtube Video](https://www.youtube.com/watch?v=VHesXJwPtcA) of me
playing the infestation-strat with this PR (Its sill possible but not
that easy, I gave up lol).
## 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
Resolves#2096
## Description:
(TO CLEARIFY THEIRS NO GRACE PERIOD ADDED, AS THAT ISSUE THAT WOULD OF
NEEDED IT WAS FIXED BEFORE ON ITS OWN)
Shows the amount left in the UI for the player who trigged it
<img width="374" height="80" alt="image"
src="https://github.com/user-attachments/assets/f269c015-5a78-4e85-a9c0-cdf039d93d2a"
/>
also the betryal icon, after 15 seconds starts a slow flash, then after
10 seconds it speeds up, and then at 5 seconds it quickly flashs.
this was a nice way to show the time left without adding any new ui
componets.
video link 36 seconds (https://streamable.com/cwzxch)
## 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:
notifxy (1379678982676676639)
## Description:
Finishes & closes#1969 and closes#1806.
## 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>
## Description: Fix Emoji Panel Hidden Behind Player Info Panel
According to : https://github.com/openfrontio/OpenFrontIO/issues/2367
After my previous Player Info Panel layout fix, the Emoji Panel was
accidentally rendered behind it (see
[comment](https://github.com/openfrontio/OpenFrontIO/pull/2410#issuecomment-3507266463)).
This PR updates EmojiTable.ts to ensure the Emoji Panel displays
correctly in front of the Player Info Panel.
Changes:
Increased z-index values for the Emoji backdrop, content, and close
button above z-[10001].
backdrop: z-[10002]
content: z-[10003]
close button: z-[10004]
Expected outcome:
The Emoji picker (backdrop, content, and close button) now correctly
appears above the Player Panel.
<img width="1325" height="857" alt="Ekran Resmi 2025-11-09 09 42 38"
src="https://github.com/user-attachments/assets/08f81d88-70be-4690-b13f-01f09766df04"
/>
- [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 : bilgehandk
## Description:
Describe the PR.
Added a new chat message from the server once player wants to renew the
alliance, to the other player.
## Please complete the following:
- [x] I have added screenshots for all UI updates
<img width="572" height="256" alt="image"
src="https://github.com/user-attachments/assets/7feec21f-fff5-4544-8992-caf99c45913d"
/>
- [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
notifxy (1379678982676676639)
## Description:
This adds moving warships by tapping them on a touchscreen. Now you can
steer them just like you already could with a mouse.
Also has some earlier returns, doing checks only when needed, prevent as
much duplicate checks and a bugfix.
In onMouseUp:
- early return if no OceanTile. Before, function findWarshipsNearCell
would still go look for warships even if ocean wasn't clicked.
- Move const nearbyWarShips down. It isn't needed when this.selectedUnit
is true.
- Remove unnecessary const clickedWarship.
- Move getting clickRef from function findWarshipsNearCell into
onMouseUp. Because it is needed in case of this.selectedUnit too, within
onMouseUp.
Getting a valid clickRef for this.selectedUnit fixes: Runtime error when
clicking outside the map after selecting a warship. The isValidCoord/Ref
check was missing for this.selectedUnit.
For findWarshipsNearCell:
- moved the cell/tile checks out to onMouseUp, the only caller of the
function.
- did NOT rename findWarshipsNearCell. Although it now uses tileRef as
input. Renaming can cause merge issues so i only do this when needed.
Added onTouch:
- Tests if we need to look for warships to select/move or if we can open
Radial Menu.
- Prevent as much duplicated checks as possible. So if no there's no
Ocean Tile found, just send the radial menu event, which checks
isValidCoord anyway. isOceanTile itself works fine even if it's no valid
cell (proven by this.selectedUnit working all this time in onMouseUp
without an isValidCoord test).
Screencap on mobile, shows selecting and moving warships, no runtime
error when clicking outside the map after selecting a warship, while
radial menu still opens as normal:
https://github.com/user-attachments/assets/1300d557-ae2f-46e3-92bd-d434c523aae7
## 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: Fixes a usability issue where the Player Info Panel and
Emoji Table overflowed the viewport on smaller screens, hiding key
controls (like Stop Trade) behind the Build Bar/Menu. Makes these panels
responsive and scrollable with minimal, low-risk CSS changes.
According to : https://github.com/openfrontio/OpenFrontIO/issues/2367
<img width="1120" height="774" alt="Ekran Resmi 2025-11-07 23 06 01"
src="https://github.com/user-attachments/assets/6fe23c23-ab5b-4254-8872-9880c322e164"
/>
Changes:
- Increased overlay z-index from 1001 to 10001 to ensure it renders
above Build Menu.
- Replaced static layout with scrollable inner container:
- Applied `max-height: calc(100vh - 120px -
env(safe-area-inset-bottom))`
- Enabled scrolling with `overflow: auto` and
`-webkit-overflow-scrolling: touch`
- Added sticky header with close (✕) button for persistent visibility
during scroll.
- Removed unused `init()` method for cleanup.
Discord: bilgehandk
## Description:
Following discussion on discord, some people (including me) thought it
would be nice to show the changelog whenever there is a new version, as
people seemed not to be aware of the gameplay change
https://github.com/user-attachments/assets/00b9531d-ea7a-4e69-8a01-64ef3b39536b
## 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
Added some basic fixes:
- Add backdrop overlay with outside-click-to-close
- Reduce emoji button sizes to fit all emojis without scrolling
- Update styling to match player info panel theme
## Description:
I updated the emoji panel such as reducing the size so it fits on the
screen without scrolling for emojis, and ability to close the panel by
clicking outside of it. Previously you couldn't close the panel by
clicking outside of it, and this was inconsistent with the rest of the
UI. I also updated the styling to match the panel before that (the
player info panel).
## Please complete the following:
- [x] I have added screenshots for all UI updates
- [ ] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [ ] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
insane.p
<img width="1237" height="874" alt="image"
src="https://github.com/user-attachments/assets/5c0bd229-0f9b-489d-bc34-a4a70021b78d"
/>
---------
Co-authored-by: Evan <evanpelle@gmail.com>
## Description:
Added prominent red alert notifications for incoming land attacks,
reusing the existing betrayal alert mechanism. Players will now receive
visual feedback when they are being attacked, improving awareness of
incoming threats.
Addressing #2355
## Please complete the following:
- [x] I have added screenshots for all UI updates
> <img width="2559" height="1436" alt="image"
src="https://github.com/user-attachments/assets/cd69a58d-764f-4910-8006-a143685a771a"
/>
- [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:
kerverse
## Description:
Some stats are missing from the recorded game stats:
- Unit upgrade
- Gold from trade and from steal
The gold from trade/steal was introduced with [PR
784](https://github.com/openfrontio/OpenFrontIO/pull/784) but was
quickly reverted with [PR
927](https://github.com/openfrontio/OpenFrontIO/pull/927), probably
involuntarily.
## 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:
Resolves#2257
Before:
<img width="644" height="380" alt="Screenshot 2025-11-06 at 21 36 50"
src="https://github.com/user-attachments/assets/f2502d17-ef22-4b2e-ab10-22c3b8fc9efc"
/>
After:
<img width="644" height="380" alt="Screenshot 2025-11-06 at 21 36 40"
src="https://github.com/user-attachments/assets/25efe3a2-632f-4a4f-941a-2305705380d5"
/>
## 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
## Description:
Two bugs where causing 403s when trying to connect to a game after
refreshing the jwt:
1. __isLoggedIn was not cleared, so the existing, cached, token was
used.
2. set "credentials: "include" in the refresh request so we get the
token as a cookie. getToken() checks cookie before checking "token" in
localstorage. So cookie wasn't being updated and we were using the
existing cookie.
## 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:
Implements SAM range extension for stacked SAMs to cover hydros as
requested in #2347 and many times from users in discord.
This implementation is as simple as possible: At level 5 and higher,
SAMs extend their range to the range of a hydrogen bomb + 10 for a small
safety margin. Levels 2-4 are interpolated between.
Screenshot to show the sizes compared to a hydro:
<img width="400" alt="image"
src="https://github.com/user-attachments/assets/a857d66c-e3d4-467f-855f-3539cc90b719"
/>
Everything works together with the new range UI, although I might need
to unify with / rebase on #2350. Not yet tested with #2348, but
shouldn't be an issue.
## Input needed:
- Should I add tests for this?
- This is in effect a massive buff to SAMs, might be too strong. Popular
ideas / suggestions from Discord to balance things:
- Cap the SAM upgrade level at the maximum range (easy to do)
- Alternative, instead of capping the level, decrease the range when
missiles are reloading
- Increase the cost scaling for SAMs per stack, and scale way higher
(e.g. 1.5M > 3M > 4.5M > 6M or something like that) (UI integration
unclear, breaks with existing cost logic)
- Decrease SAM hit probability for Hydros
I'm happy to implement any of these paths, or just roll with the simple
way it's set up now, just let me know.
## 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:
newyearnewphil
---------
Co-authored-by: Evan <evanpelle@gmail.com>
## Description:
Implements trajectory preview for nuke selection as requested in #2346.
When selecting an AtomBomb or HydrogenBomb, a dashed line preview now
shows the trajectory path from the launch silo to the target location
before launching. Line uses player's territory color with 70% opacity
and dashed pattern for clear visibility
## Please complete the following:
- [x] I have added screenshots for all UI updates
<img width="716" height="483" alt="image"
src="https://github.com/user-attachments/assets/4c263230-34ba-4e56-9502-4a59c84b5943"
/>
<img width="1199" height="965" alt="image"
src="https://github.com/user-attachments/assets/72eda758-e192-45a0-b01d-5a8f413a07d5"
/>
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file (No new text strings added)
- [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:
kerverse
---------
Co-authored-by: Evan <evanpelle@gmail.com>
## Description:
Enhanced the performance overlay to display additional tick-related
performance metrics. The overlay now shows:
1. **Tick Execution Duration** - Average and maximum time (in
milliseconds) it takes to execute a game tick
2. **Tick Delay** - Average and maximum time (in milliseconds) between
receiving tick updates from the server
The server sends 10 updates per second (100ms interval), so these
metrics help identify:
- Client-side performance bottlenecks (tick execution duration)
- Network latency issues (tick delay)
**Additional improvements:**
- Renamed `FPSDisplay` component to `PerformanceOverlay` to better
reflect its expanded purpose
- Updated method names (`updateFPS` → `updateFrameMetrics`) and CSS
classes for consistency
All metrics are tracked over the last 60 ticks, providing rolling
averages and maximum values for performance analysis.
## Please complete the following:
- [x] I have added screenshots for all UI updates:
- <img width="495" height="227" alt="image"
src="https://github.com/user-attachments/assets/142b0313-61bf-46cc-b595-61fe73f6b54c"
/>
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- Translation keys already exist in en.json for
"performance_overlay_label" and "performance_overlay_desc"
- [x] I have added relevant tests to the test directory
- All existing tests pass (309/310 tests passed)
- No new tests added as this is primarily a display enhancement
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
- Tested locally with npm test
- Verified performance overlay displays all metrics correctly
- Confirmed tick metrics are calculated and displayed accurately
## Please put your Discord username so you can be contacted if a bug or
regression is found:
Discord: kerverse
---------
Co-authored-by: Evan <evanpelle@gmail.com>
Before, the condition was "if it's not singleplayer", but replays are
counted as singleplayer game for some reason (will need to fix the
underlying issue) so it wasn't robust enough Now the condition is based
on are we in replay or not,.
## Description:
Related to issue https://github.com/openfrontio/OpenFrontIO/issues/2357
I cannot get to replay games locally for some reason (client just throws
an error that it cannot load the lobby), so I made sure that the
singleplayer text did not change (at least no regression) cf screenshot:
<img width="1920" height="963" alt="Screenshot 2025-11-02 at 17 46 57"
src="https://github.com/user-attachments/assets/27e055a8-3813-46bd-a8ae-0c463a94d1a8"
/>
## 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
## Description:
Adds a win modal for OFM and the main discord. Adds needed translation
keys and an OFM picture back to the resources file
## 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:
Iamlewis
---------
Co-authored-by: evanpelle <evanpelle@gmail.com>
## Description:
Adds a win modal for OFM and the main discord. Adds needed translation
keys and an OFM picture back to the resources file
## 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:
Iamlewis
---------
Co-authored-by: evanpelle <evanpelle@gmail.com>