Skip to content

Punch It: Kick a Vessel with an Impulse

Sometimes you don’t want to fly a ship anywhere. You want to reach into the sim and shove it : a clean, instant kick in a direction you name out loud. “Punch it to the left.” “Boot it straight up.” No engine, no propellant, no pointing the nose first.

That’s exactly what the impulse cheat does, and it’s just one write to a /sim file. In this rung we’ll wrap it in a friendly little program so a shove is one line in the terminal:

Terminal window
python3 punch-it.py --vessel Hunter --direction left --force 50000

The whole trick is turning a human word: front, back, left, right, top, bottom: into the vector the game wants. And thanks to one keyword, the game does the hard part for us.

  1. Basic gatOS I/O Toolkit: we import just write from gatos_io.py to poke the control file. That’s the only helper this program needs.

  2. A sense of the vessel’s own frame: the idea below. If you’ve done Point at Parent or the EVA Part Taxi you’ve already met the body axes; if not, the one picture in the next section is all you need.

The impulse cheat lives under /sim/debug/…, so you need the debug namespace on (debug_namespace, the default). If /sim/debug is missing, that’s why.

The idea in one picture: the vessel’s own frame

Section titled “The idea in one picture: the vessel’s own frame”

“Left” and “up” only mean something relative to the ship. A vessel tumbling through space doesn’t have a left in any fixed, cosmic sense: but it always has its own left, out its port side. So that’s the frame we work in: the vessel body frame, which rides along with the ship wherever it points.

KSA lays that frame out aircraft-style. Three axes, fixed to the hull:

+X nose (front)
−Y ←───┼───→ +Y left ← • → right
−X tail (back)
third axis, through the belly: +Z = down (bottom) , −Z = up (top)

So each of our six words is just a unit push along one of those axes, scaled by however hard you want to hit it. Call the force F:

You sayBody axisVectorWhich way it goes
front+X (nose)+F 0 0forward, out the nose
back−X−F 0 0backward, out the tail
right+Y 0 +F 0to the vessel’s right
left−Y 0 −F 0to the vessel’s left
top−Z 0 0 −Fup (yes: up is −Z)
bottom+Z 0 0 +Fdown

Here’s the part that makes the program tiny. The impulse control file takes an optional frame keyword after the numbers:

/sim/debug/vessels/<id>/impulsex y z [cci|body] [ns|dv]

Write body and the game reads your vector in the vessel’s own frame and rotates it through the ship’s live attitude for you, at the instant it applies. So 0 -F 0 body is always a shove to the ship’s left: whether it’s pointing at the Sun, flying backwards, or slowly cartwheeling. We never touch a quaternion; the body keyword is the rotation.

(Leave it off and the vector is read in CCI, the parent body’s fixed frame: handy when you’ve done orbital math, but no good for “left”.)

Save this next to your toolkit modules as ~/tutorials/punch-it.py:

~/tutorials/punch-it.py
#!/usr/bin/env python3
# Punch a vessel in a human direction with a one-shot impulse.
# No engine, no propellant, no aiming: one write to the impulse cheat.
# python3 punch-it.py --vessel Hunter --direction left --force 50000
import argparse, sys
from gatos_io import write
# The vessel body frame is aircraft-style: +X = nose, +Y = right, +Z = DOWN.
# Each word is a unit push on one axis (remember: "top" = up = -Z).
DIRECTIONS = {
"front": ( 1.0, 0.0, 0.0), # forward, along the nose (+X)
"back": (-1.0, 0.0, 0.0), # backward, out the tail (-X)
"right": ( 0.0, 1.0, 0.0), # to the vessel's right (+Y)
"left": ( 0.0, -1.0, 0.0), # to the vessel's left (-Y)
"top": ( 0.0, 0.0, -1.0), # up (+Z is DOWN, so up is -Z)
"bottom": ( 0.0, 0.0, 1.0), # down (+Z)
}
ap = argparse.ArgumentParser(description="Kick a vessel with a one-shot impulse, in its own frame.")
ap.add_argument("--vessel", required=True, metavar="ID",
help="target vessel id (need NOT be the one you're controlling)")
ap.add_argument("--direction", required=True, choices=DIRECTIONS,
help="which way to shove it, in the vessel's own frame")
ap.add_argument("--force", required=True, type=float,
help="impulse magnitude, newton-seconds (N·s)")
ap.add_argument("--dv", action="store_true",
help="treat --force as a direct velocity change in m/s instead of N·s")
args = ap.parse_args()
if args.force < 0.0:
sys.exit(f"--force must be >= 0; got {args.force}")
# Direction word -> unit vector on a body axis -> scale by the magnitude.
ux, uy, uz = DIRECTIONS[args.direction]
x, y, z = ux * args.force, uy * args.force, uz * args.force
# Build "x y z body [dv]" and write it. `body` = read the vector in the vessel's
# own frame (so "left" is always ITS left). Unit is newton-seconds unless --dv,
# which applies the vector straight as a velocity change in m/s.
line = f"{x} {y} {z} body"
if args.dv:
line += " dv"
write(f"/sim/debug/vessels/{args.vessel}/impulse", line) # errno on failure -> OSError
kind = f"{args.force:g} m/s Δv" if args.dv else f"{args.force:g} N·s"
print(f"punched {args.vessel} {args.direction} with {kind}", file=sys.stderr)

That’s the whole thing. A lookup table, a multiply, and a single write. The body keyword absorbs all the geometry that would otherwise be a page of quaternion math: this is the impulse cheat’s whole appeal.

Under the program, that one write is the same actuation you can do by hand: from inside the guest, or over HTTP from your own machine. Pick a transport; the page follows your choice.

The file twin of the program: shove Hunter to its left with a 50 kN·s impulse:

Terminal window
echo "0 -50000 0 body" > /sim/debug/vessels/Hunter/impulse

Straight up (−Z), a harder 200 kN·s:

Terminal window
echo "0 0 -200000 body" > /sim/debug/vessels/Hunter/impulse

A precise forward nudge of exactly +5 m/s (skip the mass math with dv):

Terminal window
echo "5 0 0 body dv" > /sim/debug/vessels/Hunter/impulse
~/tutorials
# who's around to punch?
ls /sim/vessels/by-id
# boot Hunter to its left with a 50 kN·s impulse
python3 punch-it.py --vessel Hunter --direction left --force 50000
# launch it straight up, hard
python3 punch-it.py --vessel Hunter --direction top --force 250000
# a precise, engine-free +10 m/s forward jump (--dv reads --force as m/s)
python3 punch-it.py --vessel Hunter --direction front --force 10 --dv

Watch the ship in the map or flight view: it doesn’t spin up an engine or spend a drop of fuel: its velocity just jumps, in one tick, exactly the way you asked. The orbit redraws itself around the new push instantly.

You’ve now got the two halves of playing god with a vessel’s state: teleport sets where it is and how fast, and this sets a sudden change to how fast: instantly, in any direction the ship calls its own.

A couple of natural next moves:

  • Kick a whole formation at once. A single impulse is frame-phased (one command per tick), so shoving several ships together smears them just like a looped teleport does. The fix is the same: batch the writes through /sim/ctl/batch so they all land in one tick (see the teleport tutorial’s batch aside).
  • Aim in the world frame. Drop the body keyword and your vector is read in CCI: so a kick along the velocity unit vector is a pure prograde/retrograde Δv, no flight computer required. That’s the bridge to real maneuver planning.