2809 Commits

Author SHA1 Message Date
scamiv fe927b9758 Fix fallback, Merge packed tile updates in non-SAB mode 2025-12-11 17:18:04 +01:00
scamiv a4094de3a7 overflows field now acts as a bool 2025-12-11 17:18:03 +01:00
scamiv 8bc140e23f refactored loadTerrainMap to reuse the existing canUseSharedBuffers 2025-12-11 17:18:03 +01:00
scamiv 2d63dcfcc5 disable TerrainMapData cache for SAB path 2025-12-11 17:18:02 +01:00
scamiv 9892537a08 removed console.log 2025-12-11 17:18:01 +01:00
scamiv fad87a9b75 Size SAB ring buffer by world tile count 2025-12-11 17:18:01 +01:00
scamiv 430d856f6b Use dirty flags to coalesce tile updates in SAB ring
- Extend SharedTileRing to include a shared dirtyFlags buffer alongside header and data
- Pass shared dirty buffer through WorkerClient/WorkerMessages and initialize views in Worker.worker
- In SAB mode, mark tiles dirty via Atomics.compareExchange before enqueuing to ensure each tile is queued at most once until processed
- On the main thread, clear dirty flags when draining the ring and build packedTileUpdates from distinct tile refs
- Keep non-SAB behaviour unchanged while reducing ring pressure and making overflows reflect true backlog, not duplicate updates
2025-12-11 17:18:00 +01:00
scamiv 99b01d8580 Revert "dedup tileRef for tileUpdateSink(tileRef)"
This reverts commit 08a2ff906b.
2025-12-11 17:17:59 +01:00
scamiv e387820eee dedup tileRef for tileUpdateSink(tileRef) 2025-12-11 17:17:59 +01:00
scamiv 09afa11a3e fix performance overlay 2025-12-11 17:17:58 +01:00
scamiv b312aa3df2 fix sab detection 2025-12-11 17:17:57 +01:00
scamiv 19e50465cc mergeGameUpdates fix batch.length === 0 return case 2025-12-11 17:17:57 +01:00
scamiv 0da975f615 add more stats to perf overlay 2025-12-11 17:17:56 +01:00
scamiv 37315e5fa5 Change the ring buffer to Uint32Array
Store only TileRef instead of packed tile+state values
2025-12-11 17:17:55 +01:00
scamiv 314d8ef25a Use SharedArrayBuffer tile state and ring buffer for worker updates
- Share GameMapImpl tile state between worker and main via SharedArrayBuffer
- Add SAB-backed tile update ring buffer to stream tile changes instead of postMessage payloads
- Wire shared state/ring through WorkerClient, Worker.worker, GameRunner, and ClientGameRunner
- Update GameView to skip updateTile when shared state is enabled and consume tile refs from the ring
2025-12-11 17:17:54 +01:00
scamiv 05181d7479 SAB+Atomics refactor
Added src/core/worker/SharedTileRing.ts, which defines a SharedArrayBuffer-backed ring buffer (SharedTileRingBuffers/SharedTileRingViews) and helpers pushTileUpdate (worker-side writer) and drainTileUpdates (main-thread reader) using Atomics.

Extended GameRunner (src/core/GameRunner.ts) with an optional tileUpdateSink?: (update: bigint) => void; when provided, tile updates are sent to the sink instead of being packed into GameUpdateViewData.packedTileUpdates (those become an empty BigUint64Array in this mode).

Extended the worker protocol (src/core/worker/WorkerMessages.ts) so the init message can optionally carry sharedTileRingHeader and sharedTileRingData (the two SABs for the ring).

Updated WorkerClient (src/core/worker/WorkerClient.ts) to accept optional SharedTileRingBuffers in its constructor and, during initialize(), include those SABs in the init message sent to Worker.worker.ts.

Updated the worker implementation (src/core/worker/Worker.worker.ts) to build sharedTileRing views from the SABs on "init" and pass a (update: bigint) => pushTileUpdate(...) sink into createGameRunner, so every tile update from the simulation goes into the shared ring instead of the message payload.

Updated the client side (src/client/ClientGameRunner.ts):
In createClientGame, when SharedArrayBuffer/Atomics are available and crossOriginIsolated is true, it allocates the ring (createSharedTileRingBuffers with capacity 262144), creates views, passes buffers into WorkerClient, and keeps the views in ClientGameRunner.
ClientGameRunner now has a tileRingViews field and, in mergeGameUpdates, if the ring is present it ignores gu.packedTileUpdates and instead drains up to MAX_TILE_UPDATES_PER_RENDER (100 000) tile updates from the SAB ring into combinedPackedTileUpdates before constructing the merged GameUpdateViewData passed to GameView.update.
If SABs are unavailable, it falls back to the original behaviour (packing gu.packedTileUpdates from messages), so the feature is opt-in and backward compatible.

