Star Control II
Toys for Bob's 1992 space adventure, read through the 3DO version's source as The Ur-Quan Masters first imported it in 2002.
On this page
The atlas reads Star Control II through the C source of its 3DO version, which Toys for Bob released under the GPL in 2002, as The Ur-Quan Masters project first imported it1. Every claim here reads that 2002 release of the 3DO port’s code, the project’s early SDL port included. That code carries the project’s early SDL port, and may differ from the 1992 DOS game1. A frame here is one pass of the battle loop, at most 24 a second in the port1.
In Melee each ship’s stats come from a table in its own file. The Earthling Cruiser turns one of 16 facings every 2 frames and thrusts every 5, to a top speed of a facing every 2 frames; a thrust step every 5 frames adds 3 world units per frame, to 242. The cap is on the speed itself, where Asteroids clamps each axis3. With the thrust off, nothing slows the ship4. The Arilou Skiff has no inertia at all: it moves only while thrust is held5.
A planet pulls every ship and shot within 255 display units toward itself by the same amount each frame, near or far6.
A ship’s crew are its hit points, and it is lost when the last one goes7. Its battery pays for both weapons and refills on a timer. The Cruiser regains 1 unit every 9 frames, and a full 18 holds two missiles8.
In HyperSpace the flagship burns 1/100 of a fuel unit for each 16 logical units it travels9.
Mechanics
| Mechanic | Kind | How |
|---|---|---|
| Inertia | No drag · Earthling Cruiser | thrust every 5 frames up to a cap on the speed itself; with thrust off, nothing slows it |
| Gravity well | Constant pull | a Melee planet adds 1 world unit per frame toward itself to anything within 255 display units |
| Hit points | Crew as hit points | the crew is the hit points: a ship is lost when its crew reaches 0 |
| Weapon energy | Shared pool | one battery pays for both weapons and refills on a per-ship timer |
| Fuel gauge | By distance | 1/100 of a fuel unit for each 16 logical units flown in HyperSpace |
| Inertia | None · Arilou Skiff | full speed while thrust is held, and a dead stop when it is let go |
Every claim about this game, by concept (9)
References
- ^ abcIn the 3DO source as The Ur-Quan Masters first imported it (2002), each pass of the battle loop sleeps until 5 ticks (
BATTLE_FRAME_RATE) after the previous pass woke, on a clock of 120 ticks a second (ONE_SECOND), so battle runs at most 24 frames a second (computed: 120 / 5). The sleep is the port'sSleepTask, in its SDL wrapper. Whennth_frameis set, which encount.c does only while the cyborg option flies the player's ships in an encounter, the loop only yields (TaskSwitch) and does not wait. The atlas calls one pass a frame.CodeThe Ur-Quan Masters (2002 import)How we know
22#define BATTLE_FRAME_RATE 5sc2/src/sc2code/element.h line 22 at 2f5b2c3 · upstream ↗ 24#define ONE_SECOND 120sc2/src/sc2code/libs/timlib.h line 24 at 2f5b2c3 · upstream ↗ 229 if (nth_frame) 230 TaskSwitch (); 231 else 232 NextTime = SleepTask (NextTime + BATTLE_FRAME_RATE);
sc2/src/sc2code/battle.c lines 229–232 at 2f5b2c3 · upstream ↗ 1315SleepTask (DWORD wake_time) ⋮ 1320 if (wake_time <= t) 1321 SDL_Delay (0); 1322 else 1323 SDL_Delay ((wake_time - t) * 1000 / ONE_SECOND); ⋮ 1325 return (GetTimeCounter ());
sc2/src/SDL_wrapper.c lines 1315–1325 at 2f5b2c3 · upstream ↗ 745 if (GLOBAL (glob_flags) & CYBORG_ENABLED) ⋮ 757 nth_frame = MAKE_WORD (1, cur_speed); 758 PlayerControl[0] = CYBORG_CONTROL | AWESOME_RATING;
sc2/src/sc2code/encount.c lines 745–758 at 2f5b2c3 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
- ^The Earthling Cruiser's stats set
MAX_THRUST24,THRUST_INCREMENT3,TURN_WAIT1, andTHRUST_WAIT4. Speeds are in world units per frame;DISPLAY_TO_WORLDmakes one display unit 4 world units. Each frame,ship_preprocesscounts a ship's turn wait down, or, when it is 0 and a turn is held, steps the ship one of its 16 facings and sets the wait toTURN_WAIT. Thrust works the same way with its own wait: when the wait is 0 and thrust is held,ship_preprocesscallsinertial_thrustonce and sets the wait toTHRUST_WAIT. Each such call is one thrust step, which addsTHRUST_INCREMENTto the velocity along the facing, up toMAX_THRUST(sc2/speed-cap). So the Cruiser turns a facing every 2 frames and takes a thrust step every 5 frames. Each step raises its speed by 3 world units per frame (3/4 of a display unit per frame), to a top speed of 24 world units (6 display units) per frame, which it reaches from rest after 8 steps along an axis (computed). Comments beside the two thrust values readDISPLAY_TO_WORLD (6), which is 24 and agrees with the code, andDISPLAY_TO_WORLD (2), which is 8 and disagrees with the code's 3.CodeThe Ur-Quan Masters (2002 import)revisedHow we know
29#define MAX_THRUST /* DISPLAY_TO_WORLD (6) */ 24 30#define THRUST_INCREMENT /* DISPLAY_TO_WORLD (2) */ 3 31#define TURN_WAIT 1 32#define THRUST_WAIT 4
sc2/src/sc2code/ships/human/human.c lines 29–32 at 2f5b2c3 · upstream ↗ 57 MAX_THRUST, 58 THRUST_INCREMENT, ⋮ 63 TURN_WAIT, 64 THRUST_WAIT,
sc2/src/sc2code/ships/human/human.c lines 56–67 at 2f5b2c3 · upstream ↗ 74 COUNT max_thrust, 75 thrust_increment; ⋮ 80 turn_wait, 81 thrust_wait,
sc2/src/sc2code/races.h lines 74–84 at 2f5b2c3 · upstream ↗ 30#define ONE_SHIFT 2 ⋮ 33#define DISPLAY_TO_WORLD(x) ((x)<<ONE_SHIFT)
sc2/src/sc2code/units.h lines 30–33 at 2f5b2c3 · upstream ↗ 105#define FACING_SHIFT 4 ⋮ 112#define NORMALIZE_FACING(f) ((COUNT)(f)&((1 << FACING_SHIFT)-1))
sc2/src/sc2code/units.h lines 105–112 at 2f5b2c3 · upstream ↗ 223 if (ElementPtr->turn_wait) 224 --ElementPtr->turn_wait; 225 else if (cur_status_flags & (LEFT | RIGHT)) ⋮ 229 NORMALIZE_FACING (StarShipPtr->ShipFacing - 1); 230 else ⋮ 238 ElementPtr->turn_wait = RDPtr->characteristics.turn_wait; ⋮ 241 if (ElementPtr->thrust_wait) 242 --ElementPtr->thrust_wait; 243 else if (cur_status_flags & THRUST) ⋮ 247 thrust_status = inertial_thrust ((ELEMENTPTR)ElementPtr); ⋮ 254 ElementPtr->thrust_wait = RDPtr->characteristics.thrust_wait;
sc2/src/sc2code/ship.c lines 223–254 at 2f5b2c3 · upstream ↗ 69 thrust_increment = WORLD_TO_VELOCITY (thrust_increment); 70 GetCurrentVelocityComponents (VelocityPtr, &cur_delta_x, &cur_delta_y); 71 delta_x = cur_delta_x 72 + COSINE (CurrentAngle, thrust_increment); 73 delta_y = cur_delta_y 74 + SINE (CurrentAngle, thrust_increment); ⋮ 79 if (desired_speed <= max_speed) 80 SetVelocityComponents (VelocityPtr, delta_x, delta_y);
sc2/src/sc2code/ship.c lines 69–80 at 2f5b2c3 · upstream ↗ 49#define VELOCITY_SHIFT 5 ⋮ 53#define WORLD_TO_VELOCITY(l) ((l)<<VELOCITY_SHIFT)
sc2/src/sc2code/velocity.h lines 49–53 at 2f5b2c3 · upstream ↗ 141 if (!(state_flags & IGNORE_VELOCITY)) ⋮ 145 GetNextVelocityComponents (&ElementPtr->velocity, 146 &delta_x, &delta_y, 1); ⋮ 150 ElementPtr->next.location.x += delta_x; 151 ElementPtr->next.location.y += delta_y;
sc2/src/sc2code/process.c lines 141–151 at 2f5b2c3 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Revised after a check by a second AI model, 2026-10-22.
- ^
inertial_thrustcaps the speed itself, not each axis: after adding a thrust step it compares the sum of the squared components withMAX_THRUSTsquared, so a ship is no faster on a diagonal. Asteroids clamps each axis of its ship's velocity apart, so its diagonal is faster (asteroids/top-speed). A step that would pass the cap still applies if the result is slower than the current speed. At the cap, a step along the line of travel sets the velocity to exactlyMAX_THRUSTalong the facing (if the ship isn't above the cap); a step off the line instead adds half a thrust step along the facing and takes a whole step off along the line of travel, kept if that ends within the cap or slower than before, so the course swings toward the facing. While the ship is flagged in a gravity well, a thrust step may take it past the cap up toMAX_ALLOWED_SPEED, 18 display units per frame.CodeThe Ur-Quan Masters (2002 import) · Computer Archeology, AsteroidsHow we know
75 desired_speed = (DWORD)((long)delta_x * delta_x) 76 + (DWORD)((long)delta_y * delta_y); 77 max_speed = (DWORD)WORLD_TO_VELOCITY (max_thrust) 78 * WORLD_TO_VELOCITY (max_thrust); 79 if (desired_speed <= max_speed) 80 SetVelocityComponents (VelocityPtr, delta_x, delta_y); 81 else ⋮ 83#define MAX_ALLOWED_SPEED WORLD_TO_VELOCITY (DISPLAY_TO_WORLD (18)) ⋮ 86 if (((StarShipPtr->cur_status_flags & SHIP_IN_GRAVITY_WELL) 87 && desired_speed <= 88 (DWORD)MAX_ALLOWED_SPEED * (DWORD)MAX_ALLOWED_SPEED) 89 || (current_speed = ⋮
sc2/src/sc2code/ship.c lines 75–128 at 2f5b2c3 · upstream ↗ 56 else if ((TravelAngle = 57 GetVelocityTravelAngle (VelocityPtr)) == CurrentAngle 58 && (StarShipPtr->cur_status_flags 59 & (SHIP_AT_MAX_SPEED | SHIP_BEYOND_MAX_SPEED)) 60 && !(StarShipPtr->cur_status_flags & SHIP_IN_GRAVITY_WELL))
sc2/src/sc2code/ship.c lines 56–62 at 2f5b2c3 · upstream ↗ BMI $7130 ; {} CMP #$40 BCC $7138 ; {} LDX #$FF LDA #$3F RTS CMP #$C0 BCS $7138 ; {} LDX #$01 LDA #$C0
content/Arcade/Asteroids/Code.md#L1135-L1145 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
- ^A ship that stops thrusting keeps its velocity: the frame's move step (process.c) adds the velocity to the position without changing it, and
ship_preprocesschanges it only throughinertial_thrust, called while thrust is held. The Earthling Cruiser's own code (human.c) sets a velocity only for its missile. Other code can still change a ship's velocity, such as a planet's pull (sc2/gravity-well) and the Arilou Skiff's own routine (sc2/arilou).CodeThe Ur-Quan Masters (2002 import)How we know
141 if (!(state_flags & IGNORE_VELOCITY)) ⋮ 145 GetNextVelocityComponents (&ElementPtr->velocity, 146 &delta_x, &delta_y, 1); ⋮ 150 ElementPtr->next.location.x += delta_x;
sc2/src/sc2code/process.c lines 141–151 at 2f5b2c3 · upstream ↗ 241 if (ElementPtr->thrust_wait) 242 --ElementPtr->thrust_wait; 243 else if (cur_status_flags & THRUST) ⋮ 247 thrust_status = inertial_thrust ((ELEMENTPTR)ElementPtr);
sc2/src/sc2code/ship.c lines 241–254 at 2f5b2c3 · upstream ↗ 111nuke_preprocess (PELEMENT ElementPtr) ⋮ 139 SetVelocityVector (&ElementPtr->velocity,
sc2/src/sc2code/ships/human/human.c lines 111–140 at 2f5b2c3 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
- ^The Arilou Skiff's stats set
THRUST_INCREMENTequal toMAX_THRUST, 40 world units (10 display units) per frame, withTURN_WAITandTHRUST_WAIT0. For such a shipinertial_thrustsets the velocity straight toMAX_THRUSTalong the facing. The Skiff's own preprocess routine, whichship_preprocessruns before turning and thrust, zeroes its velocity whenever its thrust wait is 0, outside its jump (while it isn'tNONSOLID). So the Skiff moves at full speed only on frames thrust is held and stops when it is released, with no inertia.CodeThe Ur-Quan Masters (2002 import)How we know
29#define MAX_THRUST /* DISPLAY_TO_WORLD (10) */ 40 30#define THRUST_INCREMENT MAX_THRUST 31#define TURN_WAIT 0 32#define THRUST_WAIT 0
sc2/src/sc2code/ships/arilou/arilou.c lines 29–32 at 2f5b2c3 · upstream ↗ 50 if (thrust_increment == max_thrust) ⋮ 52 SetVelocityVector (VelocityPtr, 53 max_thrust, StarShipPtr->ShipFacing); 54 return (SHIP_AT_MAX_SPEED);
sc2/src/sc2code/ship.c lines 50–55 at 2f5b2c3 · upstream ↗ 185arilou_preprocess (PELEMENT ElementPtr) ⋮ 190 if (!(ElementPtr->state_flags & NONSOLID)) ⋮ 192 if (ElementPtr->thrust_wait == 0) ⋮ 194 ZeroVelocityComponents (&ElementPtr->velocity);
sc2/src/sc2code/ships/arilou/arilou.c lines 185–196 at 2f5b2c3 · upstream ↗ 217 if (RDPtr->preprocess_func) ⋮ 219 (*RDPtr->preprocess_func) (ElementPtr); ⋮ 223 if (ElementPtr->turn_wait) ⋮ 247 thrust_status = inertial_thrust ((ELEMENTPTR)ElementPtr);
sc2/src/sc2code/ship.c lines 217–247 at 2f5b2c3 · upstream ↗ 280 arilou_desc.preprocess_func = arilou_preprocess;sc2/src/sc2code/ships/arilou/arilou.c line 280 at 2f5b2c3 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
- ^A Melee planet is an element with 200 hit points and a mass of 200, above
GRAVITY_MASS's threshold of 100 (10 timesMAX_SHIP_MASS), whose per-frame postprocess isCalculateGravity. That routine pulls every other colliding element without such mass that lies within 255 display units of the planet (GRAVITY_THRESHOLD, tested on each axis and then as a radius, measured the short way across the arena's wrapped edges): it adds 1 world unit per frame to the element's velocity, aimed at the planet, whatever the distance, and flags a ship as in a gravity well. A block under#ifdef NEVER, never compiled, works out a pull from the distance, capped at 6, and only prints it.CodeThe Ur-Quan Masters (2002 import)How we know
22spawn_planet (void) ⋮ 34 PlanetElementPtr->hit_points = 200; ⋮ 42 PlanetElementPtr->postprocess_func = 43 (void (*) (struct element *ElementPtr))CalculateGravity; ⋮ 54 PlanetElementPtr->mass_points = PlanetElementPtr->hit_points;
sc2/src/sc2code/misc.c lines 22–54 at 2f5b2c3 · upstream ↗ 131#define MAX_SHIP_MASS 10 132#define GRAVITY_MASS(m) ((m) > MAX_SHIP_MASS * 10) 133#define GRAVITY_THRESHOLD (COUNT)255
sc2/src/sc2code/element.h lines 131–133 at 2f5b2c3 · upstream ↗ 28 HasGravity = (BOOLEAN)(CollidingElement (ElementPtr) 29 && GRAVITY_MASS (ElementPtr->mass_points + 1)); ⋮ 38 && CollidingElement (TestElementPtr) 39 && (TestHasGravity = 40 GRAVITY_MASS (TestElementPtr->mass_points + 1)) != HasGravity) ⋮ 66 dx = WRAP_DELTA_X (dx); 67 dy = WRAP_DELTA_Y (dy); ⋮ 74 abs_dx = WORLD_TO_DISPLAY (abs_dx); 75 abs_dy = WORLD_TO_DISPLAY (abs_dy); ⋮ 80 if (abs_dx <= GRAVITY_THRESHOLD 81 && abs_dy <= GRAVITY_THRESHOLD) ⋮ 87 if (dist_squared <= (DWORD)(GRAVITY_THRESHOLD ⋮
sc2/src/sc2code/gravity.c lines 28–131 at 2f5b2c3 · upstream ↗ 131#define WRAP_DELTA_X(dx) ((dx)<0 ? \ 132 ((-(dx)<=LOG_SPACE_WIDTH>>1)?(dx):(LOG_SPACE_WIDTH+(dx))) : \
sc2/src/sc2code/units.h lines 131–136 at 2f5b2c3 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
- ^A ship's crew is its hit points: element.h defines
hit_pointsascrew_level, anddo_damagetakes damage to a player's ship from its crew throughDeltaCrew, which reports failure when the crew would reach 0 or less; the ship's life span is then set to 0 and it becomes nonsolid.DeltaCrewchanges nothing for the enemy in the last battle (its comment: "Samatra can't be crew-modified"). The Earthling Cruiser's table entry gives 18 crew, at its maximum of 18 (MAX_CREW); in encounters and the last battle a ship takes its crew from the fleet instead, up to that maximum.CodeThe Ur-Quan Masters (2002 import)How we know
127#define hit_points crew_levelsc2/src/sc2code/element.h line 127 at 2f5b2c3 · upstream ↗ 195do_damage (ELEMENTPTR ElementPtr, SIZE damage) ⋮ 197 if (ElementPtr->state_flags & PLAYER_SHIP) ⋮ 199 if (!DeltaCrew (ElementPtr, -damage)) ⋮ 201 ElementPtr->life_span = 0; 202 ElementPtr->state_flags |= NONSOLID;
sc2/src/sc2code/misc.c lines 195–203 at 2f5b2c3 · upstream ↗ 300DeltaCrew (ELEMENTPTR ElementPtr, SIZE crew_delta) ⋮ 307 return (TRUE); /* Samatra can't be crew-modified */ ⋮ 321 ElementPtr->crew_level = ⋮ 325 else if (crew_delta < 0) ⋮ 327 if (ElementPtr->crew_level > (BYTE)-crew_delta) 328 ElementPtr->crew_level += (BYTE)crew_delta; 329 else ⋮ 331 crew_delta = -(SIZE)ElementPtr->crew_level; 332 ElementPtr->crew_level = 0; 333 retval = FALSE;
sc2/src/sc2code/status.c lines 300–334 at 2f5b2c3 · upstream ↗ 23#define MAX_CREW 18sc2/src/sc2code/ships/human/human.c line 23 at 2f5b2c3 · upstream ↗ 47 MAX_CREW, MAX_CREW,sc2/src/sc2code/ships/human/human.c line 47 at 2f5b2c3 · upstream ↗ 92 BYTE crew_level, max_crew;sc2/src/sc2code/races.h line 92 at 2f5b2c3 · upstream ↗ 380 if (LOBYTE (GLOBAL (CurrentActivity)) == IN_ENCOUNTER 381 || LOBYTE (GLOBAL (CurrentActivity)) == IN_LAST_BATTLE) ⋮ 383 if ((RDPtr->ship_info.crew_level = StarShipPtr->special_counter) > 384 RDPtr->ship_info.max_crew) 385 RDPtr->ship_info.crew_level = RDPtr->ship_info.max_crew;
sc2/src/sc2code/ship.c lines 380–385 at 2f5b2c3 · upstream ↗ 145 if (!(ElementPtr->state_flags & APPEARING)) ⋮ 150 ElementPtr->crew_level = 151 (BYTE)RDPtr->ship_info.crew_level;
sc2/src/sc2code/ship.c lines 145–151 at 2f5b2c3 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
- ^A ship's battery pays for both its weapons and refills by itself. Each frame,
ship_preprocesscounts the energy counter down, or, when it is 0 and the battery is below full, addsENERGY_REGENERATION; every successfulDeltaEnergy, a refill or a shot's cost, resets the counter toENERGY_WAIT. A weapon fires only ifDeltaEnergycan take its whole cost. The Earthling Cruiser holds 18 (MAX_ENERGY), regains 1 unit every 9 frames (ENERGY_WAIT8), pays 9 a missile (WEAPON_ENERGY_COST) at most once every 11 frames (WEAPON_WAIT10), and 4 (SPECIAL_ENERGY_COST) for each use of its point-defense laser, taken only when a colliding, uncloaked object is within 100 display units (LASER_RANGE) to fire at. So a full battery holds two missiles and refills from empty in 162 frames, 6.75 seconds at 24 frames a second (computed).CodeThe Ur-Quan Masters (2002 import)How we know
24#define MAX_ENERGY 18 25#define ENERGY_REGENERATION 1 26#define WEAPON_ENERGY_COST 9 27#define SPECIAL_ENERGY_COST 4 28#define ENERGY_WAIT 8 ⋮ 33#define WEAPON_WAIT 10
sc2/src/sc2code/ships/human/human.c lines 23–33 at 2f5b2c3 · upstream ↗ 48 MAX_ENERGY, MAX_ENERGY, ⋮ 59 ENERGY_REGENERATION, 60 WEAPON_ENERGY_COST, 61 SPECIAL_ENERGY_COST, 62 ENERGY_WAIT, ⋮ 65 WEAPON_WAIT,
sc2/src/sc2code/ships/human/human.c lines 48–66 at 2f5b2c3 · upstream ↗ 187 if (ObjectPtr != ShipPtr && CollidingElement (ObjectPtr) && 188 !OBJECT_CLOAKED (ObjectPtr)) ⋮ 190#define LASER_RANGE (UWORD)100 ⋮ 203 if ((UWORD)delta_x <= LASER_RANGE && ⋮ 212 if (!PaidFor) ⋮ 214 if (!DeltaEnergy (ShipPtr, -SPECIAL_ENERGY_COST))
sc2/src/sc2code/ships/human/human.c lines 186–214 at 2f5b2c3 · upstream ↗ 210 if (StarShipPtr->energy_counter) 211 --StarShipPtr->energy_counter; 212 else if (RDPtr->ship_info.energy_level < (BYTE)RDPtr->ship_info.max_energy 213 || (SBYTE)RDPtr->characteristics.energy_regeneration < 0) 214 DeltaEnergy ((ELEMENTPTR)ElementPtr, 215 (SBYTE)RDPtr->characteristics.energy_regeneration);
sc2/src/sc2code/ship.c lines 210–215 at 2f5b2c3 · upstream ↗ 260DeltaEnergy (ELEMENTPTR ElementPtr, SIZE energy_delta) ⋮ 279 if ((BYTE)-energy_delta > ShipInfoPtr->energy_level) ⋮ 281 retval = FALSE; ⋮ 290 StarShipPtr->energy_counter = 291 StarShipPtr->RaceDescPtr->characteristics.energy_wait;
sc2/src/sc2code/status.c lines 260–295 at 2f5b2c3 · upstream ↗ 284 if (StarShipPtr->weapon_counter) 285 --StarShipPtr->weapon_counter; 286 else if ((StarShipPtr->cur_status_flags 287 & WEAPON) && DeltaEnergy ((ELEMENTPTR)ElementPtr, 288 -RDPtr->characteristics.weapon_energy_cost)) ⋮ 321 StarShipPtr->weapon_counter = 322 RDPtr->characteristics.weapon_wait;
sc2/src/sc2code/ship.c lines 284–322 at 2f5b2c3 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
- ^While the flagship moves in HyperSpace,
MoveSISadds up how far the flagship moves on each axis (as absolute values) since it entered (LoadHyperspacezeroes the sums), takes the square root of the sum of their squares, and charges 1 unit ofFuelOnBoardfor each 16 logical units of that distance; the first charge comes at 32, since the count starts at 1 (computed). The fuel gauge showsFuelOnBoarddivided by 100 (FUEL_TANK_SCALE), so each charge is 1/100 of a shown unit. Nothing is charged with an empty tank or while theARILOU_SPACE_SIDEgame state is above 1. The atlas reads those values as QuasiSpace: hyper.c loads theARISPACEgraphics intohyperstars[2], picks the stars ashyperstars[1 + (ARILOU_SPACE_SIDE >> 1)], and from 2 upAddEncounterElementreturns at once, adding no encounter.CodeThe Ur-Quan Masters (2002 import)revisedHow we know
91 if (GLOBAL_SIS (FuelOnBoard) 92 && GET_GAME_STATE (ARILOU_SPACE_SIDE) <= 1) ⋮ 99 hyper_dx += new_dx; ⋮ 102 hyper_dy += new_dy; ⋮ 104 hyper_dist = square_root ( 105 (DWORD)hyper_dx * hyper_dx 106 + (DWORD)hyper_dy * hyper_dy ⋮ 108 cur_fuel_ticks = hyper_dist >> 4; 109 if (cur_fuel_ticks > (COUNT)fuel_ticks) ⋮ 112 DeltaSISGauges (0, fuel_ticks - cur_fuel_ticks, 0); ⋮ 121 fuel_ticks = (BYTE)cur_fuel_ticks;
sc2/src/sc2code/hyper.c lines 91–122 at 2f5b2c3 · upstream ↗ 296 if ((dx || dy) && LOBYTE (GLOBAL (CurrentActivity)) == IN_HYPERSPACE) 297 MoveSIS (&dx, &dy);
sc2/src/sc2code/process.c lines 296–297 at 2f5b2c3 · upstream ↗ 298 hyper_dx = hyper_dy = 0; 299 fuel_ticks = 1;
sc2/src/sc2code/hyper.c lines 298–299 at 2f5b2c3 · upstream ↗ 645 if (fuel_delta != 0) ⋮ 651 else ⋮ 656 GLOBAL_SIS (FuelOnBoard) / FUEL_TANK_SCALE ⋮ 661 else if ((GLOBAL_SIS (FuelOnBoard) += fuel_delta) > ⋮ 667 GLOBAL_SIS (FuelOnBoard) / FUEL_TANK_SCALE ⋮ 671 wsprintf (buf, "%u", new_coarse_fuel);
sc2/src/sc2code/sis.c lines 645–671 at 2f5b2c3 · upstream ↗ 75#define FUEL_TANK_SCALE 100sc2/src/sc2code/sis.h line 75 at 2f5b2c3 · upstream ↗ 288 hyperstars[2] = CaptureDrawable ( 289 LoadGraphic (ARISPACE_MASK_PMAP_ANIM)
sc2/src/sc2code/hyper.c lines 288–289 at 2f5b2c3 · upstream ↗ 764 HyperSpaceElementPtr->current.image.farray = 765 &hyperstars[1 + (GET_GAME_STATE (ARILOU_SPACE_SIDE) >> 1)];
sc2/src/sc2code/hyper.c lines 764–765 at 2f5b2c3 · upstream ↗ 893AddEncounterElement (ENCOUNTERPTR EncounterPtr, ⋮ 901 if (GET_GAME_STATE (ARILOU_SPACE_SIDE) >= 2) 902 return (0);
sc2/src/sc2code/hyper.c lines 893–902 at 2f5b2c3 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Revised after a check by a second AI model, 2026-10-22.
Sources
Code
- Reiche, Paul, Fred Ford, and The Ur-Quan Masters project. 2002. “The Ur-Quan Masters: Star Control II's 3DO source, the project's initial import.” Commit 2f5b2c3. sc2/uqm @ 2f5b2c3 · licence, all uses
- Howell, Lonnie, Mark McDougall, and Christopher Cantrell. 2026. “Computer Archeology: Asteroids.” Commit 1adc2a7. topherCantrell/computerarcheology @ 1adc2a7 · licence, all uses