Commit Graph

3846 Commits

Author SHA1 Message Date
Sky Elder 38cb3027cb Feature Add retaliate keybind (#3801)
If this PR fixes an issue, link it below. If not, delete these two
lines.
Resolves #3174 

## Description:

This PR implements a keybind for retaliation against incoming non-bot
attacks (Players and Nations). It currently will target the most recent
(last in array) incoming attack when the keybind is pressed, choosing
the minimum of attack ratio or incoming attack troop size to retaliate
with. This correlates with the last displayed incoming attack on the
bottom modal. It works when there are multiple attacks (press multiple
times to retaliate against each consecutive attack). If the retaliation
size is smaller than the attack, the keybind can be pressed multiple
times to repeatedly blunt the incoming troop count.

Due to the current keybind logic KeyR cannot be used but Shift+KeyR can
so it is set to that until refactor.

<img width="867" height="121" alt="image"
src="https://github.com/user-attachments/assets/56e80810-4900-4db0-8ce7-1856e13529e5"
/>

No tests have been added as the retaliation feature doesn't seem to have
any to begin with since it is just an attack intent. The keybind is not
configured any differently than others. I did run all current tests and
was all good.

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

n1ghtingal3
2026-05-06 12:08:31 -06:00
VariableVince cdb7c18a2d Fix: CI Test failures because of too-long running test (#3861)
## Description:

Set timeout to 30s instead of the default 5s for test "en.json keys stay
in sync with source usage". It reads almost all files and therefor can
take longer to complete its run, with the growing repository.

This sometimes lead to error from vitest `Error: Test timed out in
5000ms. If this is a long-running test, pass a timeout value as the last
argument or configure it globally with "testTimeout"`. A workaround was
to re-run the test, sometimes it then ran fast enough to stay below the
5s timeout. But a more permanent fix is in this PR: set the timout to
30s specifically for this test.

<img width="997" height="251" alt="image"
src="https://github.com/user-attachments/assets/0efb138a-fd64-461a-8109-e9e0b3f57c7a"
/>

## Please complete the following:

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

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

tryout33

Co-authored-by: Copilot <copilot@github.com>
2026-05-06 09:47:47 -06:00
VariableVince eca5794ebb Chore(deps): Update and remove dependencies (#3819)
## Description:

Only mentioning removals/major updates/notable changes below, not all
minor upgrades.

### Removed:
- "@aws-sdk/client-s3": not used anywhere (was used in Archive.ts
previously)
- chai, "@types/chai", sinon-chai: not used anywhere, probably leftover.
Vitest uses a bundled version of Chai for its expect asserations under
the hood too.
- protobufjs, "@types/google-protobuf": not used anywhere, probably left
from evan's experiment with it? Removed from vite.config.ts too.
- "@types/jquery": not used anywhere, probably leftover
- sinon, "@types/sinon": not used anywhere just like chai, probably
leftover. And Vitest provides us with the same functionality.
- "@types/systeminformation": dependency systeminformation was removed
last year, this is an unneeded, deprecated and unmaintained remainder.
- vite-tsconfig-paths: removed, and removed the import and usage in
vite.config.ts and replaced it by adding `tsconfigPaths: true` to the
`resolve` block. Because of this message displayed on running the tests:
"The plugin "vite-tsconfig-paths" is detected. Vite now supports
tsconfig paths resolution natively via the resolve.tsconfigPaths option.
You can remove the plugin and set resolve.tsconfigPaths: true in your
Vite config instead."
- vite-plugin-static-copy: removed, we don't use it anymore (was used in
our vite.config.ts once,, probably before Vite natively supported
copying static assets via its publicDir configuration)

### Updated:
- color.js: v0.5 > v0.6, no breaking change affecting us
- cross-env: v7 > v10. It's a publicly archived repo since Nov 2025. But
before that he got it up-to-date from June 2025, porting to TS, dropping
old Node versions, dependencies etc. Seems still good to use for some
amount of time to come.
- dotenv: v16 > v17, now logs an informational message by default when
it loads an environment file. Can be disabled by using
dotenv.config({quite: true}) if needed.
- ejs: v3 > v5: security patches mostly. Vite still uses v3 btw.
- eslint: v9 > v10. Newly enabled rules by default:
'no-unassigned-vars', 'no-useless-assignment' and
'preserve-caught-error'. Mostly faster and minimum support moved to
higher node versions, which shouldn't be a problem.
- "@eslint/compat": v1 > v2. Minimum supported Node versions, which
should not be a problem.
- intl-messageformat: v10 > v11 no breaking changes that affect us
- jdom: v27 > v29. Faster. Most notably minimum support moved to higher
node v22 version, which should not be a problem. Also, see types/node,
kind of expecting v24 to be installed now.
- nanoid: from v3 to v5, no breaking changes that affect us
- "@opentelemetry/sdk-logs": now that addLogRecordProcessor is removed,
changed Logger.ts to pass an (empty) provider array directly to the
LoggerProvider constructor. Follows the changes in
https://github.com/open-telemetry/opentelemetry-js/pull/5588
- "@tailwindcss/vite": supports vite v8 from 4.2.2, and a fix for it in
4.2.4
- tailwindcss: supports vite v8 from 4.2.2
-- in 4.1.15 (we were already above this version) break-words was
deprecated in favor of wrap-break-word. But break-words, which we use in
15 places, will still work as expected
(https://github.com/tailwindlabs/tailwindcss/pull/19157). Same goes for
also deprecated "order-none".
- "@types/node": from v22 to v24, assuming most now use node 24
- vite v7 > v8: 
-- is now on 8.0.10 so first bugs are out of it, while v8 itself also
fixed a big number of bugs.
-- in vite.config.ts, fixed Ts error/compilation issue by changing the
manualChunks option in build.rollupOptions.output to use the function
syntax, which is required by the updated types instead of the object
syntax.
- zod: no changes that affect us

### Prettier:
Updated only because of (new because of update?) Prettier errors for
files untouched in this PR originally:
- PathFinder.Parabola.ts
- WorkerMessages.ts
- ClanModal.handlers.test.ts
- ClanModal.rendering.test.ts‎
- CONTRIBUTING.md
- README.md

### ESLint:
Fixes needed to silence errors coming from newly enabled recommended
rules 'no-useless-assignment' and 'preserve-caught-error':

For 'no-useless-assignment' (default assignment never used because of
unreachable code or they are guaranteed to get a value, so they can be
undefinedat the start. Exception was AttackExecution, so made the
default value of 0 the default case in the switch statement):
- ClientGameRunner
- GameModeSelector
- NameBoxCalculator
- StructureDrawingUtils
- TerritoryLayer
- Diagnostics
- GameRunner
- ColorAllocator
- DefaultConfig
- AttackExecution
- AiAttackBehavior
- Worker.worker
- GamePreviewBuilder

For 'preserve-caught-error', disabled the rule here because the possible
fix `{cause: error}` was introduced in ES2022 while we're still on
target ES2020 currently:
- GameServer
- Privilege

_Error: The value assigned to 'gameMap' is not used in subsequent
statements. (no-useless-assignment)
Error: The value assigned to 'timeDisplay' is not used in subsequent
statements. (no-useless-assignment)
Error: The value assigned to 'scalingFactor' is not used in subsequent
statements. (no-useless-assignment)
Error: The value assigned to 'radius' is not used in subsequent
statements. (no-useless-assignment)
Error: The value assigned to 'teamColor' is not used in subsequent
statements. (no-useless-assignment)
Error: The value assigned to 'gl' is not used in subsequent statements.
(no-useless-assignment)
Error: The value assigned to 'power' is not used in subsequent
statements. (no-useless-assignment)
Error: The value assigned to 'tickExecutionDuration' is not used in
subsequent statements. (no-useless-assignment)
Error: The value assigned to 'selectedIndex' is not used in subsequent
statements. (no-useless-assignment)
Error: The value assigned to 'mag' is not used in subsequent statements.
(no-useless-assignment)
Error: The value assigned to 'speed' is not used in subsequent
statements. (no-useless-assignment)
Error: The value assigned to 'matchesCriteria' is not used in subsequent
statements. (no-useless-assignment)
Error: The value assigned to 'shouldContinue' is not used in subsequent
statements. (no-useless-assignment)
Error: The value assigned to 'description' is not used in subsequent
statements. (no-useless-assignment)
Error: There is no `cause` attached to the symptom error being thrown.
(preserve-caught-error)
Error: There is no `cause` attached to the symptom error being thrown.
(preserve-caught-error)_

All tests pass. TypeScript and ESLint errors resolved.

## Please complete the following:

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

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

tryout33

---------

Co-authored-by: Copilot <copilot@github.com>
2026-05-06 09:12:27 -06:00
Patrick Plays Badly c0b976448b Update map LUNA (#3854)
## Description:

Corrected inbalance in Luna map between top and bottom. Now both sides
have about equal land tiles.
Testing and editing was done to help boat-pathing at least look normal
along bottom half.
Additional notch cut in orbit lines to take edge off boat-pathing. Now
obstacle is almost a straight line.
Filled in center orbits to help players push easier. It was reported to
be tedious previously.
'Top Secret Military Base' nation was renamed with only vowels blacked
out for easier reading of joke name.
'Monolith' nation was renamed with a special character that displays
like the actual Monolith.

<img width="829" height="1165" alt="l1"
src="https://github.com/user-attachments/assets/8cf10fbf-99c1-4ec8-ae0c-7066d1deae21"
/>

<img width="829" height="1165" alt="l2"
src="https://github.com/user-attachments/assets/828e2caf-60b3-4ac7-aa70-0f5b64fac643"
/>



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

## Discord username
PlaysBadly
2026-05-06 08:19:15 +00:00
babyboucher 94bab78d24 Fix off by one error (#3827)
## Description:

Currently it is impossible to search for 2 letter clan tags (UN, FR,
EU), this is because of an off by one error present in the API

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

Babyboucher
2026-05-05 22:15:47 -06:00
babyboucher b8a544a7d5 Fix off by one error (#3827)
## Description:

Currently it is impossible to search for 2 letter clan tags (UN, FR,
EU), this is because of an off by one error present in the API

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

Babyboucher
2026-05-05 22:15:28 -06:00
RickD004 3744027e94 Adds map of the Middle East (#3829)
## Description:

Starting v32 maps right now!

Adds map of the Middle East. Probably one of the most highly requested
maps.

Very large map (3.4M land pixels, similar to Two Lakes, would become the
2nd or 3rd largest map by land area) of the arabian peninsula and
surrounding regions.
This map has both huge areas of land without water access full of desert
terrain, and massive trade chokepoints, which combined will result in
crazy endgames.

The theme of this map are historical, based on the end of WW1.
Historical flags have been added for the nation NPCs to use.

(High map rotation of 8 since this is probably going to become one of
the most popular maps given the relevancy of the region in real life.)

Terrain source from NASA DEM, already credited.


https://github.com/user-attachments/assets/6a1b345f-fd92-42c2-8f92-154fac4c9733

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

tri.star1011
2026-05-05 22:12:42 -06:00
Aotumuri 27e7a56f94 Disable build hotkeys after death (#3833)
## Description:

Prevent number-key build shortcuts from opening the unit build ghost
after the player has died.
Keep build hotkeys available only while the player is alive and not in
spawn phase.

## 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
2026-05-05 22:07:07 -06:00
Evan 7f9b63a24c Increase max intent size to 2kb (#3852)
## Description:

Raised MAX_INTENT_SIZE from 500 to 2000 bytes — the move_warship intent
could exceed the old limit and get rejected.
Removed the separate MAX_CONFIG_INTENT_SIZE (also 2000) and the
intentType branching, since both paths now share the same cap.
## Please complete the following:

- [ ] 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
2026-05-05 14:59:09 -06:00
Evan af5249655c Worker init (#3850)
## Description:

- Inline the game worker into the main bundle (`?worker&inline`) instead
of loading it from the CDN via a same-origin Blob trampoline.
- Some users were failing to load the worker — most likely a
cross-origin / CDN edge case the trampoline didn't paper over. Inlining
serves the worker as a same-origin Blob from the main bundle, bypassing
the cross-origin `new Worker(url)` restriction entirely.
- Removes `createGameWorker()`, the trampoline script, the
`trampoline_error` message type, and the `onTrampolineError` listener in
`initialize()`. The 60s init timeout backstop stays.
- `cdnBase` is still forwarded in the `init` message — that's for
in-worker asset fetches (maps, etc.), unrelated to loading the worker
module itself.

Tradeoff: the worker bundles all of `src/core`, so the main JS download
grows by that amount on every page load (including lobby/settings pages
that never start a game). Accepted because load reliability > bundle
size here.

## 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.31.9
2026-05-05 13:22:58 -06:00
evanpelle ffbe48ad10 fix: catch punctuation-separated slurs in username censor
Re-add skipNonAlphabeticTransformer to both matcher chains so bypass
attempts like "n.i.g.g.e.r" are detected.
v0.31.8
2026-05-04 18:18:36 -06:00
Evan 08b9fd96e6 simplify attack overlay to reduce visual clutter (#3848)
## Description:

Simplifies the attacking-troops overlay: removes the soldier icon and
strength bar, dropping each label down to just the troop number in cyan
(outgoing) or red (incoming) with a soft dark text-shadow halo and no
background fill so territory borders show through cleanly. Also splits
the label into outer (transitioned position) and inner (instant scale)
divs so zoom changes no longer get smeared by the 0.25s cluster-move
transition, retunes the zoom→size curve, and skips incoming labels from
bot tribes to cut clutter.

<img width="374" height="307" alt="Screenshot 2026-05-04 at 5 53 17 PM"
src="https://github.com/user-attachments/assets/a7044221-06cc-4027-b19a-6ff4ca8f542a"
/>

## 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
2026-05-04 18:10:06 -06:00
evanpelle 83ff524529 increase woker init timeout to 60s 2026-05-04 18:00:16 -06:00
evanpelle 900d7f0bd0 Increase worker init timeout from 20s to 30s 2026-05-04 15:04:23 -06:00
evanpelle 8d1614de72 Merge branch 'v31' 2026-05-04 12:55:13 -06:00
Evan 94205426e7 Move turnstile check to api (#3845)
## Description

Re-enables Turnstile verification (was temporarily disabled in v31 to
diagnose intermittent `invalid-input-response` rejections) and moves the
verification call off the game servers.

Game servers no longer hold `TURNSTILE_SECRET_KEY` or hit
`challenges.cloudflare.com` directly. Instead they POST to
`${jwtIssuer}/turnstile` on the api-worker (authenticated with the
existing `apiKey`), which holds the secret and proxies to Cloudflare.
Shrinks blast radius and removes the secret from every game host + GH
Actions workflow.

Response from the api-worker is Zod-validated; null tokens short-circuit
to `rejected` locally.

## Please complete the following:

- [x] I have added screenshots for all UI updates (n/a — server only)
- [x] I process any text displayed to the user through translateText()
(n/a — no user-visible text)
- [ ] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced

## Discord:

evanpelle
v0.31.7
2026-05-04 12:53:02 -06:00
Aotumuri 8e55bf9593 Remove emoji from user settings (#3838)
## Description:

Other settings previously included emojis, but those have since been
removed.
This change updates the user settings to keep the UI consistent.

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

Co-authored-by: Ryan <7389646+ryanbarlow97@users.noreply.github.com>
2026-05-04 16:19:11 +00:00
Aotumuri 1bf7df1b68 Fix mobile logo spacing (#3842)
Resolves
#https://discord.com/channels/1359946986937258015/1381347989464809664/1500830892405424168

## Description:
Fixes a mobile layout issue where a large gap appeared below the
OpenFront logo, causing fewer menu options to be visible without
scrolling.

before
<img width="591" height="910" alt="スクリーンショット 2026-05-04 21 32 32"
src="https://github.com/user-attachments/assets/7d9de0de-8d19-4e54-bec6-2bc3b9dda6a5"
/>

after
<img width="603" height="1311" alt="OpenFront (ALPHA)"
src="https://github.com/user-attachments/assets/e606feee-0f33-4a8c-b100-514005a0d2aa"
/>


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

Co-authored-by: Ryan <7389646+ryanbarlow97@users.noreply.github.com>
2026-05-04 16:16:40 +00:00
Aotumuri 8ea3426628 fix: Show full store item names instead of truncating them (#3831)
## Description:

The store item cards were truncating names with an ellipsis. This change
updates the cosmetic card name label to wrap instead of truncating, so
the full name is always shown.

before
<img width="748" height="363" alt="スクリーンショット 2026-05-04 10 26 58"
src="https://github.com/user-attachments/assets/32030be3-6e92-4ca6-8117-451c0ae75582"
/>

after
<img width="756" height="585" alt="スクリーンショット 2026-05-04 10 27 30"
src="https://github.com/user-attachments/assets/20e0fd36-dea4-4236-852b-ca5a2cd7e0f5"
/>

## 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
2026-05-04 11:28:03 +00:00
evanpelle 257fb9b38e temporarily disable turnstile v0.31.3 2026-05-03 18:50:59 -06:00
FloPinguin 3a24383e88 Fix map land tile lookup broken by asset URL migration 🗺️ (#3826)
## Description:

`MapLandTiles` was fetching map manifests via HTTP at
`http://localhost:3000/maps/<map>/manifest.json`. This stopped working
after PR #3494 moved all public assets from stable paths (e.g.
`/maps/...`) to content-hashed paths under `/_assets/...`. The master
server no longer serves `/maps/` -- requests fell through to the SPA
handler, returned `index.html`, failed JSON parsing, and silently fell
back to the default `1_000_000` land tile count.

With 1M tiles, `calculateMapPlayerCounts` produces `[50, 40, 25]`
instead of the real values (e.g. `[185, 140, 95]` for Alps), causing all
public lobbies to be capped at 25-50 players regardless of map.

Fixes this by reading map manifests directly from disk instead of via
HTTP:
- In production: resolves the source path through
`getRuntimeAssetManifest()` to the hashed file under `static/_assets/`,
then reads it with `fs.readFile`.
- In dev: falls back to `resources/maps/<name>/manifest.json` directly
(the Dockerfile removes `resources/maps` in production, so this branch
only runs locally).

Also adds an in-process cache so each map manifest is only read once per
server lifetime.

Verified that it works on
https://fix-map-land-tiles-asset-manifest.openfront.dev/ and locally.

## 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
v0.31.2
2026-05-03 14:31:00 -06:00
FloPinguin e0e98e2cf3 Fix map land tile lookup broken by asset URL migration 🗺️ (#3826)
## Description:

`MapLandTiles` was fetching map manifests via HTTP at
`http://localhost:3000/maps/<map>/manifest.json`. This stopped working
after PR #3494 moved all public assets from stable paths (e.g.
`/maps/...`) to content-hashed paths under `/_assets/...`. The master
server no longer serves `/maps/` -- requests fell through to the SPA
handler, returned `index.html`, failed JSON parsing, and silently fell
back to the default `1_000_000` land tile count.

With 1M tiles, `calculateMapPlayerCounts` produces `[50, 40, 25]`
instead of the real values (e.g. `[185, 140, 95]` for Alps), causing all
public lobbies to be capped at 25-50 players regardless of map.

Fixes this by reading map manifests directly from disk instead of via
HTTP:
- In production: resolves the source path through
`getRuntimeAssetManifest()` to the hashed file under `static/_assets/`,
then reads it with `fs.readFile`.
- In dev: falls back to `resources/maps/<name>/manifest.json` directly
(the Dockerfile removes `resources/maps` in production, so this branch
only runs locally).

Also adds an in-process cache so each map manifest is only read once per
server lifetime.

Verified that it works on
https://fix-map-land-tiles-asset-manifest.openfront.dev/ and locally.

## 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
2026-05-03 14:30:25 -06:00
evanpelle ac679b68c5 update cache bust version to invalid bad response headers v0.31.1 2026-05-03 10:14:19 -06:00
evanpelle 5d6c48ebf2 Revert "Fix winner stats spoofing exploit"
This reverts commit 819edb21bb.
v0.31.0
2026-05-03 09:54:50 -06:00
FloPinguin 4cd6f50c03 Nations: Fix city farming + reactive defense posts + fix nuked territory capture 🛡️ (#3814)
## Description:

Would be very good to get these fixes last minute into v31.

- **Farming nations for cities is fixed**: Here you can see city farming
in action, vari farms Finland:
https://www.youtube.com/watch?v=J4J0ajlnSHs&t=137s - Lots of 125k gold
cities... Now nations will build defense posts instead of cities:

- **Nations now build defense posts reactively** instead of through the
normal structure build order. When a nation is under significant land
attack (incoming/own troops >= 35%), it places a defense post near the
attack front -- skipped on Easy, capped at 1 on Medium, and scaled by
the incoming troop ratio on Hard/Impossible. Posts spread along the
front. The old `defensePostValue()` placement path is removed.

- **Nations now capture nuked territory.**
`hasLandBorderWithTerraNullius()` was incorrectly filtering out tiles
with fallout, causing the `nuked` attack strategy to never dispatch a
attack. Big bug

.

- [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
v0.31.0-test
2026-05-03 09:33:44 -06:00
FloPinguin 58ec8b280f Nations: Fix city farming + reactive defense posts + fix nuked territory capture 🛡️ (#3814)
## Description:

Would be very good to get these fixes last minute into v31.

- **Farming nations for cities is fixed**: Here you can see city farming
in action, vari farms Finland:
https://www.youtube.com/watch?v=J4J0ajlnSHs&t=137s - Lots of 125k gold
cities... Now nations will build defense posts instead of cities:

- **Nations now build defense posts reactively** instead of through the
normal structure build order. When a nation is under significant land
attack (incoming/own troops >= 35%), it places a defense post near the
attack front -- skipped on Easy, capped at 1 on Medium, and scaled by
the incoming troop ratio on Hard/Impossible. Posts spread along the
front. The old `defensePostValue()` placement path is removed.

- **Nations now capture nuked territory.**
`hasLandBorderWithTerraNullius()` was incorrectly filtering out tiles
with fallout, causing the `nuked` attack strategy to never dispatch a
attack. Big bug

.

- [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
2026-05-03 09:33:01 -06:00
RickD004 482d1b8bff Fix Bosphorus map (#3823)
## Description:

QoL changes for the Bosphorus map.

The base image for the map had a little aliasing which resulted in some
rivers being cut off.

<img width="673" height="386" alt="image"
src="https://github.com/user-attachments/assets/b8ed181f-fbeb-4d6f-b7ab-a8b0ea300a22"
/>

All of the nations except istanbul also had absolutely nothing to do
with the region. For example, Varna is a city in Northeast bulgaria and
the aegean isles are also nowhere near. There was also a nation that did
not spawn because its coordinates were in the sea.

<img width="626" height="413" alt="image"
src="https://github.com/user-attachments/assets/a6537f79-3785-4316-8fd4-a99f55faff71"
/>

All of these poor designs are probably the result of the map being
resized, originally being a larger map. It probably explains why this is
the smallest map by land area (not counting Oceania)

Fixes:

- Fixed landlocked rivers and added More accurate bodies of water

- Complete remake of the nations. Nations are now far more accurately
placed districts of the region, and more evenly placed

<img width="664" height="407" alt="image"
src="https://github.com/user-attachments/assets/ff5a34fc-dea0-4a3d-b798-39d5711b91af"
/>

The data and gamestyle of this map should not change much, as the
landmasses remain in practice the same

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

tri.star1011
2026-05-03 09:32:27 -06:00
VariableVince 213ddd36c9 Fix: remove unnecessary optional chain i left in (#3822)
## Description:

In PR 3654 i left an unnecessary question mark.

## 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
2026-05-03 15:23:34 +00:00
RickD004 23a1538c7e Fix Bosphorus map (#3823)
## Description:

QoL changes for the Bosphorus map.

The base image for the map had a little aliasing which resulted in some
rivers being cut off.

<img width="673" height="386" alt="image"
src="https://github.com/user-attachments/assets/b8ed181f-fbeb-4d6f-b7ab-a8b0ea300a22"
/>

All of the nations except istanbul also had absolutely nothing to do
with the region. For example, Varna is a city in Northeast bulgaria and
the aegean isles are also nowhere near. There was also a nation that did
not spawn because its coordinates were in the sea.

<img width="626" height="413" alt="image"
src="https://github.com/user-attachments/assets/a6537f79-3785-4316-8fd4-a99f55faff71"
/>

All of these poor designs are probably the result of the map being
resized, originally being a larger map. It probably explains why this is
the smallest map by land area (not counting Oceania)

Fixes:

- Fixed landlocked rivers and added More accurate bodies of water

- Complete remake of the nations. Nations are now far more accurately
placed districts of the region, and more evenly placed

<img width="664" height="407" alt="image"
src="https://github.com/user-attachments/assets/ff5a34fc-dea0-4a3d-b798-39d5711b91af"
/>

The data and gamestyle of this map should not change much, as the
landmasses remain in practice the same

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

tri.star1011
2026-05-03 15:21:29 +00:00
evanpelle 819edb21bb Fix winner stats spoofing exploit
Previously, winnerVotes was keyed only on winner, so a client could send the correct winner with spoofed allPlayersStats and have their vote count toward the majority. The key is now a SHA-256 hash of both winner and allPlayersStats together, so any stats divergence produces a distinct key that must independently reach majority.

When the winner is confirmed, the log now includes votesByKey — a summary of every distinct key, its vote count, and winner value — making stat manipulation visible in the logs.
v0.31.0-beta2
2026-05-02 13:47:19 -06:00
evanpelle bf74028200 Fix medal icon CORS errors by inlining SVG as data URI
CSS mask-image triggers a CORS fetch, which failed for the CDN-hosted medal SVG. Switched to a Vite ?raw import so the SVG is embedded as a data URI at build time — no network request, no CORS.

Also stripped the SVG of Inkscape metadata and replaced filter-based color inversion with a plain fill="white", shrinking it from 3,278 → 955 bytes (387 bytes gzipped).
2026-05-02 12:54:29 -06:00
evanpelle 22dbc4fbb8 meta: increase alt/current attackerTroopLoss to 60/40 v0.31.0-beta1 2026-05-02 09:44:34 -06:00
evanpelle ba57da35e2 Increase port build time to 5 seconds 2026-05-02 09:43:19 -06:00
evanpelle 23a9d2fcee meta: increase nuke speed to 8 tiles per tick 2026-05-02 09:41:31 -06:00
evanpelle 41ed31efa3 meta: make sam & missile silo cooldown 90 ticks 2026-05-02 09:39:48 -06:00
evanpelle 1be197229a meta: make tribes slightly weaker to speed up the early game 2026-05-02 09:36:44 -06:00
evanpelle f850bdb605 fix(tests): update AttackStats to expect 50% war gold for human conquests 2026-05-02 09:33:14 -06:00
Evan f90e73c2f7 conqueror receives 50% of gold when conquering a human player (#3818)
## Description:

The motivation is to prevent snowballing players from also gaining too
much gold by conquering other players

- Adds `conquerGoldAmount` to `Config`/`DefaultConfig`: returns 100% of
captured gold for bots/nations, 50% for human players
- Updates `GameImpl.conquerPlayer` to use this amount for the
conqueror's gold gain (the conquered player still loses their full gold)

## 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
2026-05-02 09:23:49 -06:00
Evan bcdc2126c6 bugfix: SAM was only reloading when not in cooldown (#3817)
## Description:

reloadMissile() was inside the isInCooldown() block. For level-2+ SAMs,
isInCooldown() returns queue.length === level, so after firing one of
two missiles (queue.length = 1 < level = 2) the SAM is not in cooldown —
meaning expired timers were never cleaned up. Stale queue entries caused
subsequent shots to be treated as still-cooling even after the cooldown
elapsed.

SAM execution now mirrors the missile silo execution

## 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
2026-05-02 09:05:10 -06:00
evadua f5a91b8aa3 Map accuracy & consistency pass: nation names, spawn positions, and flags across 9 maps (#3780)
## Description:

Comprehensive accuracy and quality-of-life improvements across 8 maps.
No gameplay mechanics changed: only nation names, spawn positions, and
flag codes. All changes bring maps closer to real-world geographic and
historical accuracy.

**Changes by map:**

1. **North America:** Corrected numerous incorrect state spawn
positions. Added all 13 Canadian provinces and territories with correct
flags, as well as a few additional bots for balancing and completeness.
2. **South America:** Corrected spawn positions of Venezuela, Suriname,
and French Guiana. Added four Brazilian states (Amazonas, Pará, Bahia,
São Paulo) for better regional coverage and balancing.
3. **Gateway to the Atlantic:** Full historical consistency pass
targeting the ~1340-1410 CE period, matching the existing Britannia and
Italia map style. Renamed several nations for historical accuracy (Duchy
of Burgundy, Kingdom of Navarre, Kingdom of Majorca, City of Avignon,
Crown of Aragon, Duchy of Aquitaine, Hafsid Sultanate, Marinid
Sultanate, Zayyanid Sultanate, Holy Roman Empire). Added 7 new
historically accurate flag SVGs for these nations.
4. **Europe:** Shortened long-form nation names to short-form for
consistency with other maps. Added Andorra and Monaco for improved
balance.
5. **Europe Classic:** Fixed "Syrian Arab Republic" to "Syria" for
consistency with all other maps. Added Baltic states, Croatia, Denmark,
Sápmi for balancing.
6. **Oceania:** Removed ghost bots that no longer appear on the map.
Fixed truncated and outdated names: Lao PDR to Laos, Brunei Darussalam
to Brunei, TimorLeste to Timor Leste, Taiwan Province of China to
Taiwan.
7. **World:** Fixed outdated names for accuracy and consistency with the
World map and other maps. Added bots in regions lacking coverage for
more consistent global representation.
8. **Giant World Map:** Updated nation names for accuracy and
consistency. Added Canadian provinces, US states, Bolivia, and Gabon for
improved map balance.

All changes made and verified in the map editor. No en.json or UI
changes required as these are map data files only.

## 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:
@islandspiritozempic
2026-05-02 08:33:23 -06:00
VariableVince 775d9a0f0c Chore(deps): Update pixijs to 8.18.1 (#3812)
## Description:

Update pixijs to 8.18.1, mostly because we might want to use the ability
to send AutoDetectRenderer an array as "preference". And because we want
to stay up-to-date with fixes to a renderer we use.

## Please complete the following:

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

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

tryout33
2026-05-02 08:32:41 -06:00
FloPinguin 0cb17f8086 Fix build: add missing adfree field to ResolveCosmetics test mock 🔧 (#3816)
## Description:

Commit `4d5b7c0` added `adfree: boolean` as a required field to
`UserMeResponseSchema` in `ApiSchemas.ts`, but did not update the mock
object in `tests/ResolveCosmetics.test.ts`. This caused `tsc --noEmit`
to fail with a type overlap error, breaking the production build.

**Fix:** Add `adfree: false` to the `player` mock inside `makeUserMe()`
in the test file.

## Please complete the following:

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

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

FloPinguin
2026-05-02 08:32:10 -06:00
dependabot[bot] 77462b44eb Bump toshimaru/auto-author-assign from 3.0.1 to 3.0.2 in the updates group (#3813)
Bumps the updates group with 1 update:
[toshimaru/auto-author-assign](https://github.com/toshimaru/auto-author-assign).

Updates `toshimaru/auto-author-assign` from 3.0.1 to 3.0.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/toshimaru/auto-author-assign/releases">toshimaru/auto-author-assign's
releases</a>.</em></p>
<blockquote>
<h2>v3.0.2</h2>
<!-- raw HTML omitted -->
<h2>What's Changed</h2>
<h3>Dependencies</h3>
<ul>
<li>build(deps-dev): bump <code>@​rollup/plugin-commonjs</code> from
29.0.0 to 29.0.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/toshimaru/auto-author-assign/pull/154">toshimaru/auto-author-assign#154</a></li>
<li>build(deps-dev): bump rollup from 4.54.0 to 4.60.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/toshimaru/auto-author-assign/pull/155">toshimaru/auto-author-assign#155</a></li>
<li>build(deps-dev): bump rollup from 4.60.0 to 4.60.1 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/toshimaru/auto-author-assign/pull/159">toshimaru/auto-author-assign#159</a></li>
<li>build(deps): bump picomatch from 4.0.3 to 4.0.4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/toshimaru/auto-author-assign/pull/157">toshimaru/auto-author-assign#157</a></li>
<li>build(deps-dev): bump rollup from 4.60.1 to 4.60.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/toshimaru/auto-author-assign/pull/162">toshimaru/auto-author-assign#162</a></li>
<li>build(deps): bump <code>@​actions/core</code> from 2.0.1 to 3.0.1 by
<a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/toshimaru/auto-author-assign/pull/150">toshimaru/auto-author-assign#150</a></li>
<li>build(deps): bump <code>@​actions/github</code> from 6.0.1 to 9.1.1
by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/toshimaru/auto-author-assign/pull/160">toshimaru/auto-author-assign#160</a></li>
<li>build(deps): bump googleapis/release-please-action from 4 to 5 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/toshimaru/auto-author-assign/pull/165">toshimaru/auto-author-assign#165</a></li>
</ul>
<h3>Others</h3>
<ul>
<li>chore(main): release 3.0.2 by <a
href="https://github.com/github-actions"><code>@​github-actions</code></a>[bot]
in <a
href="https://redirect.github.com/toshimaru/auto-author-assign/pull/164">toshimaru/auto-author-assign#164</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/toshimaru/auto-author-assign/compare/v3.0.1...v3.0.2">https://github.com/toshimaru/auto-author-assign/compare/v3.0.1...v3.0.2</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/toshimaru/auto-author-assign/blob/main/CHANGELOG.md">toshimaru/auto-author-assign's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<h2><a
href="https://github.com/toshimaru/auto-author-assign/compare/v3.0.1...v3.0.2">3.0.2</a>
(2026-04-27)</h2>
<h3>Miscellaneous Chores</h3>
<ul>
<li>release 3.0.2 (<a
href="https://github.com/toshimaru/auto-author-assign/commit/658b95bf703955e926268fcaca1124037270bea8">658b95b</a>)</li>
<li>release 3.0.2 (<a
href="https://github.com/toshimaru/auto-author-assign/commit/ca59fc3261247bab40337927fac848bf2a60863f">ca59fc3</a>)</li>
</ul>
<h2><a
href="https://github.com/toshimaru/auto-author-assign/compare/v3.0.0...v3.0.1">3.0.1</a>
(2025-12-25)</h2>
<h3>Miscellaneous Chores</h3>
<ul>
<li>release 3.0.1 (<a
href="https://github.com/toshimaru/auto-author-assign/commit/718d4ed5349747d47952ae841ae03fcbdd74ebea">718d4ed</a>)</li>
</ul>
<h2><a
href="https://github.com/toshimaru/auto-author-assign/compare/v2.1.2...v3.0.0">3.0.0</a>
(2025-12-21)</h2>
<h3>Features</h3>
<ul>
<li>Add <code>npm run package</code> instead of <code>build</code> (<a
href="https://redirect.github.com/toshimaru/auto-author-assign/issues/130">#130</a>)
(<a
href="https://github.com/toshimaru/auto-author-assign/commit/972720f0403d2873e807f16e350c5b0b1be4dda3">972720f</a>)</li>
</ul>
<h3>Miscellaneous Chores</h3>
<ul>
<li>release 3.0.0 (<a
href="https://github.com/toshimaru/auto-author-assign/commit/d100ceff34d1e9cd2c4ea5b8055922f1409f3068">d100cef</a>)</li>
</ul>
<h3><a
href="https://github.com/toshimaru/auto-author-assign/compare/v2.1.1...v2.1.2">2.1.2</a>
(2025-12-16)</h3>
<h3><a
href="https://github.com/toshimaru/auto-author-assign/compare/v2.1.0...v2.1.1">2.1.1</a>
(2024-06-26)</h3>
<h2><a
href="https://github.com/toshimaru/auto-author-assign/compare/v2.0.1...v2.1.0">2.1.0</a>
(2024-01-17)</h2>
<h3><a
href="https://github.com/toshimaru/auto-author-assign/compare/v2.0.0...v2.0.1">2.0.1</a>
(2023-09-26)</h3>
<h2><a
href="https://github.com/toshimaru/auto-author-assign/compare/v1.6.2...v2.0.0">2.0.0</a>
(2023-09-24)</h2>
<h3><a
href="https://github.com/toshimaru/auto-author-assign/compare/v1.6.1...v1.6.2">1.6.2</a>
(2023-01-03)</h3>
<ul>
<li>chore: dependencies update</li>
</ul>
<h3><a
href="https://github.com/toshimaru/auto-author-assign/compare/v1.6.0...v1.6.1">1.6.1</a>
(2022-08-01)</h3>
<ul>
<li>doc: README Update</li>
</ul>
<h3><a
href="https://github.com/toshimaru/auto-author-assign/compare/v1.5.1...v1.6.0">1.6.0</a>
(2022-07-28)</h3>
<ul>
<li>feat: Add auto-author-assign for the issues</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/toshimaru/auto-author-assign/commit/bdd7688cbf9e6d5683f02f8c7d8ae4062a254b6d"><code>bdd7688</code></a>
chore(main): release 3.0.2 (<a
href="https://redirect.github.com/toshimaru/auto-author-assign/issues/164">#164</a>)</li>
<li><a
href="https://github.com/toshimaru/auto-author-assign/commit/658b95bf703955e926268fcaca1124037270bea8"><code>658b95b</code></a>
chore: release 3.0.2</li>
<li><a
href="https://github.com/toshimaru/auto-author-assign/commit/c14bd3bc8fcae805c462193f1fec685b5757fa14"><code>c14bd3b</code></a>
build(deps): bump googleapis/release-please-action from 4 to 5 (<a
href="https://redirect.github.com/toshimaru/auto-author-assign/issues/165">#165</a>)</li>
<li><a
href="https://github.com/toshimaru/auto-author-assign/commit/ca59fc3261247bab40337927fac848bf2a60863f"><code>ca59fc3</code></a>
chore: release 3.0.2</li>
<li><a
href="https://github.com/toshimaru/auto-author-assign/commit/725d1cbcd9c65264223e93ed01bae5a1166775b5"><code>725d1cb</code></a>
build(deps): bump <code>@​actions/github</code> from 6.0.1 to 9.1.1 (<a
href="https://redirect.github.com/toshimaru/auto-author-assign/issues/160">#160</a>)</li>
<li><a
href="https://github.com/toshimaru/auto-author-assign/commit/88a48cc86aa175353a6bedf0f62180f85cba6dc0"><code>88a48cc</code></a>
build(deps): bump <code>@​actions/core</code> from 2.0.1 to 3.0.1 (<a
href="https://redirect.github.com/toshimaru/auto-author-assign/issues/150">#150</a>)</li>
<li><a
href="https://github.com/toshimaru/auto-author-assign/commit/6a5f2a2150e1a0ba864721da16968b0d612555e3"><code>6a5f2a2</code></a>
build(deps-dev): bump rollup from 4.60.1 to 4.60.2 (<a
href="https://redirect.github.com/toshimaru/auto-author-assign/issues/162">#162</a>)</li>
<li><a
href="https://github.com/toshimaru/auto-author-assign/commit/7dbebfbadd984a53a3092c634ae3f8054ed4f81d"><code>7dbebfb</code></a>
build(deps): bump picomatch from 4.0.3 to 4.0.4 (<a
href="https://redirect.github.com/toshimaru/auto-author-assign/issues/157">#157</a>)</li>
<li><a
href="https://github.com/toshimaru/auto-author-assign/commit/49588892f33bafe848a7f70c6960ec7805aabf4a"><code>4958889</code></a>
build(deps-dev): bump rollup from 4.60.0 to 4.60.1 (<a
href="https://redirect.github.com/toshimaru/auto-author-assign/issues/159">#159</a>)</li>
<li><a
href="https://github.com/toshimaru/auto-author-assign/commit/40b645548e95cef9fed45bba6f49491d28a6fe9b"><code>40b6455</code></a>
build(deps-dev): bump rollup from 4.54.0 to 4.60.0 (<a
href="https://redirect.github.com/toshimaru/auto-author-assign/issues/155">#155</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/toshimaru/auto-author-assign/compare/4d585cc37690897bd9015942ed6e766aa7cdb97f...bdd7688cbf9e6d5683f02f8c7d8ae4062a254b6d">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=toshimaru/auto-author-assign&package-manager=github_actions&previous-version=3.0.1&new-version=3.0.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-02 08:31:50 -06:00
evanpelle d071c8228f Add cache busting to asset urls to bust assets with bad headers 2026-05-02 07:26:06 -06:00
evanpelle 4d5b7c0fb6 Use adfree flag to suppress ads
Adds adfree: boolean to player in UserMeResponseSchema and replaces the flares-length heuristic in Main.ts with a direct check of this field to determine whether ads should be shown.
2026-05-01 18:39:23 -06:00
VariableVince 914c7e750f Remove "uuid" dependency (#3811)
## Description:

One dependency less: remove uuid. It is only used to get the three
random digits after "Anon" if no name is present in localStorage.
Crypto.randomUUID also gives us a UUID v4 and can already be used from
Utils > generateCryptoRandomUUID. Not noticable when it comes to speed
either.

## 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
2026-05-01 17:00:45 -06:00
Patrick Plays Badly a93c466334 Update maps Los Angeles & Dyslexdria (#3809)
## Description:
Removed single pixel line from the bottom of LA map.
Added L.A.X. nation to LA map.
Removed USSR flags from Dyslexdria (originally imported from giant world
map). Left USSR flag on 'Rusha' only.

## 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
PlaysBadly
2026-05-01 13:04:48 +00:00
Ryan df05d21fc2 Clan System Part 2 - UI (#3625)
## Description:

Continuation from #3276 

Adds the complete client-side clan UI as a Lit web component
(`<clan-modal>`), a typed API client with Zod-validated responses,
shared response schemas, and a reusable `<confirm-dialog>` component.


### New: `ClanModal.ts`

| View | What it does |
|------|-------------|
| **My Clans** | Lists joined clans + pending join requests (built from
`/users/@me`, no extra fetches) |
| **Browse** | Search by tag (min 3 chars), paginated results,
configurable per-page (10/25/50) |
| **Clan Detail** | Stats, paginated + searchable member list, role
badges, join/leave/request actions |
| **Manage** | Edit name (max 35 chars) + description, toggle
open/invite-only, disband |
| **Transfer** | Leadership transfer with member selector + confirmation
|
| **Requests** | Approve/deny join requests (leader/officer) |
| **Bans** | View and unban (leader/officer) |
| **My Requests** | View and withdraw outgoing requests |

### New: `ConfirmDialog.ts`

Reusable `<confirm-dialog>` Lit component — replaces native
`confirm()`/`prompt()` which are blocked or broken on mobile and
CrazyGames iframes. Supports danger/warning variants and an optional
textarea (used for ban reasons). Fires `confirm`/`cancel` events.

### New: `ClanApi.ts`

Typed API client covering all clan endpoints. Every response is
Zod-validated. Auth header is always last in the spread (can't be
overridden by callers). Unknown server error messages always fall back
to a generic client-side string — never displayed verbatim.

### New: `ClanApiSchemas.ts` (in `src/core/`)

Shared Zod schemas for clan API responses with max-length constraints on
`name` (35) and `description` (200). Lives in `core/` so it can be
consumed by both client code and the leaderboard table.

### Modified: `ApiSchemas.ts`

- Added `clans` and `clanRequests` arrays to `UserMeResponseSchema`
- Moved clan leaderboard schemas out to `ClanApiSchemas.ts`
- Renamed `LeaderboardClanTagSchema` → `RequiredClanTagSchema`

### Modified: `Api.ts`

- Added `invalidateUserMe()` to bust the cached `/users/me` response
after mutations
- Removed `fetchClanLeaderboard` (moved to `ClanApi.ts`)

### Tests

- `ClanModal.test.ts` — rendering, view navigation, user actions
- `ClanApiQueries.test.ts` — fetch functions, error handling, pagination
- `ClanApiMutations.test.ts` — join, leave, kick, ban, promote,
transfer, etc.
- `ClanApiBans.test.ts` — ban/unban calls and error paths
- `ClanApiSchemas.test.ts` — Zod schema validation edge cases
- `LeaderboardModal.test.ts` — updated imports

## Notable design decisions

- **Not-logged-in state** — shows "Sign in to join clans" instead of
false "no clans" empty state
- **Rate limit feedback** — reads `Retry-After` header and surfaces wait
time to the user

## 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: evanpelle <evanpelle@gmail.com>
2026-04-30 21:27:35 -06:00
evanpelle 38bbef6ecf update structure icon filename to bust cache, previous assets had bad headers 2026-04-30 20:18:38 -06:00
evanpelle 1f549d0a03 add malibu glow on hover to ranked, join, create lobby buttons 2026-04-30 17:23:11 -06:00