- Introduced new metrics in ClientGameRunner to track worker simulation ticks and render tick calls per second.
- Updated TickMetricsEvent to include these new metrics.
- Enhanced PerformanceOverlay to display worker and render ticks per second, improving performance monitoring capabilities.
- Adjusted minimum FPS in GameRenderer
- Refactor rendering and metrics emission in ClientGameRunner to ensure updates occur only after all processing is complete
- Throttle renderGame() based on the current backlog
## 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:
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>
## Description:
1. Remove SpawnAds and replace it with AdTimer which will delete the
in-game ad after the first minute.
2. remove login blocker UI, we don't use it anymore
3. convert TerritoryPatternsModal & GutterAds to use event based when
checking for flares
4. remove window.PageOS.session.newPageView(); because it was throwing
an exception
5. Convert SpawnTimer to a lit element to give it a higher z-index to
stay above the header ad
## 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:
Put ads on the left and right gutters
## 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:
When zoomed out the tracks don't alias well and makes the map too busy.
## 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:
Make the unit display bar a proper unit build bar
Add shortcuts for all structures and units
Add ranges for ranged structures and units
Changed the shortcuts to use the key instead of the code for
internationalization purposes

<img width="285" height="517" alt="image"
src="https://github.com/user-attachments/assets/91bb01e6-e48c-4255-ace1-306af9cdc25b"
/>
## Please complete the following:
- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
Mr.Box
---------
Co-authored-by: evanpelle <evanpelle@gmail.com>
Co-authored-by: icslucas <carolinacarazolli@gmail.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
## Description:
Fix a minor typo in a TODO comment inside `GameRenderer.ts`.
No code behavior was changed.
## Please complete the following:
- [ ] I have added screenshots for all UI updates
- [ ] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [ ] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
GOC
## Description:
The issue raised describes context.restore using too much CPU. This PR
changes the layer order to reduce the number of context.restore and
context.save calls.
The order plays a role because every time a layer has to swap between
using transform (triggered by a layer's shouldTransform function
returning true) and not, it has to call context.save/context.restore.
This change simply reorders the layers so all layers which need
transform are grouped together at the start, and those who don't are at
the end.
Regarding testing, initially my plan was to add unit tests as this is an
easy thing to overlook. But the current testing setup doesn't play
nicely with pixijs, litjs, and a few others. I didn't want to make large
changes to the testing setup here, so instead I left a comment to remind
anyone making changes to pay attention to the order.
Fixes#1894
## 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:
Bornasm
## Description:
Allow the main menu modals to be closed by clicking the Escape key. The
manner by which this change achieves this is by adding a
connectedCallback to add a keydown EventListener, which closes the modal
on clicking Escape.
Relevant issue: #1586
My earlier PR was only for the in-game modals, as they can access the
Event Bus and receive the CloseViewEvent.
https://github.com/openfrontio/OpenFrontIO/pull/1604
As mentioned, this PR differs in that it does not use the Event Bus
because these are not in-game modals. The main menu modals do not have
access to the event bus.
Affected modals for this PR.
- UserSettingModal.ts
- TerritoryPatternsModal.ts
- SingePlayerModal.ts
- NewsModal.ts
- LanguageModal.ts
- JoinPrivateLobbyModal.ts
- HostLobbyModal.ts
- HelpModal.ts
- FlatInput.ts
## 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
- [x] I have read and accepted the CLA agreement (only required once).
## Please put your Discord username so you can be contacted if a bug or
regression is found:
slyty
---------
Co-authored-by: Antoine <antoine.gannat@gmail.com>
## Description:
This PR introduces handling for the canvas `contextlost` and
`contextrestored` events to make the game's rendering more robust.
Previously, if the graphics context was lost (which can happen due to
browser memory management, GPU driver resets, etc.), the render loop
would continue to run, but most drawing operations would silently fail.
This resulted in a broken visual state where terrain, structures, and
other graphics would disappear, leading to what players have referred to
as the "black screen bug".
These changes implement the following:
1. In `GameRenderer`, event listeners are added to the main canvas.
2. On `contextlost`, the `requestAnimationFrame` loop is cancelled,
pausing rendering.
3. On `contextrestored`, a full redraw of all layers is triggered, and
the render loop is restarted, allowing the game to gracefully recover.
Additionally, a related bug in the `StructureLayer` is fixed. During a
redraw/restoration, the layer could attempt to render unit icons to its
canvas before the images were fully (re)decoded. The `init` method now
explicitly waits for all icon images to be decoded before drawing them,
ensuring the layer is restored correctly.
**Important Note:** This PR represents a partial fix for the context
loss issue. Specifically, the `StructureIconsLayer` remains in a broken
state after context restoration. This layer is rendered using Pixi.js,
which has its own specific process for handling renderer recovery. Due
to my lack of experience with the Pixi.js API, I was unable to implement
the fix for this layer. This would be an excellent follow-up
contribution for someone familiar with Pixi.
## 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
- [X] I have read and accepted the CLA agreement (only required once).
## Please put your Discord username so you can be contacted if a bug or
regression is found:
aaa4xu
## Description:
Enforce minimum test coverage.
## 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
- [ ] I have read and accepted the CLA agreement (only required once).
## Description:
Display an FPS monitor to track performance on each new feature.
It only appears in the development environment, positioned at the top
center to remain visible—especially on mobile.
The display can be closed via a close button.
I already use it to evaluate my other PR on low end device.
<img width="1126" height="845" alt="image"
src="https://github.com/user-attachments/assets/a7197572-6aea-47df-9dd2-e84947c7aee0"
/>
## 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
- [x] I have read and accepted the CLA aggreement (only required once).
## Please put your Discord username so you can be contacted if a bug or
regression is found:
devalnor
## Description:
Allows ChatModal, EmojiTable, PlayerPanel and RadialMenu to accept the
CloseViewEvent, thereby enabling the modals/menus/tables to be closed by
clicking the Escape key.
As described in #1586, there are a number of modals that cannot be
closed by pressing Escape, such as ChatModal, EmojiTable, PlayerPanel
and RadialMenu, while other modals can already, such as the CTRL + Click
build menu.
## 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
- [x] I have read and accepted the CLA agreement (only required once).
## Please put your Discord username so you can be contacted if a bug or
regression is found:
slyty
## Description:
Improve existing alternate view (space bar).
It now displays territories in different colours based on their status
(enemy, allied, or your own).
Hovering over a territory highlights it. I tested several approaches,
and this one delivers excellent performance (on mobile too).


