Add 500km link cap, block-height-based claim expiry, and link count in score
- MAX_LINK_DISTANCE_KM (default 500): flat cap on link length. Real Ingress scales this off portal/resonator level (up to ~655km); Regress has no leveling system to scale off of, so this is a single ceiling. - PORTAL_TIMEOUT_BLOCKS (default 2100): claims stamp the current Bitcoin block height (claimed_at_block, new migration) and expire back to neutral after this many blocks — the game's clock is block height, not wall-clock. Current height comes from mempool.space (BlockHeightService, 60s cache), same trust model as the BTC Map dependency. A background sweep actively reverts timed-out claims (tearing down their links, same as a normal recapture); claim/link routes also check inline so correctness doesn't depend on sweep timing between runs. - Pre-existing claims (already live in production) get backfilled with the real current block height once at startup rather than a guessed historical value — dry-run verified against an actual copy of the live production database before deploying. - Score now reports link count per team alongside places/fields/area (backend already computed this; only the frontend display was missing). 22 new tests (53 total): pure expiry-logic unit tests plus full claim/link/sweep integration tests using a network-free fake block-height provider (BlockHeightProvider interface + FakeBlockHeight test double).
This commit is contained in:
@@ -42,14 +42,27 @@ Map's public API.
|
||||
(default 40m) of it, via browser geolocation — no claiming from the couch.
|
||||
- Claiming an enemy-held place captures it for your team and tears down any
|
||||
links running through it.
|
||||
- A link can be created between any two places your team currently holds,
|
||||
as long as you're standing at the origin place — no maximum link distance.
|
||||
- A link can be created between any two places your team currently holds, as
|
||||
long as you're standing at the origin place, up to `MAX_LINK_DISTANCE_KM`
|
||||
(default 500km) apart. Ingress scales its link range off portal/resonator
|
||||
level (up to ~655km at max level); Regress has no leveling system to scale
|
||||
off of, so this is a single flat cap instead.
|
||||
- A new link can't cross any existing link (either team) — same as Ingress.
|
||||
Links sharing an endpoint don't count as crossing. See
|
||||
`services/geo.ts#segmentsIntersect` and `routes/links.ts`.
|
||||
- Three mutually-linked, same-team places form a field (computed live, not
|
||||
stored) — see `server/src/services/fields.ts`.
|
||||
- Team choice is one-way once made.
|
||||
- **Claims expire after `PORTAL_TIMEOUT_BLOCKS` Bitcoin blocks (default
|
||||
2100)** and revert to neutral, tearing down any links through them — the
|
||||
game's clock is block height, not wall-clock time. Current height comes
|
||||
from a public block explorer API (`BLOCK_HEIGHT_API_URL`, defaults to
|
||||
mempool.space), same trust model as pulling place data from BTC Map. A
|
||||
background sweep (`EXPIRY_SWEEP_INTERVAL_MS`, default 5 min) actively
|
||||
reverts timed-out claims; claim/link requests also check inline so
|
||||
correctness doesn't depend on sweep timing (`services/expiry.ts`).
|
||||
- Score (`GET /api/score`) reports claimed places, **link count**, field
|
||||
count, and total field area per team.
|
||||
|
||||
## Tests
|
||||
|
||||
|
||||
Reference in New Issue
Block a user