Docking & Refueling

Overview

Ships must dock with a station to receive services (fuel, future: repair, rearm, trade). Docking requires flying within tolerance of a station and matching velocity, then the ship locks to the station for the duration. This replaces the previous instant refueling system.

Docking Tolerance

Parameter Value
Distance tolerance 500 m from station center
Velocity tolerance 5 m/s relative to station

Both conditions must be satisfied simultaneously for a dock request to succeed.

Ship Docking State

Two new fields added to the Ship dataclass:

Field Type Default Description
docked_station_id str "" Station ID when docked, empty string when free-flying
docked_at_tick int 0 Game tick when docking occurred

A ship is considered docked when docked_station_id != "".

Docking Procedure (SERVICE_DOCK)

When a player requests SERVICE_DOCK with a target station:

  1. Validate not already docked — error E030 if ship.docked_station_id != ""
  2. Look up station — find station by ID from the service request’s target_body field
  3. Check distance|ship.position - station.position| must be ≤ 500 m
  4. Check relative velocity|ship.velocity - station.velocity| must be ≤ 5 m/s
  5. Set docked state:
    • ship.docked_station_id = station.station_id
    • ship.docked_at_tick = current_tick
  6. Zero all controls:
    • thrust_level = 0
    • rotation_input = Vec3(0, 0, 0)
    • translation_input = Vec3(0, 0, 0)
    • angular_velocity = Vec3(0, 0, 0)
    • attitude_mode = "none"
  7. Snap to station — set ship position and velocity to match station exactly
  8. Save to Redis — persist updated ship state

Error Codes

Code Condition
E030 Ship is already docked
E031 Ship is not docked (on undock attempt)
E032 Too far from station (> 500 m)
E033 Relative velocity too high (> 5 m/s)
E034 Station not found

Undocking Procedure (SERVICE_UNDOCK)

When a player requests SERVICE_UNDOCK:

  1. Validate docked — error E031 if ship.docked_station_id == ""
  2. Compute push-off directionnormalize(ship.position - station.position), or station’s forward axis if positions coincide
  3. Apply push-off velocityship.velocity = station.velocity + push_dir * 2.0 m/s
  4. Clear docked state:
    • ship.docked_station_id = ""
    • ship.docked_at_tick = 0
  5. Save to Redis

Physics While Docked

When ship.docked_station_id != "", the per-tick _update_ship() method:

  1. Locks position/velocity — copies station’s current position and velocity each tick
  2. Zeroes angular velocity — prevents any rotation
  3. Transfers fuel — if ship.fuel < ship.fuel_capacity:
    • transfer = min(FUEL_TRANSFER_RATE * dt * time_scale, ship.fuel_capacity - ship.fuel)
    • ship.fuel += transfer
    • Rate: 100 kg/s before time_scale multiplier
  4. Skips all integration — no gravity, no thrust, no attitude control
  5. Auto-undock safety — if the station no longer exists, clear docking state (ship inherits last station velocity and drifts free)

Fuel Transfer

Parameter Value
Transfer rate 100 kg/s (multiplied by time_scale)
Source Unlimited (stations have infinite fuel supply)
Transfer ends When ship.fuel == ship.fuel_capacity

The fuel transfer happens automatically every tick while docked. No separate request is needed.

Configuration Constants

DOCKING_TOLERANCE_M = 500.0      # meters from station center
DOCKING_MAX_SPEED_MS = 10.0      # m/s relative velocity
FUEL_TRANSFER_RATE = 100.0       # kg/s (before time_scale)
UNDOCK_PUSH_SPEED = 2.0          # m/s radial push-off

Proto Changes

ServiceType Enum

enum ServiceType {
    SERVICE_UNKNOWN = 0;
    SERVICE_FUEL = 1;    // Deprecated — use docking
    SERVICE_RESET = 2;
    SERVICE_DOCK = 3;
    SERVICE_UNDOCK = 4;
}

ShipState Message (new fields)

string docked_station_id = 30;
int64 docked_at_tick = 31;

Client Key Bindings

Key Action
F Dock (when in range of station) / Undock (when docked)

The F key replaces the previous instant refuel behavior. When pressed:

  • If docked: sends SERVICE_UNDOCK
  • If not docked: finds nearest station within docking range and sends SERVICE_DOCK with that station’s ID

Client HUD

When Docked

  • Proximity panel shows: DOCKED: {station_name} in blue (#44f)
  • Fuel transfer indicator: REFUELING: {fuel_pct}% with progress indication
  • All flight controls disabled (thrust, RCS, attitude modes)
  • Only allowed keys: F (undock), U (ship systems), Shift+U (ship specs), Shift+D (settings), Shift+? (controls), R (RCS mode toggle), X (cut thrust — no-op when docked)

When in Range (Not Docked)

  • Proximity panel shows: {station_name} {distance}m [F] DOCK in yellow (#ff4)

Station Service Profiles

Extensible framework for future services:

STATION_SERVICES = {
    "default": ["fuel"],  # All stations offer fuel for now
}

Future services (repair, rearm, trade) will extend this dictionary.

WebSocket State Broadcast

Ship state messages include docking fields:

{
  "ship": {
    "docked_station_id": "uuid-or-empty",
    ...
  }
}

Other players’ ship objects also include docked_station_id so the client can show docked status.

API Gateway

The service request model accepts "dock" and "undock" service strings:

  • "dock"SERVICE_DOCK (requires body field = station_id)
  • "undock"SERVICE_UNDOCK

Removed: Instant Refuel (SERVICE_FUEL)

The SERVICE_FUEL proto enum remains for backwards compatibility but the client no longer sends it. The F key now triggers dock/undock instead of instant refuel. Fuel is only obtained by docking.


Back to top

Galaxy — Kubernetes-based multiplayer space game

This site uses Just the Docs, a documentation theme for Jekyll.