On this page
  1. Related
  2. Games
  3. References
  4. Sources

A craft with inertia keeps its velocity until thrust or drag changes it. Asteroids adds thrust along the ship’s facing every other frame and takes about 1/128 of the speed away only while the thrust is off1,2. Defender damps its ship’s horizontal speed by 1/64 every frame, thrusting or not, so thrust alone levels off below the speed cap3. In Star Control II, the Earthling Cruiser keeps its velocity when thrust stops, where Asteroids’ coasting ship loses speed to drag4,2. Its cap holds the speed itself, so a diagonal is no faster, where Asteroids clamps each axis apart5,6. The Arilou Skiff has no inertia: it moves at full speed only while thrust is held and stops when it is released7.

  • NoneStar Control II (1992), Arilou Skiff. Full speed while thrust is held, and a dead stop when it is let go.7
  • No dragStar Control II (1992), Earthling Cruiser. Thrust every 5 frames up to a cap on the speed itself; with thrust off, nothing slows it.8,9,5,4
  • Drag when coastingAsteroids (1979). Thrust every other frame up to a per-axis cap; with it off, about 1/128 of the speed goes each step.10,1,2,6
  • Drag alwaysDefender (1981). Horizontal speed damped by 1/64 every frame, so thrust levels off at 6 pixels a frame; up and down stop at once.3,11

Games

