Commit Graph

872 Commits

Author SHA1 Message Date
Abdallah Bahrawi 09a1cf885f Add red warning circle when nuke would break alliance (#2728)
## Description:

When placing a nuke (Atom Bomb or Hydrogen Bomb), the range circle now
turns red to warn players when the attack would break an alliance.

<img width="456" height="333" alt="Screenshot 2025-12-28 211927"
src="https://github.com/user-attachments/assets/dfe6f874-3f8b-4662-8877-0af30aa20139"
/>


## 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: iamlewis <lewismmmm@gmail.com>
2025-12-30 17:55:15 +00:00
Evan 4f3d9df46a vite: fix docker build (#2738)
## Description:

The sync-assets wasn't executing on docker-build. so instead just import
it from resources/ directory, vite logs a warning but I think that's
okay for now.

## Please complete the following:

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

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

evan
2025-12-29 18:37:51 -08:00
Ryan f1561df470 Bomb Direction (#2435)
Resolves #2434 

## Description:

Allows bomb direction to be inverted by pressing a hotkey - currently
"U".

**Check the issue for screenshots / videos.**

## 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: iamlewis <lewismmmm@gmail.com>
2025-12-29 09:03:46 -08:00
Wraith 26f5d40819 build: migrate build system to Vite and test runner to Vitest & Remove depracated husky usage (#2703)
- Replace Webpack with Vite for faster client bundling and HMR.
- Migrate tests from Jest to Vitest and update configuration.
- Update Web Worker instantiation to standard ESM syntax.
- Implement Env utility in `src/core` for safe, hybrid environment
variable access (Vite vs Node).
- Refactor configuration loaders to remove direct `process.env`
dependencies in shared code.
- Update TypeScript environment definitions and project scripts for the
new toolchain.
- Remove the [depracated usage of the
husky](https://github.com/typicode/husky/releases/tag/v9.0.1).

## Description:

migrate build system to Vite and test runner to Vitest & Remove
depracated husky usage

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

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

wraith4081

---------

Co-authored-by: evanpelle <evanpelle@gmail.com>
2025-12-28 22:10:26 -08:00
Achim Marius 5a065d71c5 Fix alliance renewal popup not being removed when alliance is broken (#2722)
Resolves #2464

## Description

This PR fixes a bug where the alliance renewal popup remained visible
after an alliance was broken or betrayed.
The issue occurred because renewal UI events were tied to player
identifiers instead of the unique allianceId.
When a player had multiple alliances, breaking one alliance did not
correctly remove the associated renewal popup.
This change ensures that renewal popups are correctly removed only for
the specific alliance that was broken.


### What was wrong
Alliance renewal UI events were previously associated implicitly with
players.
This caused incorrect behavior when a player had **multiple alliances**,
because **players are not unique identifiers of an alliance**.

As a result, breaking one alliance could leave stale renewal popups
visible.

### What was changed
- Alliance break logic now relies on **allianceId**, not player IDs
- Renewal popups are removed **only for the specific broken alliance**
- Alliances involving the same player but different allianceIds are
unaffected
- Added tests to ensure this bug cannot reappear

### Result
- Renewal popup disappears immediately when an alliance is
betrayed/broken
- No unintended removal of other alliance renewal popups
- Correct behavior even when a player is involved in multiple alliances

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

assessin.
2025-12-28 13:35:05 -08:00
bijx 7284ded290 Feat: Quick donate troops via radial menu (#2708)
If this PR fixes an issue, link it below. If not, delete these two
lines.
Resolves #2705 

## Description:

Introduces a quick donation feature in games where the `canDonateTroops`
option is enabled. It works by converting the center button in the
radial menu from a disabled attack button to a troop donate button when
the player right clicked on is friendly (teammate or ally).

Also adds donate gold button to Attack slot on radial menu when right
clicking friendly troops.

### Video Example


https://github.com/user-attachments/assets/d9b2c3f7-b6c0-482a-9dbd-b3841676cbe5

### New Icon
<img width="1310" height="931" alt="image"
src="https://github.com/user-attachments/assets/85225858-6971-470d-92f6-db68a5d05bb2"
/>

### Donate Gold


https://github.com/user-attachments/assets/b116bc06-d53d-47c7-9504-871eada6a21e


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

bijx
2025-12-27 13:05:02 -08:00
YoussfeCantCode 7339c968c9 uniformed HeadsUpMessage text (#2710)
## Description:

Moves pause-related translation keys from their own object into
```heads_up_message``` to keep all heads-up message text in one place.

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

furo18
2025-12-27 11:52:11 -08:00
YoussfeCantCode 1c52d20e83 Added pause functionality for private multiplayer games (#2657)
If this PR fixes an issue, link it below. If not, delete these two
lines.
Resolves #2491

## Description:
Adds pause/unpause functionality for private multiplayer games. Only the
lobby creator can pause the game, and all players see a pause overlay
when the game is paused.

  **Key features:**
- Lobby creator sees pause/play button in control panel (alongside
existing singleplayer/replay controls)
  - Server validates that only lobby creator can toggle pause
  - All players see "Game paused by Lobby Creator" overlay when paused
  - Game state freezes (no turn execution) while paused
  - Unpause resumes normal gameplay

  **Implementation details:**
- Server-side pause state (`isPaused`) prevents turn execution during
pause
- Each client receives `isLobbyCreator` flag in `GameStartInfo` to
show/hide pause button
- Added `TogglePauseIntent` that broadcasts to all clients via
`NoOpExecution`
  - New `PauseOverlay` component (shows in single player also)

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

furo18

<img width="1459" height="861" alt="Screenshot 2025-12-20 at 15 16 33"
src="https://github.com/user-attachments/assets/f5a3222f-f54b-473c-b0f6-104ce4c1e7a8"
/>
2025-12-26 10:21:18 -08:00
scamiv 7f3ca3c97e Update GameRenderer to disable alpha channel in GameRenderer 2D context (#2699)
## Description:

Updated the main onscreen canvas context to opaque: 
Impact: avoids alpha compositing for the main canvas (we already paint a
full opaque background each frame), which can slightly reduce GPU work.

## 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
2025-12-26 10:11:05 -08:00
scamiv 6ce6e16837 make TerrainLayer opaque (alpha:false) (#2700)
## Description:

Make the terrain backing canvas explicitly opaque by requesting a 2D
context with alpha: false.
Remove confusing latent alpha support in TerrainLayer

Current themes always generate opaque terrain colors, but the code
previously looked like it supported per-tile alpha (via
terrainColor.rgba.a), which is misleading.
Being explicit about opacity can avoid unnecessary alpha compositing
work and clarifies intent.

No visual change expected with current themes (terrain was already
effectively opaque).

## 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
2025-12-26 10:09:57 -08:00
evanpelle fcabf49a74 Merge branch 'v28' 2025-12-25 12:49:12 -08:00
Evan a810e0ad34 crazy games integrations (#2675)
## Description:

Integrate with crazy games SDK

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

evan
2025-12-23 09:11:00 -08:00
DevelopingTom 3612667bcd Improve SAM Radius layer rendering and performances (#2667)
## Description:

This PR updates the SAM radius layer to render sharply at all zoom
levels instead of pixelated.


![cleam_sam](https://github.com/user-attachments/assets/9e1a23e1-ea47-428f-a3a5-635874b3029c)

The radius is now drawn using primitives directly on the parent
rendering context, rather than via an intermediary canvas and
`drawImage`.

### Performance improvement:

Since the radius computation is quite heavy, it could lead to bad
performances previously because radii were recomputed and redrawn on
every frame.
With 1k SAM:

<img width="559" height="33" alt="image"
src="https://github.com/user-attachments/assets/207e4fca-2b30-4a32-a69b-be3aacc3d7cf"
/>


This PR separates radius computation from rendering:
- radius values are now recomputed only on the first frame after a SAM
changes.
- subsequent frames reuse the cached results and only handle rendering.

Now with 1k SAM:

<img width="624" height="67" alt="image"
src="https://github.com/user-attachments/assets/9facdf04-1dc2-4908-8ebc-fd80933f0232"
/>



## 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
2025-12-21 14:59:38 -08:00
bijx 4ee3319397 Feat: Added cursor price option to user and basic settings (#2655)
## Description:

Following the hotkey cursor price textbox addition of #2650, this
feature adds the option to enable and disable the visual feature via the
User Settings menu or the Basic Settings modal in game. Also added a
[new icon](https://thenounproject.com/icon/pay-per-click-2586454/) for
the Basic Settings modal from the Noun Project and added credit for it
to the `CREDITS.md` file.

### Video Demo


https://github.com/user-attachments/assets/1667081e-45e3-4b11-9bda-3f00c341e03c

### User Settings Menu
<img width="1029" height="1436" alt="image"
src="https://github.com/user-attachments/assets/e4e6bf6d-db59-463a-81fb-f622ef6e3931"
/>

### Basic Settings Menu
<img width="964" height="1545" alt="image"
src="https://github.com/user-attachments/assets/6b083655-b96e-4937-95d6-f3458858f03d"
/>



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

bijx
2025-12-20 11:09:44 -08:00
bijx 4e8aa1f066 Feat: Add cost to ghost structure icon when using keyboard shortcuts (#2650)
## Description:

Introduces a dynamic textbox under the cursor and populates it with
price when a keyboard hotkey is pressed. Prices update correctly based
on current value of the structure or strike being purchased, even if the
value is 0 (during `Infinite Gold` mode). Price value updates live even
if the price box is currently being shown (for example, when voluntarily
removing a structure causes the price to change. See video below).

### Video Demo 


https://github.com/user-attachments/assets/3f974268-c14b-4129-9629-5a0f7db8b30c


The more in depth demo was too big for GitHub, but I uploaded it on the
Discord

https://discord.com/channels/1284581928254701718/1447907175522504704/1451483322260914297

### Live price updates on tooltip


https://github.com/user-attachments/assets/0d98739c-6f24-4fcd-a047-cc304e7e86aa

### Works with `Infinite Gold` mode


https://github.com/user-attachments/assets/25bd2919-77cd-4735-8c3f-043306f53b8f




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

bijx
2025-12-19 19:06:21 -08:00
Mateusz Żołdak b63744834d fix: area right from control-panel is clickable (#2640)
If this PR fixes an issue, link it below. If not, delete these two
lines.
Resolves #[2638](https://github.com/openfrontio/OpenFrontIO/issues/2638)

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

Not on discord yet, but this bug makes me crazy. :)

Edit:
Also, I wasn't sure from which branch to start from.
2025-12-18 16:21:27 -08:00
FloPinguin 4d5bb7a835 Cleanup nations (Part 1) 🧹 (#2637)
## Description:

1. Using the wording `"Nation"`, `"FakeHuman"` and `"NPC"` at the same
time is confusing.
So I renamed every mention of `"FakeHuman"` and `"NPC"` in the entire
project to `"Nation"`. Just like they are called ingame.

2. `BotBehavior.ts` was originally intended for sharing the logic
between nations and bots.
But at the moment, the logic there isn't really shared and it's
basically just about attacking.
So I renamed `BotBehavior.ts` to `AiAttackBehavior.ts`. I use "Ai" to
indicate that this file is used by bots AND nations.

3. Moved `execuction/utils/AllianceBehavior.ts` to
`execuction/nation/NationAllianceBehavior.ts` to make sure everybody
understands that this file is not about alliances in general. It's just
about nations and how they handle alliances.

4. Removed `difficultyModifier` from `DefaultConfig`. It's unused and I
think we usually want to finetune the difficulty instead of using that
method.

5. Added `assertNever` in all `switch (difficulty)` default cases.

## Please complete the following:

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

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

FloPinguin
2025-12-18 16:20:23 -08:00
evanpelle f4ed2a932f remove ofm advert in winmodal 2025-12-18 11:06:28 -08:00
evanpelle 85bfdbc066 reduce in-game ad frequency 2025-12-18 08:12:35 -08:00
bijx c9f00a5eb8 feat: Factory Railway Tracks become more visible in Alternate View (#2626)
## Description:

Adds network bright green highlighting to Railway tracks connecting
_your_ factories and buildings together when in the alternate view
(spacebar view). It is sometimes hard to see your own tracks on certain
areas of the map (mountain terrains for example), so this change will
highlight the tracks the same color as your border outline in the
alternate view (#00FF00). Also suggested by [this
comment](https://discord.com/channels/1284581928254701718/1445984695752855562/1445984695752855562)
in the Discord.

### Normal Railway Connection
<img width="1009" height="872" alt="image"
src="https://github.com/user-attachments/assets/31c028a8-13d8-4d82-ba4a-385b8372c9ac"
/>

### Alternative View (spacebar)
<img width="1124" height="956" alt="image"
src="https://github.com/user-attachments/assets/f4f3bb38-7233-4f2c-9bbf-a407196b0124"
/>

### Other nation colors remain unchanged
<img width="1566" height="1447" alt="image"
src="https://github.com/user-attachments/assets/c4dde970-20f1-480b-959d-876d4eb0f32b"
/>


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

bijx
2025-12-17 19:46:32 -08:00
evanpelle 2a294d93df have events display retaliate button send counter troops based on the attack ratio 2025-12-17 12:35:58 -08:00
FloPinguin 8b9bed0e0b Hotfix: Max troops instead of troops for team stats 📊 (#2631)
## Description:

Missing i18n key because I forgot to add maxTroops to the team
leaderboard...
I completely forgot that troops are also shown on the team leaderboard

Before:

<img width="905" height="309" alt="Screenshot 2025-12-17 022043"
src="https://github.com/user-attachments/assets/c2f95c0b-86a5-4447-bbfc-1925d70005f6"
/>

After:

<img width="778" height="309" alt="Screenshot 2025-12-17 025028"
src="https://github.com/user-attachments/assets/fe6c968a-7867-4be9-8ee1-65f2baa26190"
/>

## Please complete the following:

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

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

FloPinguin
2025-12-16 19:16:03 -08:00
DevelopingTom 648ae1943f Christmas Themed FX (#2624)
## Description:

### Santa:
- spawn randomly on the map every minute:


![santa_is_coming](https://github.com/user-attachments/assets/0c40f983-7c5e-4fd9-93cd-5601008cb2ef)

### Nuke changes:
- Atom: small gift
- Hydro: big gift
- MIRV: shooting star


![all_christmas_nukes](https://github.com/user-attachments/assets/db80d765-6292-44e0-a5a3-fe08c0516993)

### Nuke fallout FX:
- melting snowman
- happy elves
- elves needing assistance


![christmastroph](https://github.com/user-attachments/assets/92270357-a0f6-43bf-9b95-cc5b2427a542)

## 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
2025-12-15 20:24:23 -08:00
FloPinguin f96fd6dc12 Show max troops in PlayerInfoOverlay and leaderboard 🖌️ (#2625)
## Description:

In the main discord, people seem to be divided in their opinions about
this.
But lets see what the playtest-people are saying, we can easily roll
this back.

<img width="197" height="312" alt="Screenshot 2025-12-15 220648"
src="https://github.com/user-attachments/assets/c6acd1f8-03b1-4949-b15e-6a32f8460e18"
/>
<img width="405" height="323" alt="Screenshot 2025-12-15 220623"
src="https://github.com/user-attachments/assets/21190a6f-1a0b-4db3-b6d0-c0722e98902a"
/>

## Please complete the following:

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

## Please put your Discord username so you can be contacted if a bug or
regression is found:
FloPinguin
2025-12-15 20:22:59 -08:00
FloPinguin b4ec54113d Fixed events panel scroll position not staying at the bottom 🛠️ (#2613)
## Description:

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

## Please complete the following:

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

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

FloPinguin
2025-12-13 19:35:55 -08:00
evanpelle 04370eda17 Merge branch 'v27' 2025-12-12 16:20:43 -08:00
Evan a09f0c67f1 Update auth & login to follow best practices (#2559)
## Description:

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

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

## Please complete the following:

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

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

evan
2025-12-11 11:25:27 -08:00
Roan 8dde30ebb6 Update game timer UI (#2577)
## Description:

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

### Before:

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


### After:

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


## Please complete the following:

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

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

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

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

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


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

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

## Please put your Discord username so you can be contacted if a bug or
regression is found:
aotumuri
2025-12-09 19:43:48 -08:00
Roan e104614a85 Consistent border radius and padding from edge of screen for in game UI (#2576)
## Description:

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


Before:

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

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


After: 

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

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




## Please complete the following:

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

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

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

Missile silos should also show SAM previews for placement consideration.

## Please complete the following:

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

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

bibizu
2025-12-09 16:26:12 -08:00
Ahmet Dedeler 327d425fd5 Fix obvious typos (#2585)
## Summary
- fix obvious spelling typos flagged by codespell across docs, tests,
comments
- no functional changes

## Testing
- pre-commit hooks (eslint/prettier) ran during commit
2025-12-09 16:12:00 -08:00
evanpelle 1d7685a5bf Merge branch 'v27' 2025-12-09 15:39:49 -08:00
Wraith 7658c67662 optimize(RailroadLayer): throttle color scans, cull blits, and remove (#2565)
## Description:

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

## Please complete the following:

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

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

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

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

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

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

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

## Please complete the following:

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

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

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

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

This PR fixes this by:

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

Reference to comments on it on Dev Discord:

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


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

Orange alert frame on being attacked over land:

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

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

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

## Please complete the following:

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

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

tryout33
2025-12-04 13:26:55 -08:00
VariableVince ec0bf079ef Fix spacing in player team label display (#2560)
## Description:

Add a space after "Your team:"

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

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

## Please complete the following:

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

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

tryout33
2025-12-03 16:37:17 -08:00
Lavodan 4ff2ca3315 Fix: firefox back button not working (#2557)
## Description:

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

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

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

Functionality is preserved for Chrome.

## Please complete the following:

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

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

Lavodan
2025-12-03 15:41:58 -08:00
Roan 5d513dfe5d Remove border around in game time (#2544)
## Description:

Removes the border around the in game time because it looks better this
way. Sorry my screenshots are a bit washed out, windows doesn't like my
HDR monitor...

Before:
<img width="201" height="145" alt="image"
src="https://github.com/user-attachments/assets/ef399dcd-72bc-4ee7-ac67-42a0e4b2b793"
/>

After:
<img width="213" height="143" alt="image"
src="https://github.com/user-attachments/assets/bdb211af-d2c6-4b5e-8946-1cb88bf707c2"
/>


## Please complete the following:

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

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

rovi.
2025-11-30 19:00:36 -08:00
FloPinguin 38145254af Alliance icon does no longer stretch/disappear 🖌️ (#2527)
Resolves #2521

## Description:

Small CSS fix so the new alliance icon does not stretch when there are
multiple icons.

## Please complete the following:

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

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

FloPinguin
2025-11-26 19:51:21 -08:00
FloPinguin ab53ee687f Alliance icon does no longer stretch/disappear 🖌️ (#2527)
Resolves #2521

## Description:

Small CSS fix so the new alliance icon does not stretch when there are
multiple icons.

## Please complete the following:

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

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

FloPinguin
2025-11-26 19:50:58 -08:00
CrackeRR11 8f53785a80 BUG FIX: Gold double deduction + Rmoval of UnitType.Construction (#2378)
## Description:

- Removed the temporary UnitType.Construction and embedded construction
state into real units via isUnderConstruction().
- Centralized non-structure spawning to perform a single validation
right before unit creation/launch.
- Updated UI layers to render construction state without relying on the
removed enum.
- Adjusted and created tests to match the new flow and to cover the
no-refundscenarios.

# Tests updated 
- tests/economy/ConstructionGold.test.ts: covers structure cost
deduction and income, tolerant of passive income; ensures no refunds
during construction.
- tests/nukes/HydrogenAndMirv.test.ts: accounts for single-check launch
flow; MIRV test targets a player-owned tile; ensures launch after
payment.
- tests/client/graphics/UILayer.test.ts: mocks now provide
isUnderConstruction and real type strings;

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

CrackeRR1

---------

Co-authored-by: Evan <evanpelle@gmail.com>
2025-11-26 14:45:14 -08:00
NOBODY 049485cd39 Fix: Correct percentage (%) placement in Persian UI (RTL handling) (#2501)
## Description:

Fixes incorrect RTL rendering where the percentage symbol (%) appeared
before the label in Persian (fa-IR).
The UI now correctly displays values as `20%`.

**Changes:**
- Updated `controlpanel.ts` to fix percentage position.
- 16 additions, 7 deletions.

**Testing:**
1. Switch UI language to Persian (fa-IR).
2. Open control panel with percentage display.
3. Confirm `%` appears after numeric value.
4. Verified no changes in LTR languages.

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

nobodyiran
2025-11-24 10:29:08 -08:00
Rj Manhas a5cdd23c00 feat: added retaliate button (#2426)
If this PR fixes an issue, link it below. If not, delete these two
lines.
Resolves #495 

## Description:

Adds a button to quickly retaliate against a incoming attack

<img width="464" height="212" alt="image"
src="https://github.com/user-attachments/assets/4764d261-a408-4d61-a2d2-2685018aa698"
/>


## 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)
2025-11-24 09:34:04 -08:00
evanpelle 5fbdea3c39 Show enzo tutorial video on death screen if played less than 3 games 2025-11-22 12:23:33 -08:00
evanpelle 9287d0323d bugfix: emoji table was too small on firefox 2025-11-20 16:49:45 -08:00
Hauke12345 dcf5d1b103 Fading handshake (#2474)
## 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>
2025-11-19 12:32:01 -08:00
FloPinguin 90b73451a8 Added NameLayer-Icons to PlayerInfoOverlay (#2446)
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>
2025-11-18 15:03:52 -08:00
Mike Harris 2b44b68362 Feature - Improve Structure Color Contrast (#2454)
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
2025-11-16 20:58:34 -08:00