G-code and 3D Printing Standards
How generated G-code stays safe on real hardware: the machine is never asked to move from an unknown position, never asked to extrude cold, and never asked to override a firmware safety feature. Every rule here maps to a specific way printers catch fire, crash, or ruin a plate.
Baseline: Marlin 2.1.x and Klipper current stable. Both accept the standard G-code below, the difference is that Klipper expects complex sequences to live in Jinja2 macros rather than in the slicer.
When to activate
- Writing or reviewing start, end, layer-change, or tool-change G-code.
- Building or editing a Klipper macro.
- Diagnosing a crash, a cold extrusion, a nozzle dragging through a print, or a Z-offset problem.
- Calibrating pressure advance, extrusion multiplier, or retraction for a filament.
- Version-controlling slicer profiles or embedding a profile reference in output.
- Generating or post-processing G-code from a script.
When not to activate
- Designing the PCB the printed enclosure houses, use
kicad. - Writing firmware for the printer's own microcontroller, use
embedded-c-arduino. - Writing the shell script that uploads or post-processes the file, use
bashorpowershell. - Automating the printer from Home Assistant, use
home-assistant. - Documenting the printer setup for other people, use
markdown-writer.
Thermal safety
Never override or disable firmware thermal runaway protection from G-code. It is the feature that stops a detached
thermistor from turning into a fire. Use the blocking heat commands before any extrusion: M109 waits for the
hotend, M190 waits for the bed. The non-blocking M104 and M140 are for starting a heat-up early, never as the
only heat command before extruding, because cold extrusion shreds filament and strips the extruder gear.
Pass:
M140 S60
M104 S215
M190 S60
M109 S215
Fail:
M104 S215
G1 E10 F300
Respect the hardware ceiling: a PTFE-lined hotend stays at or below 230 C, because PTFE decomposition starts above
240 C and off-gasses. An all-metal hotend follows the manufacturer's stated maximum. Run M303 E0 S<temp> C8 PID
tuning before committing a new filament profile.
Declare the coordinate mode
Never rely on the machine's assumed state. Declare absolute positioning with G90 and pick the extruder mode
explicitly: M82 for absolute E values, M83 for relative. The choice must match what the slicer profile computes.
Use G91 only for an immediate micro-move such as a Z-hop, and return to G90 on the next line.
Pass:
G90
M83
Fail:
G1 X50 Y50 F3000
Home before moving, and stay inside the build volume
G28 before any G0 or G1. A move commanded from an unknown position is a crash. Be given the exact build volume
and never generate a coordinate outside it.
Pass:
G28
G1 Z5 F600
Fail:
G1 Z0 F600
Z-hop over already-printed areas so the hot nozzle cannot collide with and dislodge the part:
G91
G1 Z0.4 F600
G90
G0 X120 Y95
G91
G1 Z-0.4 F600
G90
Klipper macros over raw sequences
On Klipper, tool changes, filament runout, and mesh levelling go through pre-configured Jinja2 macros, so the logic
lives in printer.cfg under version control rather than being regenerated by every slicer export.
Pass:
START_PRINT BED_TEMP=60 EXTRUDER_TEMP=215
Fail:
M190 S60
M109 S215
G28
BED_MESH_CALIBRATE
G1 X1 Y20 Z0.3 F5000
Feedrate F is always millimetres per minute, never mm/s, so 600 is 10 mm/s. Insert M400 before anything that
needs the toolhead physically stopped: a camera snapshot, a macro handoff, a pause.
Start G-code, bed mesh and purge line
The sequence is fixed: home, level, heat to the real target, purge outside the part, then print. Never hard-code a Z-offset, read it from the printer's saved configuration. Never purge over the area the part will occupy.
Pass, a complete start sequence for a 220 x 220 bed:
G90
M83
M140 S{bed_temperature}
M104 S{first_layer_temperature}
G28
M190 S{bed_temperature}
M109 S{first_layer_temperature}
BED_MESH_PROFILE LOAD=default
G92 E0
G1 Z5 F600
G1 X1.0 Y20 Z0.3 F5000
G1 E10 F300
G1 X1.0 Y180 E25 F1500
G1 X1.4 Y180 Z0.3 F5000
G1 X1.4 Y20 E40 F1500
G92 E0
G1 Z2 F3000
On Marlin with UBL or BLTouch, replace the BED_MESH_PROFILE LOAD=default line with G29.
And the matching end sequence, which retracts, lifts, parks clear of the part, and cuts the heaters and motors:
M400
G91
G1 E-4 F2100
G1 Z10 F600
G90
G1 X5 Y200 F6000
M104 S0
M140 S0
M106 S0
M84 X Y E
M117 Print complete
Fail, an end sequence that leaves the nozzle sitting on the part with the heaters live:
M104 S0
M84
The pair belongs together in the slicer profile and in version control. The end sequence retracts before it lifts, so no ooze is dragged across the top surface, and it leaves the Z motor energised so the gantry cannot drop.
Emergency stop and operator checkpoints
Insert ; VERIFY: <instruction> comments where the operator must confirm hardware state, bed clear or filament
loaded, before the sequence continues. Use M112 as the abort in any script detecting a fatal condition, and
understand that it cuts power to all motors and heaters and needs a firmware restart afterwards.
Pass:
; VERIFY: bed clear and previous part removed
Fail:
M0 Click to continue
Reference files
| Open this | For |
|---|---|
| references/calibration-and-profiles.md | Calibrating a new filament, fan and seam post-processing, multi-material tool changes, and slicer profile version control |
Related skills
kicadfor the board that goes inside the printed enclosure.embedded-c-arduinofor firmware on the printer's own controller.home-assistantfor automating the printer, its power, and its notifications.bashandpowershellfor upload and post-processing scripts.markdown-writerfor the printer and profile documentation.
Checklist
- No G-code overrides or disables a firmware thermal safety feature.
-
M109andM190block before the first extrusion, hotend ceiling respected. -
G90and an explicitM82orM83declared before any move. -
G28precedes every XYZ move, and no coordinate leaves the build volume. - Z-hop wraps every travel move over printed material.
- Complex sequences invoke a Klipper macro rather than inline G-code.
- Start sequence homes, levels, heats, and purges outside the part, with no hard-coded Z-offset.
- End sequence retracts, lifts, parks clear, and cuts heaters and fan.
- Every
Fvalue is in mm/min. - Pressure advance, extrusion multiplier, and retraction recorded per filament.
- Slicer profile committed, and its name and version stamped in the G-code header.