## Please complete the following:
- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors
Related issue:
https://github.com/openfrontio/OpenFrontIO/issues/900https://github.com/openfrontio/OpenFrontIO/issues/484
## Please put your Discord username so you can be contacted if a bug or
regression is found:
devalnor
## Description:
Add a close button for the Emoji table, and switch the modal to
TailWind.
<img width="698" height="1161" alt="image"
src="https://github.com/user-attachments/assets/45c998d8-e584-4d83-9177-036679828586"
/>
https://github.com/user-attachments/assets/999baf1b-1cdb-409c-a1f0-12d8298dc638
## 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
- [x] I have read and accepted the CLA aggreement (only required once).
## Please put your Discord username so you can be contacted if a bug or
regression is found:
IngloriousTom
## Description:
Reverting control panel back to v23. Once we remove the worker/troop bar
we can revisit moving it to back to the top.
## 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
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors
## Please put your Discord username so you can be contacted if a bug or
regression is found:
evan
## Description:
The settings has grown to the point where it deserves its own modal.
<img width="1144" alt="Screenshot 2025-07-07 at 3 55 23 PM"
src="https://github.com/user-attachments/assets/a1527d79-93c3-4bf3-ba67-dce643bc81ea"
/>
NOTE: styling is still needed.
## 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
- [ ] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
- [ ] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors
## Please put your Discord username so you can be contacted if a bug or
regression is found:
evan
## Description:
Add triangle shape for missile silos, square for sam, octagon for
defense posts, and add a filter in the topbar to highlight structures


