Skip to content

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_path alone is not enough; the project main scene can reclaim the tab, so the capture retries until get_edited_scene_root().scene_file_path matches.

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.pngseq_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.