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:
- Validate not already docked — error
E030ifship.docked_station_id != "" - Look up station — find station by ID from the service request’s
target_bodyfield - Check distance —
|ship.position - station.position|must be ≤ 500 m - Check relative velocity —
|ship.velocity - station.velocity|must be ≤ 5 m/s - Set docked state:
ship.docked_station_id = station.station_idship.docked_at_tick = current_tick
- Zero all controls:
thrust_level = 0rotation_input = Vec3(0, 0, 0)translation_input = Vec3(0, 0, 0)angular_velocity = Vec3(0, 0, 0)attitude_mode = "none"
- Snap to station — set ship position and velocity to match station exactly
- 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:
- Validate docked — error
E031ifship.docked_station_id == "" - Compute push-off direction —
normalize(ship.position - station.position), or station’s forward axis if positions coincide - Apply push-off velocity —
ship.velocity = station.velocity + push_dir * 2.0 m/s - Clear docked state:
ship.docked_station_id = ""ship.docked_at_tick = 0
- Save to Redis
Physics While Docked
When ship.docked_station_id != "", the per-tick _update_ship() method:
- Locks position/velocity — copies station’s current position and velocity each tick
- Zeroes angular velocity — prevents any rotation
- 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
- Skips all integration — no gravity, no thrust, no attitude control
- 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_DOCKwith 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] DOCKin 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(requiresbodyfield = 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.