## 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
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors
## Please put your Discord username so you can be contacted if a bug or
regression is found:
Vivacious Box
## Description:
This PR reverts 0b79d0be16
The unit menu adds additionally complexity, and can be unintentionally
opened on mobile when trying to build a unit.
Unit upgrades will be handled automatically:
https://github.com/openfrontio/OpenFrontIO/commit/513fcb094418f0e9405e878396bd5b3db8b34e5a
## 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
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors
## Please put your Discord username so you can be contacted if a bug or
regression is found:
evan
## Description:
When building a structure in the same location as a nearby structure, it
will update the existing structure instead of creating a new one.
Also fix ctrl+click shortcut to bring up the build menu.
## 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
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors
## Please put your Discord username so you can be contacted if a bug or
regression is found:
evan
## Description:
Top Bar Refactor – UI & UX Improvement Proposal
This update overhauls the top game bar to improve clarity,
responsiveness, and overall user experience across desktop and mobile.
It consolidates player resources (e.g., building counts), integrates
game controls (pause, settings, time), and enhances visual contrast.
Key changes:
Redesigned top bar with player data and game options.
Team color indicator bar (team games only).
Countdown bar during "Choose Starting Position" phase.
Removed redundant info (e.g., troop/worker counts shown elsewhere).
Inspired by strategy games like Travian Legends, this refactor offers a
cleaner and more intuitive layout, especially for smaller screens.
⚠️ Note: This is a large change and likely contains visual or functional
bugs I can’t currently spot due to fatigue. Thorough testing is required
before approval.
## 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
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors
## Please put your Discord username so you can be contacted if a bug or
regression is found:
Diessel

om/user-attachments/assets/3a0edbef-e621-4fc4-b6b7-c1ed

8f9a8219)

Closes#1165
---------
Co-authored-by: Scott Anderson <scottanderson@users.noreply.github.com>
Co-authored-by: evanpelle <evanpelle@gmail.com>
## Description:
Add a new pixi layer for rendering structure icons
Add new sprites for structures

## 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
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors
## Please put your Discord username so you can be contacted if a bug or
regression is found:
Vivacious Box
---------
Co-authored-by: evanpelle <evanpelle@gmail.com>
## Description:
Display OFM25 ad in WinModal 50% of the time.

## 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
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors
## Description:
With the alert frame, we're notified and can view the event using a
“Focus” button that moves the map to the traitor, or dismiss it with a
“Dismiss” button. The alert auto-dismisses after a few seconds.
**Because this feature provides an advantage, the trade-off is having to
wait a full 10 seconds or manually clicking “Dismiss” to close it.**
- Show a red alert frame animation when the player is betrayed.
- ~~The alert frame can be dismissed manually.~~
- The alert frame is automatically dismissed after ~~10~~ 3 seconds.
- If the user doesn’t want to see it at all, they can disable it in the
settings.




## 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
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors
## Please put your Discord username so you can be contacted if a bug or
regression is found:
This is my first PR let me know if anything needs improvement!
devalnor
## Description:
This is meant to give players more customization options.
Permission handling hasn’t really been implemented yet.
## 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
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors
## Please put your Discord username so you can be contacted if a bug or
regression is found:
aotumuri
## Description:
Add a rail network to handle train stations/railroad between structures.
Changes:
- `RailNetwork` is responsible for the train station graph. Use it to
connect new `TrainStations`
- A `RailRoad` connects two `TrainStation`
- No loop possible in the rail network
- Train stations handles its railroads
- Added a layer to draw the railroads under the structures
#### Clusters
- To speed up computations, each `TrainStation` references its own
cluster
- A cluster is a list of `TrainStation` connected with each other,
created by the `RailNetwork` when connecting the station
- Train stations spawn trains randomly depending on its current cluster
size
- A `TrainStation` decides randomly of the train destination by picking
one from the cluster
#### Production building:
- Added a factory which has no gameplay impact currently. _To be
discussed._
#### Train stops:
- When a train reaches a factory, it's filled with a "cargo". The loaded
trains has no impact currently. _To be discussed._
- When a train reaches a city, the player earn 10k gold
- When a train reaches a port, it sends a new tradeship if possible
- If a destination/source is destroyed, the train & railroad are deleted
too
https://github.com/user-attachments/assets/42375c17-9e04-4a42-98d0-708c81ffd609https://github.com/user-attachments/assets/fbecdb53-a516-4df8-87fb-1f9a62c4efa0
## 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
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors
## Please put your Discord username so you can be contacted if a bug or
regression is found:
IngloriousTom
---------
Co-authored-by: Scott Anderson <scottanderson@users.noreply.github.com>
## Description:
Refactor & clean up the Radial menu.
* Only show certain build menu items, depending on whether or not you
clicked on your own territory
* show items as greyed out instead of just the disabled icon
* remove back button on hover trigger
## 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
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors
## Please put your Discord username so you can be contacted if a bug or
regression is found:
evan
## Description:
Adds a bottom rail add during the spawn phase if player has played over
5 games.
Also only show the death screen ad if player has played a couple of
games.
This keeps the experience ad-free for the first few games.
<img width="1003" alt="74fb6676-273d-4b58-9fcb-50ec438c4e27"
src="https://github.com/user-attachments/assets/fedca20f-7b31-4a06-be57-bde5bd0118f0"
/>
## 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
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors
## Please put your Discord username so you can be contacted if a bug or
regression is found:
evan
---------
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
## Description:
Show the gutter ads only when the win/lose modal is active.
Describe the PR.
<img width="1899" alt="Screenshot 2025-06-18 at 1 14 36 PM"
src="https://github.com/user-attachments/assets/86b20d48-6b07-4058-8dff-8447cf565e02"
/>
## 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
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors
## Please put your Discord username so you can be contacted if a bug or
regression is found:
DISCORD_USERNAME
evan
## Description:
Add ads on the left and right gutters on homepage, one small in game add
above the control panel.
## 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
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors
## Please put your Discord username so you can be contacted if a bug or
regression is found:
evan
<img width="1710" alt="Screenshot 2025-06-17 at 10 06 02 AM"
src="https://github.com/user-attachments/assets/1f8d0114-be2b-4fb4-90e2-86d1c5119b04"
/>
<img width="368" alt="Screenshot 2025-06-17 at 10 06 32 AM"
src="https://github.com/user-attachments/assets/8b56f92a-a9c9-47e1-8d85-23d8c4dbf773"
/>
![Uploading Screenshot 2025-06-17 at 10.07.38 AM.png…]()
## Description:
This PR update the leaderboard and team stats component to be more
responsive on mobile and desktop.
Include new component gameLeftISidebar that manages showing/hiding
elements.
Add icons as components for easy use
## 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
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors
## Please put your Discord username so you can be contacted if a bug or
regression is found:
Diessel
Closes#1163
Images:




## Description:
PR for https://github.com/openfrontio/OpenFrontIO/issues/1105
This pull request introduces a new replay-panel under options-menu to
control singleplayer and replay speed.

User can select 4 different speed multipliers based on the
turnIntervalMs config.
I locally tested the feature in singleplayer mode. I couldn't find a way
to test replay mode.
Tested with the pause button, working as you would expect.
Here is an example:
[replay-speed.webm](https://github.com/user-attachments/assets/7b3a7616-5f8f-4fbb-88ba-0b2414c6f2ea)
## 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
⚠️ I need help to test this feature in real conditions with a replayed
game in dev env.
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors
## Please put your Discord username so you can be contacted if a bug or
regression is found:
ghisloufou
---------
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: evanpelle <evanpelle@gmail.com>
## Description:
- Adds logic to hard-set the transform handler directly to a new
position, without a movement animation
- Implements #1004



- removed a second initialization of the TransformHandler to prevent
transformation desyncs between layers. Incidentally this probably fixes
#62
## 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
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors
## Please put your Discord username so you can be contacted if a bug or
regression is found:
demonessica
---------
Co-authored-by: tnhnblgl <51187395+tnhnblgl@users.noreply.github.com>
## Description:
Changed from consolex to console
## 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
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors
## Please put your Discord username so you can be contacted if a bug or
regression is found:
@qqkedsi
## Description:
Tiles are only run through putImageData() if they are currently viewed
by the player.
This significantly (usually between 20-80%) reduces the computation time
of putImageData() on large maps.
## Please complete the following:
- [x] I have added screenshots for all UI updates
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors
## Please put your Discord username so you can be contacted if a bug or
regression is found:
1brucben
---------
Co-authored-by: evanpelle <evanpelle@gmail.com>
## Description:
GameView provides a `myPlayer()` implementation.
## 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
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors
## Description:
My first game, I was embarrassingly confused about the spawn phase. I
looked for where my nation spawned for something like 3 minutes before I
realized I needed to actually click a location at the beginning.
Therefore, my first contribution is to add a simple UI message during
the spawn phase that will hopefully prevent anyone else from making the
same mistake.
I have implemented this as an overlay layer that displays at the top and
center of the screen during spawn phase.
## UI Screenshots
Spawn phase message

## Please complete the following:
- [x] I have added screenshots for all UI updates
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors
## Please put your Discord username so you can be contacted if a bug or
regression is found:
spicydll
## Description:
We are adding a modal to display information about a unit.

In the future, this modal will likely include buttons for upgrading or
dismantling the unit.
## Please complete the following:
- [x] I have added screenshots for all UI updates
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors
## Please put your Discord username so you can be contacted if a bug or
regression is found:
aotumuri