Demo Media¶
Last updated: September 6, 2026
Current approach: generated stills¶
Screenshots are generated from a committed scene rather than captured by hand, so they can be regenerated whenever geometry, materials, or defaults change.
# 1. Build the showcase level (headless, writes samples/hf_demo_showcase.tscn)
godot --headless -s res://tools/build_showcase_scene.gd --path .
# 2. Render the stills into docs/images/ (must NOT be headless)
godot --path . -s res://tools/capture_showcase.gd
Step 2 requires a real rendering context: under --headless the dummy renderer
writes blank images, and the script refuses to run rather than emit them.
Current output, all 1920x1080 and referenced from README.md:
| File | Shot |
|---|---|
docs/images/showcase_hero.png |
Interior down the colonnade toward the dais |
docs/images/showcase_overview.png |
The level from above, showing the window bays and towers |
docs/images/showcase_gallery.png |
Low view up through the columns to the gallery |
Edit LAYOUT in tools/build_showcase_scene.gd to change the level, or SHOTS
in tools/capture_showcase.gd to change framing. The level AABB is
x -17..31, y -1..10, z -15..13; elevated cameras must clear the 10-unit walls
or the nearest corner fills the frame.
Editor UI screenshots¶
The interface shots and the how-it-works strip are captured by
addons/hf_docshot, a dev-only editor plugin. It opens the showcase scene,
drives the editor's own 3D camera, cycles the dock tabs, switches main screens,
and writes the images before quitting.
python tools/capture_ui.py
The plugin is not enabled in project.godot. The wrapper enables it for the
duration of the run and removes it again, because an EditorPlugin that reads
an environment variable and can call get_tree().quit() should not load during
normal editing -- a stray HF_DOCSHOT=1 would otherwise close your editor
mid-work. The env var remains as a second gate for anyone enabling the plugin
by hand.
Composing the shot¶
Screenshots are product shots, not screenshots of a dev checkout. Before capturing, the plugin composes the editor:
- The onboarding guide card is suppressed. It otherwise fills the top ~40%
of the dock with "Step 1 of 2" tutorial chrome. Turn it off first:
godot --headless -s res://tools/prepare_editor_smoke.gd --path . -- --show-welcome=false - Godot's own docks are hidden (Scene, FileSystem, Inspector). They are not
HammerForge UI: the Inspector shows a column of truncated bake property
labels, and the FileSystem shows repository files. Hiding them roughly
doubles the viewport width. This is done live, because Godot clamps dock
splitter offsets written into
editor_layout.cfg. - The selection is cleared after the camera is placed, so the transform gizmo does not sit in the middle of the level.
- The scene is verified active.
open_scene_from_pathalone is not enough; the project main scene can reclaim the tab, so the capture retries untilget_edited_scene_root().scene_file_pathmatches.
Use the wrapper rather than editing anything by hand:
python tools/capture_ui.py
It suppresses the onboarding card, removes the contributor MCP server from
project.godot so it does not appear in the editor's main-screen bar, resets
the open-scene list so the tab bar is not cluttered, runs the capture, and puts
both files back.
The swap is recoverable, not merely careful. It refuses to start if either
tracked file already has uncommitted changes, so it never backs up an
already-mutated file; backups carry a marker, so a run that dies before
restoring is healed by the next invocation instead of stacking a second swap on
top; and restoration runs from a finally block, so it survives exceptions and
Ctrl-C. The MCP server is build tooling for contributors, not part of
HammerForge, and must not appear in user-facing screenshots.
Output:
| File | Shot |
|---|---|
ui_editor_3d.png |
Dock, viewport toolbar, scene tree and inspector |
ui_dock_build.png / ui_dock_paint.png / ui_dock_objects.png / ui_dock_test.png |
Each dock mode |
ui_console.png |
The Console status board |
ui_console_controls.png |
The Console Controls tab: every setting, grouped |
seq_1_draw.png … seq_4_test.png |
The four-step how-it-works strip (cropped) |
Three editor behaviours the plugin has to work around, all commented in the
script: the editor restores its previous session after _enter_tree, so the
showcase must be opened late or it loses the active tab; opening a level hands
the main screen back to the HammerForge plugin, so each screen is re-selected
immediately before its own capture; and F-to-frame never reaches the viewport,
so the editor camera is positioned directly.
Captures are not byte-stable¶
Re-running a capture with no changes still produces slightly different PNGs.
The Console header carries a live Checked HH:MM:SS timestamp, and antialiasing
around dock text varies with layout timing, so a few kilobytes shift each run.
Only commit regenerated images when something actually changed. git restore
docs/images/ discards a no-op run.
Not covered by the stills¶
Nothing currently captures the bake pipeline running, or any interaction that only makes sense in motion (dragging a brush out, extruding a face). Those still need a screen recording.
Video clips (deferred)¶
Screen-recorded clips were planned in February 2026 and never produced. They are
deferred rather than dropped; stills cover the immediate "what does this look
like" gap. If clips are revisited, keep them at 1280x720 or 1920x1080 and name
them demo_<topic>_vX.Y.Z.mp4 in this directory.