Net effect: when the page is cross-origin isolated, the worker no longer sends per-tick BigUint64Array tile payloads via postMessage; it streams tile updates into a shared ring buffer, and the main thread pulls and applies them at its own pace while still batching non-tile updates and rendering exactly as before. If you’d like, I can next run the existing tests/build in your environment to sanity-check everything.
2025-12-11 17:17:54 +01:00
scamiv 2f2a12eefa Add performance metrics for worker and render ticks
- 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
2025-12-11 17:17:53 +01:00
scamiv 391f19d061 Refactor rendering and throttle based on backlog
- Refactor rendering and metrics emission in ClientGameRunner to ensure updates occur only after all processing is complete
- Throttle renderGame() based on the current backlog
2025-12-11 17:17:52 +01:00
scamiv 2dde26223c add "ticks per render" metric 2025-12-11 17:17:52 +01:00
scamiv 0ffe9c39ad remove redundant logic 2025-12-11 17:17:51 +01:00
scamiv bd6dbd3f4b ClientGameRunner: simplify catch-up loop with indexed queue
process updates in a single budgeted loop per RAF and render once
track queue head with pendingStart and compact to avoid array shifts
2025-12-11 17:17:50 +01:00
scamiv a04abbec53 Refactor slice budget calculation in ClientGameRunner to improve backlog handling. Introduced dynamic slice budget scaling based on backlog size, allowing for longer processing times when necessary while maintaining UI responsiveness. 2025-12-11 17:17:50 +01:00
scamiv bd300708c7 Implemented time-sliced catch-up on the main thread to keep input responsive.
src/client/ClientGameRunner.ts now drains pending game updates in small chunks (max 100 updates or ~8ms per slice) via requestAnimationFrame, merging and rendering per slice, and only clears the processing flag when the queue is empty.
2025-12-11 17:17:49 +01:00
scamiv f710c78dcf Clean up previous implementations
removed:
- catchUpMode and its CATCH_UP_ENTER/EXIT thresholds in ClientGameRunner
- tick metrics fields and overlay UI for inCatchUpMode and beatsPerFrame
- leftover worker heartbeat plumbing (message type + WorkerClient.sendHeartbeat) that was no longer used after self-clocking

changed:
- backlog tracking: keep serverTurnHighWater / lastProcessedTick / backlogTurns, but simplify it to just compute backlog and a backlogGrowing flag instead of driving a dedicated catch-up mode
- frame skip: adaptRenderFrequency now only increases renderEveryN when backlog > 0 and still growing; when backlog is stable/shrinking or zero, it decays renderEveryN back toward 1
- render loop: uses the backlog-aware renderEveryN unconditionally (no catch-up flag), and resets skipping completely when backlog reaches 0
- metrics/overlay: TickMetricsEvent now carries backlogTurns and renderEveryN; the performance overlay displays backlog and current “render every N frames” but no longer mentions catch-up or heartbeats

Learnings during branch development leading to this