GameYearHowNote
Star Control II1992No dragEarthling Cruiser · thrust every 5 frames up to a cap on the speed itself; with thrust off, nothing slows it
Asteroids1979Drag when coastingthrust every other frame up to a per-axis cap; with it off, about 1/128 of the speed goes each step
Defender1981Drag alwayshorizontal speed damped by 1/64 every frame, so thrust levels off at 6 pixels a frame; up and down stop at once
Descent 31999Drag alwaysthrust on three axes against a drag proportional to speed, solved exactly each frame, so the ship settles at thrust over drag
Every claim about this mechanic, by game (13)
Asteroids 1979Asteroids paces its main loop by its 250 Hz NMI: every fourth NMI increments a counter, and the main loop waits on that counter before each pass, so the loop runs at most 62.5 times a second (computed: 250 / 4). The atlas calls one pass a frame. The listing reads Atari's revision 2 program ROMs.Code
While the ship is in play, a held rotate button turns it 3 of its 256 directions per frame. On every other frame (when the fast timer's low bit is clear), a held thrust button adds twice the cosine of the direction to the horizontal velocity and twice the sine to the vertical, read from a 65-entry sine table for a quarter turn, 0 to 127, which the lookup folds for the other quarters. Velocities carry 8 fraction bits, so one thrust step adds at most 254/256 of a position unit per frame to an axis's speed (computed).Code
On the same every-other frames, when thrust isn't held, each axis of the ship's velocity loses 2/256 of its whole-unit part (and 1/256 more when moving right or up), about 1/128 of itself per step, until it reaches zero. With the thrust off, the ship's speed so halves in about 88 steps, 176 frames, about 2.8 seconds at 62.5 frames a second (computed).Code
Thrust holds each axis of the ship's velocity to its own limit: at most 63 255/256 position units per frame right or up, and 63 255/256 left or down (computed from $3F.FF and $C0.01). Because the axes are clamped apart, a diagonal can reach about 1.41 times the top speed along one axis (computed).Code
Defender 1981Defender moves its ship once per video frame: the interrupt calls the player routine once each time the beam passes line 128. Each call damps the horizontal velocity by 1/64 of itself, then a held thrust button adds 3/256 of a velocity unit in the facing direction (reverse negates it), and the velocity is held to ±1 unit. A unit is 256 world units, 8 pixels, a frame (the world has 32 units to a pixel). Since the damping runs every frame, thrust alone levels off at 3 × 64 = 192/256 of a unit, 6 pixels a frame, below the cap (computed). The source is the Red Label release.Code
Up and down have no inertia in Defender: a held direction moves the ship 1 pixel a frame at once, rising by 8/256 of a pixel each frame to 2 pixels a frame (after 32 frames, computed), and letting go stops it. The ship stops climbing once at row 43 or higher, and descending at row 238 or lower.Code
Super Mario Bros.: The Lost Levels 1986The player's control and movement code (GameRoutines through ImposeFriction) is Super Mario Bros.'s, instruction for instruction in 14 of its 19 regions, with these changes: OnGroundStateSub and the jump and swim code move the player through a new JmpMove, which lets the wind push them (BlowPlayerAround) once a disk file beyond worlds 1 to 4 is loaded; PlayerPhysicsSub's friction table moves up to follow the fall forces, inside the 17 bytes that LoadPhysicsData overwrites with Mario's or Luigi's set; PlayerEndLevel queues the level-end music once, guarded by a new FlagpoleMusicFlag, where Super Mario Bros. queues it whenever ScrollLock is set, and sets the hidden 1-up's flag on 10 coins in any world, where Super Mario Bros. reads a per-world table, and starts world 9 over after 9-4; PlayerDeath shares one RTS. The entrances, pipes, size change, injury blink, flagpole slide, falling, climbing, animation speed and ImposeFriction differ only in their addresses.Code
Star Control II 1992In 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's SleepTask, in its SDL wrapper. When nth_frame is 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.Code
The Earthling Cruiser's stats set MAX_THRUST 24, THRUST_INCREMENT 3, TURN_WAIT 1, and THRUST_WAIT 4. Speeds are in world units per frame; DISPLAY_TO_WORLD makes one display unit 4 world units. Each frame, ship_preprocess counts 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 to TURN_WAIT. Thrust works the same way with its own wait: when the wait is 0 and thrust is held, ship_preprocess calls inertial_thrust once and sets the wait to THRUST_WAIT. Each such call is one thrust step, which adds THRUST_INCREMENT to the velocity along the facing, up to MAX_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 read DISPLAY_TO_WORLD (6), which is 24 and agrees with the code, and DISPLAY_TO_WORLD (2), which is 8 and disagrees with the code's 3.Code
inertial_thrust caps the speed itself, not each axis: after adding a thrust step it compares the sum of the squared components with MAX_THRUST squared, 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 exactly MAX_THRUST along 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 to MAX_ALLOWED_SPEED, 18 display units per frame.Code
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_preprocess changes it only through inertial_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).Code
The Arilou Skiff's stats set THRUST_INCREMENT equal to MAX_THRUST, 40 world units (10 display units) per frame, with TURN_WAIT and THRUST_WAIT 0. For such a ship inertial_thrust sets the velocity straight to MAX_THRUST along the facing. The Skiff's own preprocess routine, which ship_preprocess runs before turning and thrust, zeroes its velocity whenever its thrust wait is 0, outside its jump (while it isn't NONSOLID). So the Skiff moves at full speed only on frames thrust is held and stops when it is released, with no inertia.Code
Descent 3 1999In Descent 3's released source, which includes the unreleased "1.5" patch, the player ship's thrust is the sum of a forward, an up, and a sideways push along the ship's own axes, each the control's value times full_thrust, the whole scaled by the player's movement_scalar and by 1.3 outdoors; the physics then moves a thrusting object against a drag proportional to velocity, solved in closed form over the frame: v = (v₀ − F/d)·e^(−(d/m)·t) + F/d. Computed from that formula, drag acts while the ship thrusts too, and speed levels off at F/d, as in Doom, whose floor friction multiplies momentum by 0.90625 each tic thrust or not; Quake's ground acceleration instead stops at the wish speed.Code

References

  1. ^ abWhile the ship is in play, a held rotate button turns it 3 of its 256 directions per frame. On every other frame (when the fast timer's low bit is clear), a held thrust button adds twice the cosine of the direction to the horizontal velocity and twice the sine to the vertical, read from a 65-entry sine table for a quarter turn, 0 to 127, which the lookup folds for the other quarters. Velocities carry 8 fraction bits, so one thrust step adds at most 254/256 of a position unit per frame to an axis's speed (computed).CodeComputer Archeology, Asteroids
    How we know
    LDA $2407 ; {hard.SWROTLEFT} Rotate Left Switch … LDA #$03 … LDA #$FD CLC ADC $61 ; {ram.direction} Current Ship Direction STA $61 ; {ram.direction} LDA $5C ; {ram.fastTimer} Fast Timer LSR A BCS $7085 ; {} LDA $2405 ; {hard.SWTHRUST} Thrust Switch …
    content/Arcade/Asteroids/Code.md#L1054-L1099 · upstream ↗
    ADC #$40 ; A holds current ship direction BPL $77DF ; {} A holds current ship direction … CMP #$41 … EOR #$7F … LDA $57B9,X ; Vector ROM
    content/Arcade/Asteroids/Code.md#L1992-L2004 · upstream ↗
    1158# Sine lookup table
    ⋮
    1161; Used for vertical thrust (offset by 64 to get cosine for horizontal thrust)
    
    content/Arcade/Asteroids/VectorROM.md lines 1158–1178 at 1adc2a7 · upstream ↗
    LDY $59 ; {ram.hyperSpaceFlag} Hyperspace Flag … RTS
    content/Arcade/Asteroids/Code.md#L1030-L1053 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  2. ^ abcOn the same every-other frames, when thrust isn't held, each axis of the ship's velocity loses 2/256 of its whole-unit part (and 1/256 more when moving right or up), about 1/128 of itself per step, until it reaches zero. With the thrust off, the ship's speed so halves in about 88 steps, 176 frames, about 2.8 seconds at 62.5 frames a second (computed).CodeComputer Archeology, Asteroids
    How we know
    LDA #$00 STA $3C03 ; {hard.SNDTHRUST} Ship Thrust Sound LDA $023E ; {ram.horzVelShip} ORA $64 ; {ram.ship_thrust_dH} BEQ $7105 ; {} LDA $023E ; {ram.horzVelShip} ASL A LDX #$FF CLC EOR #$FF BMI $70FA ; {} INX …
    content/Arcade/Asteroids/Code.md#L1100-L1134 · upstream ↗
    1050223 - 0245 Horizontal Velocity 0-255, (255-192) = Left, 1-63 = Right
    
    content/Arcade/Asteroids/RAMUse.md line 105 at 1adc2a7 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  3. ^ abDefender moves its ship once per video frame: the interrupt calls the player routine once each time the beam passes line 128. Each call damps the horizontal velocity by 1/64 of itself, then a held thrust button adds 3/256 of a velocity unit in the facing direction (reverse negates it), and the velocity is held to ±1 unit. A unit is 256 world units, 8 pixels, a frame (the world has 32 units to a pixel). Since the damping runs every frame, thrust alone levels off at 3 × 64 = 192/256 of a unit, 6 pixels a frame, below the cap (computed). The source is the Red Label release.Codemwenge/defender
    How we know
    75The game source code for Defender in [src](src) was originally retrieved from
    76https://github.com/historicalsource/defender. It is the Motorola 6809 assembly language
    77source code for the 'Red Label' version of the game.
    
    README.md lines 75–77 at e740063 · upstream ↗
    1937        LDA    VERTCT           ;PAST 128
    1938        CMPA   #128
    1939        BLO    I0               ;NO
    1940        LDA    IFLG             ;ALREADY DONE ?
    1941        BNE    IRQX             ;NO
    1942        INC    IFLG
    ⋮
    1944        JSR    PLAYER
    
    src/defa7.src lines 1931–1944 at e740063 · upstream ↗
    1960I0      LDB    IFLG
    1961        BEQ    IRQX
    1962        CLR    IFLG
    
    src/defa7.src lines 1960–1962 at e740063 · upstream ↗
    2336*PLAYER PROCESS
    2337*CALLED FORM IRQ
    ⋮
    2342*X DAMPING
    2343        CLR    ITEMP
    2344        LDD    PLAXV
    2345        COMA 
    2346        COMB 
    2347        ADDD   #1               ;NEGD
    2348        BPL    PL00
    2349        COM    ITEMP            ;SIGN EXTEND
    2350PL00    ASLB                    ; SHIFT
    2351        ROLA 
    ⋮
    
    src/defa7.src lines 2336–2371 at e740063 · upstream ↗
    2421        LDD    PLAXV
    2422        CMPD   #$0100           ;MAX VEL
    2423        BLT    PV11
    2424        LDD    #$0100
    2425PV11    CMPD   #-$0100
    2426        BGT    PV12
    2427        LDD    #-$0100
    2428PV12    STD    PLAXV
    2429        ADDD   BGL
    2430        SUBD   BGDELT
    2431        STD    BGL
    
    src/defa7.src lines 2420–2431 at e740063 · upstream ↗
    1249        LDD    #$0300
    1250        STD    PLADIR           ;THRUST+DIRECTION
    
    src/defa7.src lines 1249–1250 at e740063 · upstream ↗
    3155*REVERSE
    ⋮
    3160        LDD    PLADIR
    3161        COMB 
    3162        COMA 
    3163        ADDD   #1
    3164        STD    NPLAD
    
    src/defa7.src lines 3155–3164 at e740063 · upstream ↗
    3333ISCAN   LDD    BGL
    3334        SUBD   #100*32          ;100 PIXEL LEFT BUFFER
    
    src/defa7.src lines 3333–3334 at e740063 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  4. ^ abA 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_preprocess changes it only through inertial_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.

    In the claim ledger

  5. ^ abinertial_thrust caps the speed itself, not each axis: after adding a thrust step it compares the sum of the squared components with MAX_THRUST squared, 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 exactly MAX_THRUST along 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 to MAX_ALLOWED_SPEED, 18 display units per frame.CodeThe Ur-Quan Masters (2002 import) · Computer Archeology, Asteroids
    How 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.

    In the claim ledger

  6. ^ abThrust holds each axis of the ship's velocity to its own limit: at most 63 255/256 position units per frame right or up, and 63 255/256 left or down (computed from $3F.FF and $C0.01). Because the axes are clamped apart, a diagonal can reach about 1.41 times the top speed along one axis (computed).CodeComputer Archeology, Asteroids
    How we know
    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 ↗
    ADC $023E ; {ram.horzVelShip} JSR $7125 ; {} STA $023E ; {ram.horzVelShip} STX $64 ; {ram.ship_thrust_dH}
    content/Arcade/Asteroids/Code.md#L1076-L1084 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  7. ^ abThe Arilou Skiff's stats set THRUST_INCREMENT equal to MAX_THRUST, 40 world units (10 display units) per frame, with TURN_WAIT and THRUST_WAIT 0. For such a ship inertial_thrust sets the velocity straight to MAX_THRUST along the facing. The Skiff's own preprocess routine, which ship_preprocess runs before turning and thrust, zeroes its velocity whenever its thrust wait is 0, outside its jump (while it isn't NONSOLID). 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.

    In the claim ledger

  8. ^In 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's SleepTask, in its SDL wrapper. When nth_frame is 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 5
    
    sc2/src/sc2code/element.h line 22 at 2f5b2c3 · upstream ↗
    24#define ONE_SECOND 120
    
    sc2/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.

    In the claim ledger

  9. ^The Earthling Cruiser's stats set MAX_THRUST 24, THRUST_INCREMENT 3, TURN_WAIT 1, and THRUST_WAIT 4. Speeds are in world units per frame; DISPLAY_TO_WORLD makes one display unit 4 world units. Each frame, ship_preprocess counts 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 to TURN_WAIT. Thrust works the same way with its own wait: when the wait is 0 and thrust is held, ship_preprocess calls inertial_thrust once and sets the wait to THRUST_WAIT. Each such call is one thrust step, which adds THRUST_INCREMENT to the velocity along the facing, up to MAX_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 read DISPLAY_TO_WORLD (6), which is 24 and agrees with the code, and DISPLAY_TO_WORLD (2), which is 8 and disagrees with the code's 3.CodeThe Ur-Quan Masters (2002 import)revised
    How 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.

    In the claim ledger

  10. ^Asteroids paces its main loop by its 250 Hz NMI: every fourth NMI increments a counter, and the main loop waits on that counter before each pass, so the loop runs at most 62.5 times a second (computed: 250 / 4). The atlas calls one pass a frame. The listing reads Atari's revision 2 program ROMs.CodeComputer Archeology, Asteroids
    How we know
    7>>> binary 6800:roms/035145.02 + roms/035144.02 + roms/035143.02 
    ⋮
    23; 6800~035145.02+035144.02+035143.02 (Rev 2)
    
    content/Arcade/Asteroids/Code.md lines 7–23 at 1adc2a7 · upstream ↗
    9The MMI interrupt is clocked at 250Hz.
    
    content/Arcade/Asteroids/Hardware.md line 9 at 1adc2a7 · upstream ↗
    INC $5E ; {ram.$5E} LDA $5E ; {ram.$5E} AND #$03 BNE $7B83 ; {} INC $5B ; {ram.??timeout??}
    content/Arcade/Asteroids/Code.md#L2556-L2563 · upstream ↗
    LSR $5B ; {ram.??timeout??} Code check. This value is incremented by one each BCC $680C ; {}
    content/Arcade/Asteroids/Code.md#L35-L36 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  11. ^Up and down have no inertia in Defender: a held direction moves the ship 1 pixel a frame at once, rising by 8/256 of a pixel each frame to 2 pixels a frame (after 32 frames, computed), and letting go stops it. The ship stops climbing once at row 43 or higher, and descending at row 238 or lower.Codemwenge/defender
    How we know
    2441*VERTICAL MOTION
    2442        LDB    PLAY16           ;GET ADDR FOR LIMIT CHK
    2443        LDA    PIA31            ;UP?
    2444        LSRA 
    2445        BCS    PLAUP            ;YES
    2446        LDA    PIA21
    2447        BMI    PLADN            ;DOWN
    2448        LDD    #0
    2449        BRA    PYV1
    2450PLAUP   CMPB   #YMIN+1
    2451        BLS    PLAYX
    2452        LDD    PLAYV
    ⋮
    
    src/defa7.src lines 2441–2476 at e740063 · upstream ↗
    20YMAX    EQU    240
    21YMIN    EQU    42               ;MIN Y COORD
    
    src/phr6.src lines 20–21 at e740063 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

Sources

Code