Movement & Travel Times¶
Canonical model for how ships traverse sectors, what Ship.current_speed actually does, what a warp tunnel costs to traverse, and how wall-clock travel time emerges from the turn-regen pipeline. This doc is the single source of truth on the movement model — ship-roster.md carries the per-ship speed values, ship-systems.md covers the Engine upgrade, sectors.md covers warp-tunnel discovery and one-way mechanics, and turns.md covers the turn pool itself; this doc explains how those pieces compose.
The model in one paragraph¶
Movement is turn-gated and wall-clock-instantaneous. A traversal costs a fixed number of turns (1 for adjacent-sector direct warp, 1–3 for warp tunnels based on length, 0 for player-built warp gates, 50 for a Quantum Jump). The traversal commits instantly at the moment the player has the turns — there is no "in transit" wall-clock delay between origin and destination. Wall-clock time enters the picture only because the turn pool refills lazily at a fixed regen rate (ADR-0004): a player with a banked turn pool moves immediately, a player with an empty pool waits for turns to regenerate. Ship.current_speed does not change the turn cost of any traversal — it feeds Fleet.average_speed and is reserved for future combat-side hooks. Combat evasion (today's hit-probability driver) and escape success use other inputs entirely; see What Ship.current_speed does and does not do below.
What Ship.current_speed does and does not do¶
Ship.current_speed is a Float on Ship (column source: models/ship.py:Ship.current_speed, Ship.base_speed). The Engine upgrade adds +0.5 per level. Its actual consumers are narrower than legacy text suggested:
- Fleet stat denormalization —
Fleet.average_speed = mean(member.current_speed)is computed and stored on the Fleet row by_recalculate_fleet_stats(see fleet-tactics.md, fleet-coordination.md). Used by the fleet-pacing UI and as input to fleet-vs-fleet relative-speed mechanics where those exist. - Future combat-side hooks (📐 Design-only). Today's combat-resolver escape formula (
combat-resolver.md:122-126) reads ship type (FAST_ESCAPE_SHIP_TYPESflag for Fast Courier and Scout), hull damage, sector-edge proximity, and pursuer class — notcurrent_speeddirectly. Today's combat-resolver evasion is driven byShip.evasion(a separate column scaled by Sensor upgrades per ship-systems.md), not bycurrent_speed. Wiringcurrent_speedinto either formula is a 📐 Design-only future change; this doc reflects what the column actually does today.
It does not:
- Reduce sector turn cost. A Scout (speed 2.5) and a Cargo Hauler (speed 0.5) both pay the same
WarpTunnel.turn_costto traverse the same tunnel. - Add a real-time delay between origin and destination. Movement commits atomically when the player has the turns.
- Affect
WarpTunnel.properties.lengthortraversal_costreads. - Drive combat hit probability on the ship — that's the
Ship.evasioncolumn scaled by Sensor upgrades, not Engine. - Drive escape success — that's the
FAST_ESCAPE_SHIP_TYPESflag plus hull/edge/pursuer-class factors per the canonical formula incombat-resolver.md:122-126.
Ship speed values¶
From ship-roster.md → Capacity & speed:
| Ship | Base speed | Combat-archetype rationale |
|---|---|---|
| Scout Ship | 2.5 | Recon — fast, hard to hit, escapes well |
| Fast Courier | 2.0 | Time-critical cargo runs |
| Light Freighter | 1.0 | Generalist baseline |
| Defender | 1.0 | Combat platform — speed is sufficient, not the strength |
| Carrier | 0.75 | Capital hull — slow but devastating |
| Cargo Hauler | 0.5 | Capacity over agility |
| Colony Ship | 0.4 | Slowest non-pod hull — large, fragile |
| Warp Jumper | jump-only | No conventional speed; uses Quantum Jump |
| Escape Pod | very low | Survival shell, not a real ship |
Engine upgrade levels add +0.5 each. Practical caps are set by ShipSpecification.max_upgrade_levels.engine.
Movement primitives and their turn costs¶
Five primitives exist. Each has a different turn cost; the choice between them is a strategic decision the player makes per traversal.
| Primitive | Turn cost | Distance | Real-time gate | Notes |
|---|---|---|---|---|
| Direct warp (adjacent sector) | Ship.turn_cost (≈1) |
1 sector | None beyond turn regen | Standard sector-by-sector navigation |
Warp tunnel (natural or generator-placed ARTIFICIAL) |
WarpTunnel.turn_cost (1–3) |
2+ sectors (skips intermediate) | None beyond turn regen | Discovery-gated; long tunnels cost more |
| Player warp gate (player-built one-way) | 0 turns | Cross-region or long-distance | None | The speed advantage that justifies the gate's 1.1M cr build cost |
| Quantum Jump (Warp Jumper only) | 50 turns at commit | 5–15 sector hops along bearing | 24h jump cooldown + 4h scan cooldown | Multi-phase ritual; consumes 1 Quantum Charge per jump |
| Tractor tow through any of the above | Base cost + size surcharge (+1 / +2 / +3 / +5 turns by towed-ship size) | Same as the underlying primitive | Same | Hauler + towed pair as one combined contact |
Long warp tunnels¶
Warp tunnels carry a length attribute on WarpTunnel.properties JSONB (per ../../DATA_MODELS/galaxy.md#warptunnel). Length is the in-fiction physical extent of the tunnel — short tunnels link nearby sectors, long tunnels span across clusters or zones.
WarpTunnel.turn_cost (and its mirror properties.traversal_cost) is set by the generator from a length-based table:
| Length band | traversal_cost |
Typical use |
|---|---|---|
| Short (≤ 5 hop-units) | 1 turn | Cluster-internal links; the dominant case |
| Medium (6–10 hop-units) | 2 turns | Cluster-to-cluster within a zone |
| Long (11+ hop-units) | 3 turns | Zone-to-zone; cross-region long-haul; rare ESCAPE_HATCH inbound |
Hop-units approximate Euclidean distance between the tunnel's origin and destination sectors using their 3D coordinates. The mapping is generator-time and persisted on the row; gameplay reads turn_cost directly without recomputing.
Why turn cost caps at 3 instead of scaling indefinitely. Tunnels longer than the band 3 cap exist in the schema (the length field is not bounded), but the gameplay cost is clamped at 3 turns to keep the player's turn-pool budget predictable. Beyond ~3-turn cost, the design intent is that the tunnel should instead be a Quantum Jump destination (covered separately, with its own 50-turn commit cost and 24h cooldown gating) rather than a routine multi-turn traversal.
Real-time experience for a long tunnel. A 3-turn long tunnel costs the same number of turns whether the player is in the Scout (speed 2.5) or the Colony Ship (speed 0.4). Speed does not buy a faster traversal of long tunnels — only the gate-mediated 0-turn warp gate or the Quantum Jump primitive bypass the tunnel cost.
Quantum Jump¶
✅ Shipped. The Warp Jumper's signature long-range primitive. Pipeline at
services/gameserver/src/services/quantum_jump_service.py.
The Quantum Jump bypasses the warp graph and arrives at a sector several hops away along a player-chosen bearing. It is a three-phase, multi-step commit — scan, commit, resolve — not a one-click teleport. Each phase has its own resource cost, and the resolve step is allowed to fail when the player commits to a bearing with nothing reachable on it. Only the Warp Jumper hull can Quantum Jump.
Phase 1 — Bearing and scan¶
The player opens the Quantum Jump panel on a Warp Jumper and sees a 3D minimap of sectors within roughly 25 hop-units Euclidean distance. Selection is two-axis — yaw (horizontal bearing) and pitch (vertical bearing) — plus a range band:
| Range band | Distance | Gate |
|---|---|---|
| Near | 5–6 sectors | base scan cost |
| Mid | 7–8 sectors | base scan cost |
| Far | 9–10 sectors | +1 Quantum Shard to scan in this band |
| Extended | 12–15 sectors | locked behind Sensor L3; +1 Quantum Shard to scan in this band |
A scan costs 5 turns. The server projects a 15° half-angle cone along the chosen bearing out to the chosen range band and returns fuzzy intelligence — a resonance band, a texture word, and a binary hostile-presence echo — under the disclosure rules in ../galaxy/sectors.md. Scans can be repeated with adjusted bearings to triangulate; results expire after 10 real-minutes, so triangulation is bounded by a usable window. A 15% misread probability applies per scan, reduced 5 percentage points per Sensor level (L1 = 10%, L2 = 5%, L3 = 0%). A 4-hour scan cooldown runs on the Warp Jumper, decoupled from the jump cooldown so scanning cannot be spammed on the way back from a jump.
Each scan emits an anonymous "long-range quantum sweep detected" event in the destination cone. The event's bearing precision is degraded to ±45° and delivery is delayed 30 seconds before it reaches any listeners in that area. The defender learns someone is sweeping, but not who or exactly where from.
Phase 2 — Commit¶
The player commits to a chosen bearing and range band. Commit consumes:
- 1 Quantum Charge — a refined consumable produced 1-Shard-to-1-Charge at any Class-3+ station or SpaceDock up front (the same venue rule as Quantum Crystal assembly). Quantum Charges sit in the Warp Jumper's special-equipment slot, not regular cargo, and are spent at commit time.
- 50 turns.
- A 24-hour Quantum Jump cooldown on the player, beginning from the commit timestamp.
- A lock on the Warp Jumper for the duration of resolve — it cannot move, dock, or transfer until resolve completes.
Once committed, the bearing and range band are final; there is no abort.
Phase 3 — Resolve¶
The server projects the committed bearing to the committed range and selects a destination:
- Find candidates within an accuracy radius of 1.5 inter-sector spacings of the projected point.
- If candidates exist, pick one weighted by inverse distance to the projection point.
- If none exist, expand the radius once by 1.5× and repeat.
- If still none, the jump misfires: the Warp Jumper arrives in the nearest existing sector on the bearing line at a distance shorter than the committed range, taking a flat 5% hull damage that insurance does not cover (a navigation hazard, not a destruction event). The Quantum Charge, the 50 turns, and the 24-hour cooldown are all consumed regardless.
On a successful resolve the Warp Jumper arrives at the picked candidate sector and the lock releases.
Quantum Jump is also the only primitive that reaches the lost-formation set — see Cross-region travel below.
Wall-clock travel time¶
Wall-clock time is a function of:
- Turn cost of the chosen primitive (above table).
- Player's banked turns at the moment of attempt.
- Turn-regen rate while waiting for turns to refill if banked is insufficient.
Turn-regen rate¶
From turns.md:
base_rate = 1000 / 86400 ≈ 0.01157 turns/sec
effective_rate = base_rate × Player.aria_bonus_multiplier
seconds_per_turn = 1.0 / effective_rate
aria_bonus_multiplier is set by the consciousness-level table — 1.0 at L1 Dormant up to 1.5 at L5 Transcendent. So:
| ARIA level | Multiplier | Seconds per turn | Turns per hour |
|---|---|---|---|
| L1 Dormant | 1.0× | 86.4 sec | 41.7 |
| L2 Aware | 1.1× | 78.5 sec | 45.8 |
| L3 Awakened | 1.2× | 72.0 sec | 50.0 |
| L4 Sentient | 1.35× | 64.0 sec | 56.3 |
| L5 Transcendent | 1.5× | 57.6 sec | 62.5 |
From turn cost to wall clock¶
wall_clock_seconds = max(0, (turn_cost − banked_turns) × seconds_per_turn)
Worked examples (assume L1 Dormant, banked = 0):
| Traversal | Turn cost | Wall-clock seconds | Wall-clock minutes |
|---|---|---|---|
| Direct warp | 1 | 86 | 1.4 min |
| Short warp tunnel | 1 | 86 | 1.4 min |
| Medium warp tunnel | 2 | 173 | 2.9 min |
| Long warp tunnel | 3 | 259 | 4.3 min |
| Quantum Jump commit | 50 | 4,320 | 72.0 min (1.2 hrs) |
| Warp gate | 0 | 0 | instant |
If the player is at L5 Transcendent ARIA with the same empty turn pool, divide by 1.5: a long tunnel falls to 173 seconds (~2.9 min); a Quantum Jump commit falls to 2,880 seconds (~48 min).
If the player has a full turn pool (1,000 turns banked at the default cap), every primitive except Quantum Jump is wall-clock instantaneous, and even a 50-turn Quantum Jump commit only costs the next 50-turn segment of regen time (since the 50 was already banked). Banked turns are the entire point of the turn pool — they're what lets a player burst through a multi-tunnel route in a single play session.
When wall-clock matters¶
Most regular play is unaffected: a player with 50+ turns banked moves through ordinary navigation with zero perceptible delay. Wall-clock starts to bite when:
- A new player has just spent down their starter pool and is rebuilding it.
- A player chains multiple Quantum Jumps in succession (each commit eats 50 banked turns and the cooldown wall is real-time, not turn-based).
- A player attempts a long-tunnel-heavy route after a combat encounter that drained the pool.
- A player is at low ARIA consciousness and high regional taxes have eroded their effective time budget.
The wall-clock regen design is intentional: it caps the per-day playtime depth without explicit time-gating, makes high-tier ARIA progression valuable, and gives Quantum Jump's cooldown teeth.
Fleet movement¶
Fleets move as a single combined contact. The fleet endpoint POST /api/v1/fleets/{id}/move (see fleet-coordination.md) routes the entire fleet together; per-ship movement is suppressed while in a fleet.
Fleet turn cost. A fleet pays the maximum turn cost any single member would pay — i.e., the slowest-tunnel-eligible ship in the fleet sets the pace, never the average. This means a Scout in a fleet with a Cargo Hauler still pays the Cargo Hauler's costs while in formation. Players who want Scout-pace mobility leave the fleet first.
Fleet.average_speed. Computed and stored on the fleet row, but used for fleet-vs-fleet pursuit and combat-escape calculations, not for fleet movement turn cost. A faster average_speed lets the fleet escape combat better and pursue routed enemies more reliably; it does not reduce traversal turn cost.
Quantum Jump in fleets. Only the Warp Jumper itself can Quantum Jump, and a Warp Jumper in a fleet must leave the fleet to jump (the jump is a per-ship primitive, not a fleet primitive). The post-jump pilot ejects to an escape pod at the destination per ADR-0029 only at Phase 3 of warp-gate construction; standalone Quantum Jumps don't sacrifice the hull.
Cross-region travel¶
Three primitives cross region boundaries; pick by what the player has available.
- Central Nexus warp-gate path (free for free-tier). Every player region attaches to the Central Nexus via a generator-placed warp gate (per
../../SYSTEMS/galaxy-generator-design.md#phase-14--region-attachment--statistics-rollup). Free-tier players can traverse home-region → Nexus → home-region (Nexus is universal). Galactic Citizens ($5/mo) extend this to Nexus → other-player-region. Each gate traversal costs 0 turns; the path is a chain of one-way gates (see../galaxy/warp-gates.md). - Long-distance ESCAPE_HATCH inbound. Some
ESCAPE_HATCHformations stamp a long-distance one-wayWarpTunnelfrom a far sector into a nearby sector (per ADR-0034). The arriving player learns they came from "an unknown sector" — origin discovery is investigation gameplay. This is not a chosen movement; it's a consequence of formation interaction. - Quantum Jump out of a stranded sector — when stranded behind a one-way warp, the Warp Jumper's Slipdrive can self-rescue (multi-turn charge, fuel cost scaled by graph distance to the nearest non-sink sector). Federation distress beacon is the alternative for non-Warp-Jumper hulls (free transport to nearest fedspace sector at the cost of
−10Terran Federation reputation, 24h cooldown, per ADR-0034).
Quantum Jump and lost formations (per ADR-0070). Quantum Jump is the only primitive that reaches the lost-formation set — LOST_SECTOR, LOST_CLUSTER, and ARCHIPELAGO formations (see ../galaxy/special-formations.md#lost-worlds-quantum-jump-only-content). The two Warp-Jumper primitives split cleanly: Quantum Jump is the discovery tool (it punches through the warp-graph wall to find lost formations), and the Slipdrive is the stranded-recovery tool (it self-rescues from WARP_SINK and similar one-way traps). A lost formation reached by Quantum Jump may still need Slipdrive to leave if no exit warp surfaced; the two primitives are complementary, not redundant.
Worked example: a typical journey¶
A Galactic Citizen owns a Light Freighter (speed 1.0, base turn cost 1). Their home region is 600 sectors deep; their target is a high-end commodity station in another player-owned region.
Route: 1. Home region sector 47 → Capital sector (47 hops via the proximity warp graph). Most hops are 1-turn direct warps; ~5 are 2-turn medium tunnels. Total: ~57 turns. 2. Capital sector → Nexus warp gate sector (in starter cluster). 1-turn direct warp. Total: 1 turn. 3. Nexus warp gate (home region → Nexus): 0 turns. 4. Nexus internal traversal to the destination region's gate (avg 8 hops, mix of 1-turn and 2-turn). Total: ~12 turns. 5. Nexus warp gate (Nexus → destination region): 0 turns. 6. Destination Capital → target station (~30 hops, similar mix). Total: ~38 turns.
Aggregate: ~108 turns one-way. At L3 Awakened ARIA (1.2× rate, 72 sec/turn), assuming the player started with a near-full 1,000-turn pool: trivially banked, wall-clock instantaneous if the player chains the move without combat or trading interruptions. If the player's pool is empty, ~108 × 72 = 7,776 seconds wall-clock = ~2 hours of regen wait — but realistically players bank turns and play in bursts, so the typical experience is "click, arrive, click, arrive."
A Cargo Hauler (speed 0.5) on the same route pays the same turn cost. The Cargo Hauler's 4× larger cargo hold is the trade for its lower combat evasion, not for any travel-time difference.
Status¶
🚧 Partial.
Ship.base_speedandShip.current_speedare columns; the Engine-upgrade+0.5delta is in the upgrade-spec target (per./ship-systems.md). Combat-escape and fleet-pacing reads ofcurrent_speedare partly wired (per combat-resolver.md). The length-band →WarpTunnel.turn_costmapping in the Long warp tunnels section is the design target — current generator code uses a flat 1-turn cost for natural tunnels and the schema'sproperties.lengthis not yet populated end-to-end. The wall-clock formulas above follow the ADR-0004 continuous-regen model:MovementServicelazily regenerates turns on each move (per../../SYSTEMS/turn-regeneration.md).
Source map¶
| Topic | Path (target) |
|---|---|
| Movement entry point | services/gameserver/src/services/movement_service.py:MovementService.move_player_to_sector |
| Fleet movement | services/gameserver/src/services/fleet_service.py:FleetService.move_fleet |
| Quantum Jump pipeline | services/gameserver/src/services/quantum_jump_service.py (✅ Shipped) |
| Turn-regen lazy entry | MovementService._regenerate_turns (per ADR-0004) |
Ship.current_speed reads |
combat_service.py (escape, evasion); fleet_service.py (_recalculate_fleet_stats) |
| Engine upgrade | ship_upgrade_service.py |
Cross-references¶
./turns.md— turn pool, regen formula, turn cost table../ship-roster.md— per-ship speed values../ship-systems.md— Engine upgrade ladder, scanner / sensor evasion stack../combat.md— combat evasion (driven byShip.evasion) and escape mechanics (driven byFAST_ESCAPE_SHIP_TYPESflag + hull / sector-edge / pursuer-class factors)../fleet-tactics.md— fleetaverage_speedand formation modifiers.../galaxy/sectors.md— natural warp tunnels, one-way warps, Quantum Jump spec.../galaxy/warp-gates.md— player-built warp gate construction and traversal.../../SYSTEMS/galaxy-generator-design.md— how the warp graph is laid down at generation time, includingWarpTunnel.properties.lengthassignment.../../SYSTEMS/combat-resolver.md— escape-success formula citing speed.../../SYSTEMS/fleet-coordination.md— fleet movement endpoint, average-speed denormalization.- ADR-0004 — continuous turn regeneration model.
- ADR-0030 — Quantum Jump multi-step commit.
- ADR-0034 — one-way warp tunnel design (for stranding-recovery context).