Once the worker self-clocks, a separate “catch-up mode” and beats-per-frame knob don’t add real control; they just complicate the model.
Backlog is still a valuable signal, but it’s more effective as a quantitative input (backlog size and whether it’s growing) than as a boolean mode toggle.
Frame skipping should be driven by actual backlog pressure plus frame cost: throttle only while backlog is growing and frames are heavy, and automatically relax back to full-rate rendering once the simulation catches up.
2025-12-11 17:17:48 +01:00
scamiv 7e6717c1b8 Worker now self-clocks; no heartbeats needed
GameRunner exposes pending work via a new hasPendingTurns() so the worker can check whether more ticks need to be processed.
Worker auto-runs ticks: as soon as it initializes or receives a new turn, it calls processPendingTurns() and loops executeNextTick() while hasPendingTurns() is true. No more "heartbeat" message type; the worker no longer depends on the main thread’s RAF loop to advance the simulation.
Client main thread simplified:
Removed CATCH_UP_HEARTBEATS_PER_FRAME, the heartbeat loop, and the lastBeatsPerFrame tracking.
keepWorkerAlive now just manages frame skipping + draining. When it decides to render (based on renderEveryN), it drains pendingUpdates, merges them, updates GameView, and runs renderer.tick().
Because rendering a batch always implies draining, we restored the invariant that every GameView.update is paired with a layer tick() (no more lost incremental updates).
MAX_RENDER_EVERY_N is now 5 to keep the queue from growing too large while the worker sprints.
2025-12-11 17:17:47 +01:00
scamiv e3a6e0bfcc frameskip 2025-12-11 17:17:47 +01:00
scamiv a31a6a04a9 Batch worker updates in client catch-up mode to reduce render cost
- Refactor worker update handling into processPendingUpdates so multiple GameUpdateViewData objects are batched per frame.
- Combine all tick updates in a batch into a single GameUpdateViewData before applying it to GameView, while still running per-tick side effects (turnComplete, hashes, backlog metrics, win saving).
- Ensure layers using updatesSinceLastTick and recentlyUpdatedTiles see all events in a batch, fixing visual artifacts during fast-forward resync.
2025-12-11 17:17:46 +01:00
scamiv 5e264a54bc Add client catch-up mode
Increase worker heartbeats per frame when far behind server to fast-forward simulation.
Track backlog and expose catch-up status via TickMetricsEvent.
Extend performance overlay to display backlog turns and indicate active catch-up mode.
2025-12-11 17:17:45 +01: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
Aaron Tidwell ae884cb902 Add New York City Map (#2542)
## Description:

Adds New York City Map.

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

tidwell

Screenshots

<img width="1700" height="1081" alt="location-select"
src="https://github.com/user-attachments/assets/06d229c1-f804-4766-bd58-35923c6696bc"
/>
<img width="1705" height="1079" alt="map-bots"
src="https://github.com/user-attachments/assets/16a677d1-da6b-4aca-9ecf-8b0fbb161019"
/>
<img width="1706" height="1082" alt="map-select"
src="https://github.com/user-attachments/assets/8adfd26b-f506-4c72-be05-a1fa638311ab"
/>
<img width="745" height="929" alt="nation-placement"
src="https://github.com/user-attachments/assets/6b5ffd0e-0b2e-4189-b118-bd04c8ac4240"
/>


Misc

Dimensions: 1500 x 1900 px
Total Area: 2,850,000 px²
New Flag Assets: None


[Inspired by this Discord
Thread](https://discord.com/channels/1284581928254701718/1440439003160641667/1440439003160641667)

Some of the water features are adjusted for playability. NYC doesn't
have a ton of elevation differences, so marshland is replicated w/
highland noise. This is roughly placed to match
[Pre-WWI](https://www.geographicus.com/P/AntiqueMap/newyorkcity-usgs-1915),
but allows maintaining the modern silhouette of the area. This 1901 map
is also the main inspiration for composition and projection. For the
Nations, British and Dutch Colonies along with Native Peoples make this
a bit of an amalgamation of the 17th - 20th centuries

Other elevation differences come from [Topographic
Map](https://en-gb.topographic-map.com/map-6sm14/New-York/?center=40.63067%2C-73.89158&zoom=11)

[Tribal Nation Names and
Info](https://en.wikipedia.org/wiki/History_of_Long_Island)
[Additional Tribal
Names/Info](https://libguides.pratt.edu/c.php?g=1088684&p=9380209)

---------

Co-authored-by: Evan <evanpelle@gmail.com>
2025-12-10 12:30:19 -08:00
Henry d4dd9ccd74 UI Improvement: Add rank to stats modal in the lobby for clarity (#2562)
## Description:

This PR adds a rank column to the stats modal on the lobby page.

## 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 (N/A)
- [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:

HardShellTurtle
<img width="2551" height="1258" alt="Screenshot 2025-12-04 232356"
src="https://github.com/user-attachments/assets/26665f3a-f9ee-44b7-a5ba-061c04101997"
/>
2025-12-10 10:33:15 -08:00
Luis Leiva 121e45d5d2 Block UI actions while GameStartingModal is visible (#2587) (#2596)
## Description:
- Original intent was to fix the bug where you could click and start the
next lobby game through the “Game is Starting…” modal, and while
testing, i've found the issue affected all action buttons behind the
modal, not just the lobby join button.
- Added a full-screen overlay that captures pointer events whenever
`GameStartingModal` is visible, preventing any background UI actions
until the start flow completes.

- Screenshot: 
<img width="1918" height="908" alt="image"
src="https://github.com/user-attachments/assets/f6358cb4-1270-4e0b-9f2e-9e57b085ca03"
/>


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

Leivadev
2025-12-10 18:22:07 +00:00
Aaron Tidwell afe072f7d0 Add map-generator --maps flag to process a subset of maps (#2595)
Resolves #2594

## Description:

- Added an optional `--maps` flag to the map-generator that allows
passing a subset of maps to process.
- Updated `README.md` w/ documentation for using the new flag

Used the [go/flag](https://pkg.go.dev/flag) package.

Running without the flag, or with no arguments matches existing behavior
of processing all the maps defined in `main.go`

`go run .`
`go run . --maps=`

New behavior is triggered to process a subset of maps by passing the
`--maps` flag. Multiple maps are defined in a comma-separated list

`go run . --maps=world,africa`

Or a single map (useful for map development)

`go run . --maps=fourislands`

If an invalid map is passed, the process aborts and renders the error

```bash
go run . --maps=invalidmapname
Error generating terrain maps: map "invalidmapname" is not defined
exit status 1
```

By using the default flag package, we get `--help` for free:

```bash
go run . --help
Usage of <path-to-exe>/exe/map-generator:
  -maps string
    	optional comma-separated list of maps to process. ex: --maps=world,eastasia,big_plains
```

I do not write GO often.  Gemini contributed to this syntax.

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

tidwell
2025-12-10 10:23:39 -08:00
Aaron Tidwell 2bfe245a72 Add format:map-generator command (#2563)
I'd like to submit some PRs in the future to add additional options for
logging and debugging to the map-generator, however I don't want to
introduce any code style changes in feature requests.

## Description:

I noticed there was not any style guide or formatting being done for the
go files, and went with the simplest built-in approach w/ [go
fmt](https://go.dev/blog/gofmt)

- Adds a `format:map-generator` npm command that will run the default
`go fmt` in the `map-generator` directory to format the go code.
- Runs the formatter and commits the changes to `main.go` and
`map_generator.go`
- Updates the `map-generator` README:
  - Updated location for generated files
  - Updated Links to use markdown links
  - Add `info.json` example
  - Add in-game enabling instructions with list of files to modify
  - Add development tools section with format command

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

tidwell
2025-12-09 19:46:13 -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
VariableVince f0feabfb13 Fix: Filter out in construction buildings for totalunitlevels (#2580)
## Description:

Fix for v28.

After PR #2378 changes, unit type Construction doesn't exist anymore.
Resulting in totalUnitLevels counting in construction buildings towards
total units in TeamStats, old and new Build Menu and Player Info
Overlay. To fix this we now need to filter out the construction phase.

totalUnitLevels is only used for displaying total count purposes, it
doesn't affect other logic.

Before PR 2378 changes:

https://github.com/user-attachments/assets/7748092a-8b7b-41bb-bc68-439ba922b479

After PR 2378 changes:

https://github.com/user-attachments/assets/bc77d7c2-be02-487a-b46a-c02367ae5ad8

After fix in this PR it is back to what is was before:

https://github.com/user-attachments/assets/8d7d14b6-7b6b-4ddb-96d1-17a0a45727f3

## 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-09 16:14:25 -08:00
Aotumuri 29a895ab35 Remove unused strings from en.json (#2582)
## Description:

This PR removes several unused strings from en.json.
Leaving unused entries increases Crowdin storage usage and makes
translation management harder, so they should be cleaned up regularly.

The removed strings were originally added in the following PRs but are
not used anywhere in the codebase:
- #2146
- #2060
- #2233

## 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 16:12:25 -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
Ahmet Dedeler 18efa4cd73 Load env vars before server config init (#2586)
## Summary
- load dotenv before constructing the server config so .env values are
available
- avoid misconfigured tunnels/host metadata when env vars were
previously undefined

## Testing
- npm test -- --runInBand
2025-12-09 16:10:53 -08:00
scamiv 5e95ba8da5 Lobby team size (#2591)
## Description:

show team size in lobby

## Please complete the following:

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

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

DISCORD_USERNAME
2025-12-09 16:10:21 -08:00
evanpelle 1d7685a5bf Merge branch 'v27' 2025-12-09 15:39:49 -08:00
evanpelle 73be130916 print and alert cloudflare turnstile error callback 2025-12-09 14:30:32 -08:00
evanpelle 50fe3581cc bugfix: only prefetch turnstile token once to prevent multiple checkboxes v0.27.6 2025-12-09 07:54:22 -08:00
evanpelle afa3e70b62 Check if turnstile is defined v0.27.5 2025-12-08 18:08:23 -08:00
Evan 335a371fdb bugfix: singleplayer not starting (#2589)
#075c232 introduced a bug that prevented singplayer games from starting.

The `updateCallback` was not set for localserver, and local server
didn't send a start message when client sent a "rejoin".

## 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
v0.27.4
2025-12-08 16:42:29 -08:00
Evan 3314ca16ce Turnstile: require token before joining a multiplayer game (#2572)
When user tries to join either a public or private multiplayer game, the
turnstile callback is triggered, and the turnstile token is passed to
the server when joining a game.

## Please complete the following:

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

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

evan
2025-12-08 16:16:31 -08:00
Evan 075c232d8a improve game websockt (re)connection (#2584)
Previously, the connection and reconnection logic were identical in
Worker.ts, so clients would need to be re-authorized for cosmetics etc
even when reconnecting. Now, on reconnect, Worker.ts only does
authentication - verifying the jwt is valid.

This will allow clients to require a valid turnstile token when first
connecting, and not when reconnecting after a broken ws connection.

## 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-08 14:07:07 -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