Commit Graph

13 Commits

Author SHA1 Message Date
scamiv 8cc6c2c2aa Perf spawn train (#3130)
## Description:

Train spawning hot-path optimization (trade destination selection)

## Summary
This PR reduces per-tick overhead in train spawning by removing
temporary allocations and reducing work in the
destination-selection path.

The change focuses on `Cluster` trade destination lookup and how
`TrainStationExecution` picks a destination.

## What changed
### 1) Maintain a “trade-capable” station subset per cluster
`src/core/game/TrainStation.ts`

- `Cluster` now maintains:
  - `stations`: all stations in the cluster (unchanged)
- `tradeStations`: maintained subset of stations that can act as trade
endpoints (`City` or `Port`)
- `tradeStations` is kept in sync in:
  - `addStation()`
  - `removeStation()`
  - `clear()`

Impact:
- Trade queries no longer scan every station in the cluster; they only
scan `tradeStations`.

### 2) Add cheap eligibility helpers
`src/core/game/TrainStation.ts`

- `hasAnyTradeDestination(player)`:
- Fast early-exit check: returns as soon as it finds any eligible trade
destination.
- `randomTradeDestination(player, random)`:
- Picks a random eligible trade destination directly without
materializing an intermediate `Set`.

### 3) Use reservoir sampling for single-pass random choice
`src/core/game/TrainStation.ts`

`Cluster.randomTradeDestination()` uses reservoir sampling:
- Iterates `tradeStations` once.
- Maintains a running count of eligible stations (`eligibleSeen`).
- Replaces the selected station with probability `1/eligibleSeen`.

Properties:
- Uniform selection among eligible stations.
- One pass instead of “count then pick by index” (two pass).
- Allocation-free.
- Returns `null` when no eligible destination exists.

### 4) Update train spawning to avoid temporary sets
`src/core/execution/TrainStationExecution.ts`

- Previously: `spawnTrain()` called `cluster.availableForTrade()` and
then `random.randFromSet(...)`.
  - This built a new `Set` on the hot path.
- Now:
  - Early-exit via `cluster.hasAnyTradeDestination(owner)`.
  - Destination via `cluster.randomTradeDestination(owner, random)`.

Net effect:
- Less per-tick work and no per-spawn temporary `Set` allocations.

## Why this helps
Train spawning happens frequently and can become a hot path in large
games / large rail clusters.
Avoiding repeated allocations and reducing work inside `tick()` helps
keep frame/update time predictable.

## notes
- Trade rules are unchanged (`tradeAvailable(player)` still gates
eligibility).
- Destination selection remains random-uniform over eligible
`City`/`Port` stations that satisfy `tradeAvailable(player)`.
- `TrainStationExecution` now avoids calling `spawnTrain()` entirely
when `spawnTrains` is falsy (it was already guarded inside).




## Please complete the following:

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

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

DISCORD_USERNAME
2026-02-05 12:16:59 -08:00
DevelopingTom 9415162f51 Split railroads when placing overlapping structures (#3003)
## Description:
Players wrongly assume that building a structure over an existing
railroad will connect it properly. What actually happens is that the
structure will connect on the network with its own railroad, even if the
new railroads are overlapping over the existing network.

To address this issue, this PR splits the overlapping railroad into two
segments when a structure is built over it, and inserts the structure as
a new node in the rail graph. It does not alter the rail network
visually because the same railroad tiles are used for the new segments.

Railroad tiles are not stored directly in the map, they exist only as
edges in the rail graph, so looking for nearby rails would be terribly
inefficient. To address that, this PR introduces a new `RailSpatialGrid`
class which indexes rails on a 4×4 grid, allowing fast spatial queries.

Alternative considered: removing overlapping rails and rebuilding them
from the new structure. It would visually modify the rail network, which
may be unexpected for the player.

It's still missing a visual indicator so the player knows that the
structures has been connected properly.

### Line placement:


![snap_line](https://github.com/user-attachments/assets/f24ddd36-1594-4316-91ff-093a5cebd576)

### Multi-railroad overlap:


![snap_cross](https://github.com/user-attachments/assets/b2cc962e-6dce-4444-b689-7e04a09de603)


## 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
2026-01-22 19:19:51 -08:00
DevelopingTom c80ccaece9 Record train trading stats (#2891)
## Description:

The current gold stats don’t include gold generated by trains, even
though this is a significant part of the economy for many players.

This PR tracks those stats with two values:
- other players trains visits the player station
- the player trains visits any station

Linked to this infra PR: https://github.com/openfrontio/infra/pull/242

## 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
2026-01-14 01:00:55 +00: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
Mykola 6112547273 Improve random spawn (#2503)
## Description:

This is a previously approved PR with an additional commit that fixes
case when nations change spawn & jump around, their previous territory
wasn't getting deleted.

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

nikolaj_mykola

---------

Co-authored-by: Evan <evanpelle@gmail.com>
2025-12-20 13:35:30 -08:00
Abdallah Bahrawi 0a6ab07d2e fix: traitor bug when attacking immediately after initiating an alliance (#2044)
## Description:

This PR fixes a critical race condition bug where players could
unintentionally receive the traitor debuff when alliance requests were
accepted mid-attack.


Critical Bug Fixes #1866

**Root Cause:** 
Players could bypass UI alliance checks ( isFriendly() ) by accepting
alliances and immediately attacking after that, causing the server to
treat the attack as betrayal
Solution: Added server-side alliance validation in
AttackExecution.init()
This ensures attacks on allies are blocked at the server level.

- Once Bots and Nations decide to attack, they breaks the alliance. I
added maybeConsiderBetrayal(), which currently always returns true. I’ll
add proper logic for alliance-breaking soon on another PR; this didn’t
exist in the code before.

## 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: evanpelle <evanpelle@gmail.com>
2025-09-13 09:21:21 -07:00
evanpelle 3e880a34ef v25 meta update (#1872)
## Description:

v25 meta update:

- Trade ship spawn rate is determined by number of ports players has and
total number of tradeships on the map
- Train spawn rate scales hyperbolically with number of factories owned
by player
- Factory & Port share the same early unit discount (eg building a port
makes the factory more expensive), this is to encourage more
specialization: become a naval economy or land based economy.
- Trains spawn from factories and arrive on cities
- Trains only give gold on cities
- Trains give 50k gold for allies, 25k for nonallies, and 10k for self
- Large players are given a 30% speed/attack debuff in sigmoid curve
- Reduced attack bonus for large players
- Nerf bot gold production from 1k/s => 500/s
- Nerf bot max troops

## 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-08-19 18:53:42 -07:00
evanpelle 754db60a00 Have trains produce more gold (#1759)
## Description:

During the play test, trains did not produce enough gold. So increase
gold, and give 4x bonus for allies.

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

evan
2025-08-08 18:38:16 -07:00
DevelopingTom a05814a7fb Rework trains to encourage alliances (#1697)
## Description:

This update encourages alliances by modifying how train-based trading
works. Trading is now restricted to allied networks, and allied trades
offer better rewards than self-trades, incentivizing cooperation.

Changes:
- Train destinations are now limited to stations owned by the player or
their allies.
    - Delivering a train to one’s own station grants 4,000 gold.
- Delivering a train to an ally’s station grants 5,000 gold to both the
sender and the receiver.

This system encourages players to form alliances, especially with
factory-focused players.


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

IngloriousTom
2025-08-03 23:13:27 +00:00
Tyler Hanavan 0726449b6e Don't become traitor when betraying inactive player (#1610)
## Description:

Don't become traitor when betraying inactive player

This PR makes the following changes
- Do not mark the attacking player as a traitor, if they attack/betray
an ally who is disconnected from the game
- Do not send the attacking player the betrayal message (traitor debuff
applied message), if they attack/betray an ally who is disconnected from
the game
- Add test case for traitor debuff being applied if the attacking player
attacks an ally who is still connected to the game
- Add test case for traitor debuff NOT being applied if the attacking
player attacks an ally who is disconnected from the game


I also tested this manually with nuking an allied player who is
connected and nuking an allied player who is disconnected. The logic
worked as expected.

This PR was made in regards to the following issue: #1599 

## 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
2025-07-28 11:22:07 -07:00
DevelopingTom 6353a5d6f7 Automatic train stations (#1353)
## Description:

Train stations are now built automatically when a factory is
constructed.

Changes:
- When a factory is built, nearby structures are connected to the rail
network
- When a city is built near a factory, it is connected to the rail
network
    - All structures behave the same when a train stops: to be defined
    - Removed station badge
    - Gold income is now related to the structure's level

## 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
2025-07-06 13:15:49 -07:00
DevelopingTom 29170321e4 Add gold fx when a tradeship lands (#1322)
## Description:

Add a text popup FX when a tradeship lands in your port.
They are only displayed for the current player.


https://github.com/user-attachments/assets/586ded57-5311-4394-a322-903ecea89bd6


## 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: Tom Rouillard <trouilla@mathworks.com>
Co-authored-by: evanpelle <evanpelle@gmail.com>
2025-07-03 19:26:36 -07:00
DevelopingTom 43397779fa Add trains (#1159)
## 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-708c81ffd609


https://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>
2025-06-22 08:14:08 -07:00