Skip to content

HammerForge User Guide

Last updated: September 5, 2026

This guide covers the current HammerForge workflow in Godot 4.7: brush-based greyboxing, bake, entities, floor paint, and per-face materials/UVs.

Quick Start

  1. Enable the plugin: Project -> Project Settings -> Plugins -> HammerForge.
  2. Open any 3D scene. HammerForge now appears in the main-screen switcher at the top of the editor, beside 2D, 3D and Script, and the left dock is titled HammerForge.
  3. In the empty-state banner, click Create Starter to add a LevelRoot, floor, sunlight, and player spawn. Use Create Empty when you want only the root.
  4. In Build, choose Draw and drag in the viewport to set the base; click again to set the height.
  5. Open Test and click Test Level (Bake + Play). HammerForge checks the spawn, bakes, and launches the playtest.

If anything is not behaving, open the Console (the HammerForge entry in the switcher) and read the Status board. It is the fastest way to find out what is wrong and what fixes it.

HammerForge Console

Open it from HammerForge in the main-screen switcher. The overall lamp also sits in the 3D viewport toolbar while you build; clicking it opens the Console.

Three tabs.

Status

Eight checks, each a red / amber / green lamp with what was measured, what it means, and the one button that resolves it.

Check Green Amber Red
Level root A LevelRoot is in the open scene No LevelRoot, so every tool is inert — Create Starter Level
Geometry budget 50 brushes + entities or fewer Above 50; bakes get slower Above 100; dragging starts to stutter
Bake Baked meshes match the drafts Never baked, or brushes edited since — Bake Now
Level check Scanned, no faults 1–5 issues — Check + Fix 6 or more
Material palette Materials loaded Empty (fine for greyboxing) — Load Palette Empty and face-material bake is on
Player spawn At least one spawn point None, but auto-spawn is on — Add Spawn Point None and auto-spawn is off
Autosave On, and a snapshot exists Off, or nothing written yet — Turn On
Session log No warnings Warnings this session — Open Log Errors this session

A grey lamp means not measured yet — usually because no level is open. It is not a fault.

Every lamp carries a shape as well as a colour (tick, exclamation, cross, dash), so the board reads the same with a red/green colour deficiency. Hover any row for the thresholds behind it. Needs attention only hides the checks that are already fine.

The header carries the overall lamp, the live scope line (Arena · 74 brushes · 9 entities · ~3120 verts · 256 KiB paint), and when the board was last checked. Counts refresh once a second while the Console is open; the two measurements that walk the whole level refresh on a slower beat or when you press Re-check.

Controls

Every HammerForge switch on one screen, grouped by what it affects:

  • Viewport — show grid, grid follows brush, shortcut HUD, power-user overlays, I/O connection lines, subtract preview, spawn debug, texture lock, cordon
  • Bake — merge meshes, LODs, unwrap UV0, lightmap UV2, face materials, navmesh, visible only, MultiMesh, material atlas, auto connectors, wire I/O, occluders, worker threads, freeze on commit, chunk size
  • Safety net — autosave (with interval and backups kept), compress saves, auto-spawn player, debug logging

Each switch is captioned with what it does, and Find a setting searches those captions as well as the names, so "pathfinding" finds Bake navmesh. Turn Descriptions off to fit more on screen; the text stays on the tooltips. A switch with nowhere to write — no level open — is disabled rather than shown at a made-up default.

These are the same settings as Test → Settings and Test → Advanced Bake in the dock. The Console writes through the dock's own controls, so the two always agree.

Log

HammerForge's own messages, separate from Godot's Output panel where every addon's output is mixed together. The level buttons show how many of each arrived this session and double as the filter — click Errors 2 to see just those two. Follow keeps the newest line in view, and Copy / Save… take whatever is currently shown.

A message that repeats collapses to one row with a count ((x4)) rather than filling the buffer. The buffer holds the most recent 600 entries; the footer says how many older ones were dropped.

Viewport Mouse Controls

Plain RMB uses Godot's native 3D camera look whenever HammerForge is idle. It works the same whether nothing, a brush, a face, an entity, a camera, or another scene node is selected, and persistent tool modes do not claim it just by being enabled. While RMB is held, native W/A/S/D camera flight and mixed mouse input stay with Godot and cannot accidentally switch tools, draw, or change selection. MMB and the mouse wheel also remain available to Godot for camera navigation.

Alt+LMB is also reserved for Godot's alternate viewport navigation and transform schemes. HammerForge does not begin a selection or box-select gesture from that press.

In Select mode, every ordinary LMB click or drag uses Godot's native Object Select pipeline. HammerForge contributes accurate filled gizmo hit targets for brush faces and visible entity preview meshes; it does not draw a second object rectangle or guess whether the press was on a transform/property widget.

Press starts on Result
Empty viewport space Godot handles the empty click or its native object box selection
A visible HammerForge brush/entity surface Godot selects it through the filled face/preview hit target, then HammerForge normalizes its owner or group
A selected brush, resize handle, or transform/property widget Godot or the custom brush gizmo owns the complete drag; no competing HammerForge selection appears
A native Godot object or gizmo, such as a camera or light Godot owns the click and drag; HammerForge remains available for the level but does not edit through it

Object selection follows Godot's modifiers, not a second HammerForge rule set. Shift keeps Godot's native additive/active-selection behavior for clicks and adds native box-selection results. Ctrl/Cmd are left to Godot's configured viewport transform and navigation behavior; HammerForge does not turn them into an Object Select toggle.

Once a transform/property widget or yellow resize handle claims a press, it owns the whole gesture—including Escape and keyboard modifiers—until release or recovery. HammerForge will not start a box selection, nudge with Ctrl+Arrow, paint, or trigger another tool underneath it.

Godot's visible EditorSelection is authoritative. HammerForge reads native click and region results after Godot finishes them, maps internal entity-preview children back to their object, and expands brush groups as one selection unit. Clearing the Scene tree or clicking empty space remains a real empty selection; HammerForge does not preserve a hidden stale selection behind it.

Face Select Mode is a focused modal state rather than a second object-selection layer. Enabling it switches to the Select tool, turns Paint off, saves the current object selection, and temporarily clears it. That hides Godot's transform widget and HammerForge's resize handles so they cannot overlap a face click or marquee. Face Select has its own deliberate modifiers: Shift adds faces; Ctrl/Cmd toggles faces. Turning the mode off manually clears the face selection and restores still-valid objects from the snapshot. Leaving the Paint tab, choosing an incompatible built-in or external tool, or entering Vertex Edit closes Face Select through the same restore path. Selecting an object in the Scene tree exits immediately and keeps that newly selected object instead of restoring the old snapshot. Escape clears selected faces first; press it again to exit and restore objects, or press it once to exit when no faces are selected.

During an interaction that already owns the pointer, RMB keeps its local meaning: it cancels an active draw, extrusion, Face Select marquee, or vertex drag, and steps back one point while Polygon or Path placement is active. An active paint stroke keeps pointer ownership until LMB is released. Explicitly cancelled releases and buttonless motion restore or settle HammerForge-owned transient edits. On application/window focus loss, HammerForge clears its transient owners while Godot settles any native or custom gizmo it owns, so one gesture is never committed and restored by two systems. In the Measure tool, use Ctrl+Click (or Cmd+Click on macOS) to set a snap reference. Press Space for HammerForge's contextual viewport menu.

LevelRoot

LevelRoot is required because it owns the containers and systems HammerForge uses: - DraftBrushes, PendingCuts, CommittedCuts - PaintLayers and Generated (floors/walls) - Entities - Baker and paint systems

The empty-state banner is the clearest way to create it. An intentional left-click while the Draw tool is active can also create an empty root; camera navigation, right-clicks, and other passive viewport input never mutate the scene. LevelRoot stays active even when you select other scene nodes (sticky root discovery) -- you do not need to re-select it after clicking a camera, light, or other node.

First-Run Tutorial

On first launch, a short tutorial guides you through the essential two-step loop:

Step Goal Trigger
1 Draw something Place any brush
2 Test your level Complete a successful bake with Test Level Now

Each step auto-advances when you complete the required action. You can go back, skip, or hide the guide. Progress persists across sessions if you close and reopen the editor.

Use Don't show at startup to hide it on future launches. Reopen or restart the guide from Help; you do not need to edit preference files.

Coach Marks (First-Use Tool Guides)

Opt-in. This is one of the power-user overlays, off by default so the core loop stays quiet. Turn on Power-user overlays in the Console's Controls tab, or in the dock under Test -> Settings.

When you activate an advanced tool for the first time, a floating overlay appears with step-by-step instructions. Coach marks are available for 10 tools:

Tool Trigger Steps shown
Polygon P key Click vertices → close loop → set height → confirm
Path ; key Place waypoints → Enter → set height → confirm
Vertex Edit V key Select → multi-select → edge mode → merge/split
Extrude E/U/J keys Select brush → click face → drag → confirm
Carve Ctrl+Shift+R Select brushes → preview (green wireframe) → confirm → delete fragments
Clip Shift+X Select → preview (cyan wireframe + orange plane) → confirm → split
Hollow Ctrl+H Select solid → preview (yellow wireframe walls) → confirm → hollow
Measure M key Click start → click end → Shift+Click to chain → Ctrl+Click for snap ref
Decal N key Click surface → resize/rotate → assign material
Surface Paint Shift+P toggle Toggle paint → select tool → click cells

Each guide has a "Don't show again" checkbox. Dismissed guides are persisted in user prefs. Guides trigger from keyboard shortcuts, the command palette, and context toolbar actions.

Operation Replay Timeline

Opt-in. This is one of the power-user overlays, off by default so the core loop stays quiet. Turn on Power-user overlays in the Console's Controls tab, or in the dock under Test -> Settings.

Press Ctrl+Shift+T to toggle a compact timeline showing your recent operations (up to 20). Each operation appears as a color-coded icon:

Color Action Type
Blue Draw / Create brush
Red Delete / Remove
Orange Subtract
Green Extrude
Yellow Carve / Clip
Purple Vertex / Merge / Split

Hover an entry to see its name and elapsed time. Click an entry, then click Replay to undo or redo the history to that point. The timeline records every action that passes through the undo/redo system.

Undo History Browser

The Test tab → History section contains a visual undo history browser with viewport thumbnails. It replaces the plain text history list:

  • Up to 30 entries are recorded, each with a color-coded action icon and an 80x48 viewport thumbnail captured at the time of the action.
  • Hover an entry to see an enlarged thumbnail preview.
  • Double-click an entry to navigate the undo/redo system to that point in history.
  • Undo/Redo buttons are integrated into the browser header, with disabled state automatically tracking the undo/redo manager.
  • Action icons reuse the same color scheme as the Operation Replay Timeline (blue=draw, red=delete, etc.).

Error Prevention & Forgiveness

HammerForge prioritizes non-destructive workflows so you can experiment freely:

Geometry Previews (Preview Before Commit)

Destructive geometry operations show a wireframe preview overlay before permanently modifying brushes:

Operation Preview Color What It Shows
Carve (Ctrl+Shift+R) Green wireframe All resulting slice pieces
Clip (Shift+X) Cyan wireframe + orange plane Two resulting halves + the cut surface
Hollow (Ctrl+H) Yellow wireframe 6 wall pieces at the chosen thickness
Extrude (U/J) Semi-transparent brush New brush being extruded from the face
Subtract (toggle) Red CSG cut Live intersection of overlapping subtract/additive brushes

Each preview appears immediately, then a confirmation dialog gives you the option to Cancel and abort without changing anything.

Bulk Delete Safeguard

Deleting 3 or more brushes at once prompts a confirmation dialog. The dialog reminds you that Ctrl+Z can undo the deletion. Deleting 1-2 brushes remains instant (no friction for common operations).

Undo Everything

All brush operations (draw, delete, carve, clip, hollow, extrude, move, resize, merge, material assignment, UV changes) are fully undoable via Ctrl+Z. The Undo History Browser (Test tab) provides visual navigation with thumbnails.

Measure Tool (Multi-Ruler)

Press M to activate the Measure tool. It supports persistent multi-ruler measurements with angle display and snap references:

  • Click to set point A, click again to set point B — a ruler line appears with distance, dX/dY/dZ decomposition.
  • Shift+Click chains a new ruler from the last ruler's endpoint. Consecutive chained rulers that share a vertex display the angle between them in degrees.
  • Up to 20 rulers can be active simultaneously, each drawn in a cycling color palette.
  • Ctrl+Click near a ruler to set it as a snap reference line. The snap system will project nearby points onto that line.
  • Press A to toggle align mode on/off.
  • Press Delete/Backspace to remove the last ruler.
  • Press Escape to clear all rulers.
  • The HUD shows ruler count, distance of the last ruler, and alignment status.

Command Palette (Ctrl+K)

The command palette is a searchable action list. Open it with Shift+?, F1, or Ctrl+K.

  • Type to filter actions by name or keybinding
  • Fuzzy search: if no exact match, the palette finds approximate matches using subsequence matching with word-boundary bonuses
  • "Did you mean: ..." suggestion appears when fuzzy matching kicks in
  • Actions gray out when unavailable (e.g., Hollow requires a brush selection)
  • Press Enter to execute the first visible enabled action
  • Press Esc to close without executing

Example Library

The Test tab contains an Examples section (collapsed by default) with 5 built-in demo levels:

Example Difficulty Key Concepts
Simple Room Beginner Additive brushes, floor
Corridor with Doorway Beginner Subtract operations, spatial planning
Jump Puzzle Platforms Intermediate Multiple brushes, player spawn entity
Hollowed Building Intermediate Hollow + subtract for windows
Simple Arena Advanced Multi-level, ramps, cover, multiple spawns
  • Load clears the current level and instantiates the example's brushes and entities
  • Study This shows numbered annotations explaining the design decisions
  • Search/filter by title, description, tags, or difficulty level

Dock Layout (4 tabs)

The dock has 4 tabs with collapsible sections for organized access to all controls. Each collapsible section has a visual separator and indented content; collapsed state persists across sessions. A "No LevelRoot" banner appears at the top when no root node is found.

Mode Indicator

A colored banner between the toolbar and tabs always shows your current tool and gesture stage: - Draw (blue) -- "Step 1/2: Draw base — 64 x 32 x 48" / "Step 2/2: Set height — 64 x 96 x 48" (live dimensions update as you drag) - Select (green) - Extrude ▲ (green) / Extrude ▼ (red) -- "Extruding..." - Paint (orange)

When typing numeric input during a gesture, the value appears in brackets (e.g. "[64]").

Toolbar

The primary toolbar keeps the everyday path visible: Draw, Select, Paint, More, and Help. Operation and advanced geometry commands live in Build sections, the context toolbar, or More. Help opens the guide and shortcut discovery; Shift+?, F1, or Ctrl+K opens the command palette.

Build tab

  • Tools: Draw and Select are always available in the primary toolbar. Use More, contextual actions, or the sections below for advanced operations.
  • Shape: choose from 15 built-in shapes with recognizable icons (plus Custom). Sides appears only for compatible pyramid/prism shapes.
  • Size X/Y/Z: defaults for new brushes.
  • Grid Snap: snap increment with quick preset buttons (1, 2, 4, 8, 16, 32, 64).
  • Snap Modes: G (Grid), V (Vertex), C (Center), E (Edge midpoint), and P (Perpendicular projection). Toggle independently; the closest eligible geometry candidate within the threshold beats grid snap.
  • Material: active material picker.
  • Physics Layer: collision layer for baked output.
  • Texture Lock: UV alignment preserved on move/resize (enabled by default).
  • Selection Tools (visible when brushes are selected, grouped by domain):
  • Brush Modification: Hollow (wall thickness spinner + button, Ctrl+H) with yellow wireframe preview; Clip Selected (Shift+X) with cyan wireframe preview + orange split plane. Carve (Ctrl+Shift+R) with green wireframe preview. Merge (Ctrl+Shift+M) combining 2+ brushes.
  • Positioning: Move to Floor (Ctrl+Shift+F) / Ceiling (Ctrl+Shift+C).
  • Entity Binding: Tie/Untie brush entity class (populated from entity definitions).
  • Duplicate Array: count, X/Y/Z offset, Create/Remove Array buttons.
  • Bulk delete: deleting 3+ brushes shows a confirmation dialog (undo reminder). Single/dual deletes remain instant.

Paint tab (collapsible sections)

  • Floor Paint: Brush, Erase, Rect, Line, Bucket, Blend tools. Brush shape (Square/Circle), radius, and layer picker. Rename button ("R") for custom layer display names.
  • Heightmap: Import PNG/EXR or Generate procedural noise. Height Scale and Layer Y spinboxes. Sculpt tools: Raise, Lower, Smooth, Flatten buttons with strength/radius/falloff spinboxes for interactive terrain editing. Convert Selection → Heightmap button rasterizes selected brush top faces into a new heightmap layer (inherits grid origin/basis and chunk_size from the paint layer manager).
  • Blend & Terrain: Blend Strength, Blend Slot (B/C/D), and Terrain Slot A-D texture pickers with UV scales.
  • Foliage & Scatter: Interactive scatter brush for foliage and object placement. Pick a mesh resource, set density/radius/height constraints/slope filter/scale variation. Choose Circle or Spline brush shape. Preview generates a MultiMesh preview (Dots/Wireframe/Full). Scatter commits as a permanent MultiMeshInstance3D. Clear removes the preview. Spline mode uses selected nodes as path control points with a configurable width band.
  • Regions: Region Streaming enable, Region Size, Stream Radius, Show Region Grid, memory stats.
  • Materials: Visual thumbnail browser (HFMaterialBrowser) with search, pattern/color filters, and Prototypes/Palette/Favorites view toggle. Add/Remove/Refresh Prototypes buttons. Face Select Mode toggle. Assign to Selected Faces. Right-click thumbnails for context menu (Apply to Faces, Apply to Whole Brush, Toggle Favorite, Copy Name). Hover a thumbnail to preview on selected faces. Press T for Texture Picker (eyedropper). The Refresh Prototypes button batch-loads 150 built-in SVG textures (15 patterns x 10 colors) for quick greyboxing.
  • UV Editor: Per-face UV editing with drag handles, Reset Projected UVs, and Justify grid (Fit, Center, Left, Right, Top, Bottom in 3×2 layout).
  • Surface Paint: Paint Target (Floor/Surface), layers, texture picker, radius/strength.

Objects tab

  • Create DraftEntity button.
  • Entity palette with drag-and-drop placement.
  • Selected DraftEntity nodes use the same managed Delete, Ctrl+D Duplicate, arrow-key X/Z nudge, and PageUp/PageDown Y nudge workflow as brushes, including HammerForge undo/state cleanup.
  • Entity Properties (collapsible, context-hidden): auto-generated typed controls based on entity definition. Only visible when an entity is selected.
  • Entity I/O (collapsible, context-hidden): Output, Target, Input, Parameter fields. Delay (seconds) and Fire Once checkbox. Add Output / Remove buttons and connection ItemList. Only visible when an entity is selected; connections auto-refresh on selection change. Show I/O Lines checkbox to visualize connections in the viewport.
  • I/O Wiring (collapsible, context-hidden, collapsed by default): Quick-wire form (output name, target dropdown, input name, parameter, delay, fire-once). Only visible when an entity is selected. Connection summary shows triggers and triggered-by counts. Highlight toggle button pulses all linked entities in the viewport. Connection Presets picker with 6 built-in patterns (Door+Light+Sound, Button→Toggle, Alarm Sequence, Pickup+Remove, Damage+Break, Timer Lights) plus user-saved presets. Target tag mapping lets you assign preset target placeholders to actual entity names.

Progressive disclosure: During greyboxing, the Objects tab shows only the entity palette and create button. Entity Properties, Entity I/O, and I/O Wiring sections appear automatically when you select an entity, keeping the UI clean when you're focused on shapes and layout. - I/O connection lines: Bézier curves with arrowheads, color-coded by output type (cyan=OnTrigger, red=OnDamage, yellow=OnUse, green=OnOpen, magenta=OnBreak, orange=OnTimer). Fire-once connections pulse brighter; delayed connections dim proportionally. Parallel connections between the same pair offset laterally. - Highlight Connected: when enabled, all entities wired to the selected entity display a pulsing overlay. The context toolbar shows an "HL" toggle and an I/O summary label ("Triggers 2 targets (door1, light1)"). The highlight state stays in sync between the context toolbar and the wiring panel.

I/O Runtime Signal Translation

Entity I/O connections are automatically translated into live Godot signals when you bake or export a playtest scene. No manual signal wiring is required.

How it works: An HFIODispatcher node is injected into the exported/baked scene. On _ready(), it scans all entities for entity_io_outputs metadata and builds a connection table. When a source entity fires an output, the dispatcher delivers to each target via: 1. Direct method call (e.g. Open(), Kill()) 2. Snake-case variant (e.g. turn_on() for TurnOn) 3. Generic handler (_on_io_input(input_name, parameter)) 4. User signal (io_Open emitted on the target)

Firing outputs from game scripts:

# From any entity script at runtime:
HFIORuntime.fire_on(self, "OnTrigger")

# Or via the dispatcher directly:
var dispatcher = $HFIODispatcher
dispatcher.fire("my_button", "OnPressed", "fast")

Configuration: - Export Playtest: always auto-injects the dispatcher when entities have I/O connections. - Bake Wire I/O: on by default. Regular bakes and Test Level attach HFIORuntime when any entity has I/O connections. Uncheck bake_wire_io on LevelRoot (Inspector) to skip dispatcher attach. - Source entities receive io_<OutputName> user signals (e.g. io_OnTrigger) so you can also use standard connect() / emit_signal() patterns.

Test tab (collapsible sections)

  • Test Level: Test Level (Bake + Play) is the one-click default. Check Only validates without baking and Bake Only produces geometry without launching. Play from Camera and Play Selected Area remain available for focused testing.
  • Advanced Bake: Bake Selected/Changed, dry run, mesh, LOD, lightmap, navmesh, face material, preview, collision, chunking, occluder, and connector controls are collapsed until needed.
  • Actions: Create Starter, Create Empty/Create Floor, Apply/Clear/Commit/Restore Cuts, and Clear Brushes.
  • Spawn: Validate Spawn (bakes, then runs physics-based checks and shows debug overlay), Create Default Spawn (auto-places a player_start at brush centroid), Preview Spawn Debug (bakes, then shows persistent capsule/ray overlay toggle).
  • File: Save/Load .hflevel, Import/Export .map (Classic Quake / Valve 220), Export .glb.
  • Presets: Save/rename presets grid.
  • History: Undo history browser with thumbnails, color-coded action icons, double-click navigation, undo/redo buttons.
  • Settings: Show HUD, Show Grid, Follow Grid, Debug Logs, Autosave path/toggle, Settings Export/Import.
  • Performance: Health summary (green/yellow/red), brush count ProgressBar, entity count, vertex estimate, paint memory, chunk count, last bake time, recommended chunk size.
  • Visgroups & Groups: Visgroup list with [V]/[H] toggle, New/Add Sel/Rem Sel/Delete, Group Sel/Ungroup.
  • Cordon: Enable checkbox, min/max spinboxes, Set from Selection.
  • Prefabs: Save/search/filter/delete prefabs. Browse with tag filtering and variant indicators. Drag-from the library to instantiate. Save Linked for live propagation. Right-click for variant/tag editing.

Test Level and Spawn Validation

Test Level (Bake + Play) bakes the level and launches it with a first-person controller. Before every test:

  1. Spawn lookup: finds the active player_start entity (primary-flagged first, then first found).
  2. Auto-create: if no player_start exists, a safe default is created at the centroid of all brushes + 5 m height.
  3. Validation: physics-based checks (floor raycast, capsule collision, headroom, below-map). Issues appear as toasts and optional debug overlays.
  4. Fix dialog: critical issues (severity ≥ 2: inside geometry, floating in void) show a dialog offering "Fix & Play" (snaps to nearest valid floor) or "Cancel". Severity 1 warnings toast and proceed.
  5. Launch: bakes geometry + collision, then runs the scene with the FPS controller spawned at the validated position and yaw rotation.

Play from Camera

Click Play from Camera in the Test tab to playtest from your current editor camera position: - The spawn entity is temporarily moved to the camera position; camera yaw is written to entity_data["angle"]. - The level bakes, spawn is validated, and the playtest launches. - After launch, the spawn is automatically restored to its original position and angle. - On validation failure (severity ≥ 2), the spawn is restored before showing the fix dialog. - Full undo/redo support records both the position move and yaw change.

Play Selected Area

Click Play Selected Area to bake and playtest only the region around your current brush selection: - The current cordon state (enabled, AABB) is saved. - A temporary cordon is set from the AABB of the selected brushes. - The level bakes within that cordon, spawn is validated, and the playtest launches. - After launch, the original cordon state is restored (enabled/disabled, original AABB). - On validation failure (severity ≥ 2), the cordon is restored before showing the fix dialog.

Export Playtest Build

Click Export Playtest Build in Test → Advanced Bake to create a standalone playable scene: - Validates spawn (severity ≥ 2 blocks the export). - If no spawn exists, auto-creates a default (fully undoable with state capture). - Bakes the level in Full mode. - Packs baked geometry, brush entities, point entities, DefaultSun (if present), and fallback lighting (DirectionalLight3D + WorldEnvironment if no light exists) into a temporary scene at user://hammerforge_playtest.tscn. - Adds the playtest player controller at the active spawn and applies the spawn's yaw. - Preserves world transforms while reparenting export content and recursively owns nested geometry/collision so it survives scene packing. - Injects the entity I/O runtime automatically when the exported content contains connections. - Initializes only the runtime level core in the exported scene. Grid, drawing, snapping, selection, previews, prefab authoring, validation, undo, and other editor services are not loaded or constructed by export templates. - Launches the scene via EditorInterface.play_custom_scene(). - A toast confirms "Playtest launched" on success.

Incremental Bake

For faster iteration on large levels: - Bake Selected: bakes only the currently selected brushes and merges the output into the existing baked container. Previously baked geometry is preserved. - Bake Changed: bakes only brushes that have been modified (dirty-tagged) since the last successful bake. Dirty tags survive failed bakes and accumulate until the next success.

Bake Preview Modes

Use the Preview Mode dropdown in Test → Advanced Bake to choose how baked geometry renders: - Full: standard material rendering (default). - Wireframe: cyan wireframe overlay using a custom shader — useful for inspecting geometry topology. - Proxy: semi-transparent grey unshaded material — ultra-fast rendering for layout testing.

Quick Wireframe Preview: When brushes are selected, the context toolbar shows a Bake▷ toggle button. Click it to instantly bake with wireframe preview — you can see the final mesh topology before committing to a full bake. Click again to re-bake at full quality. This toggle: - Is fully undoable (Ctrl+Z reverts both the bake and the toggle state). - Stays in sync with the dock's Preview Mode dropdown — if you bake from the dock with Wireframe mode, the toolbar toggle reflects that. - Is disabled while a bake is in progress to prevent overlapping operations.

Bake Options

The Test → Advanced Bake section exposes additional controls: - Chunk Size (SpinBox, 0-256, default 32): spatial chunk size for bake grouping. Set to 0 to disable chunking. - Bake Visible Only (checkbox): skips hidden visgroups and invisible brushes during bake. - Use MultiMesh (checkbox): after baking, consolidates repeated identical meshes into MultiMeshInstance3D nodes. Useful for levels with many copies of the same brush shape — reduces draw calls. - Material Atlas (checkbox): packs per-face textures into a single atlas image so all atlased geometry renders in one draw call. Requires Use Face Materials to be enabled. Faces with tiling UVs (scale > 1) are automatically excluded and rendered as separate surfaces with their original material so texture repeat works correctly. Best for levels with many small non-tiling textures. Textures with painted layers or ShaderMaterials are not atlased. - PBR maps come along. Normal, roughness, metallic, and emission maps are packed into parallel atlases over the same layout, so materials keep their surface response. A material that supplies no map for a slot contributes a flat tile carrying its own scalar (its roughness value, its metallic value, a flat normal, or black), so mixing mapped and unmapped materials is fine. - Cost. Each packed slot is a second full-size atlas image, so a level whose materials carry all four maps holds five atlases rather than one. Slots no material supplies are never built. - When a slot is skipped. The atlas material holds one multiplier and one texture-channel selector per slot, so every material supplying a map has to agree on them. If they disagree — different roughness_texture_channel values, different normal_scale, a metallic map left at the default metallic = 0 multiplier — that slot is left out rather than baked wrong. Albedo still atlases. Give the mapped materials matching settings (multiplier 1.0 is the usual fix) to bring the slot back in. - Collision Mode (0/1/2, default 0): controls how baked collision shapes are generated. - 0 — Trimesh (default): single ConcavePolygonShape3D per chunk. Simple but worst-case for physics broadphase. - 1 — Per-brush convex: each brush gets a ConvexPolygonShape3D (convex hull). Much better for physics queries and bot navigation. - 2 — Per-visgroup partitioned: separate StaticBody3D per visgroup, each containing convex hulls for its member brushes. Best for navigation mesh generation and room-based broadphase. - Convex Clean (checkbox, default on): deduplicate vertices before building convex hulls. Disable to keep raw vertex data (degeneracy guard still runs). - Convex Simplify (slider, 0.0–1.0, default 0.0): reduce convex hull complexity by merging nearby vertices into an AABB-proportional grid. Higher values = fewer vertices = simpler collision. - Unwrap UV0 (checkbox): applies per-vertex planar UV projection during bake for surfaces that lack explicit UVs. - Generate Occluders (checkbox): automatically generates OccluderInstance3D nodes from large flat surfaces during bake. The bake pass groups coplanar triangles across the entire baked hierarchy (including chunked bakes) and emits occluders for groups exceeding the minimum area threshold. This enables Godot's built-in occlusion culling at runtime without manual occluder placement. Sub-controls: - Min Area (SpinBox, 0.5–100.0, default 4.0): minimum coplanar face-group area in world units² to emit an occluder. Raise this value to reduce occluder count (fewer culling tests); lower it to increase coverage (more surfaces act as occluders). Surfaces smaller than this threshold are skipped. - Auto Connectors (checkbox): auto-generates ramps or stairs between paint layers at different heights during bake. Requires at least 2 paint layers with filled cells at adjacent grid positions and a height difference ≥ 0.1 world units. Sub-controls: - Mode dropdown: Ramp (smooth slope), Stairs (stepped), Auto (stairs when height diff ≥ 2.0, ramp otherwise). - Step H (SpinBox, 0.05–2.0): stair step height in world units (only affects Stairs/Auto modes). - Width (SpinBox, 1–8): connector width in grid cells. Connectors are generated before navmesh baking, so the navmesh automatically covers connector surfaces. Auto-connectors are skipped during selection bakes (Bake Selected) to avoid pulling in unrelated geometry.

The main Bake button is smart: if only specific brushes have been modified since the last bake, it automatically uses incremental bake (Bake Changed) instead of a full re-bake.

Bake Issue Detection

Click Check Bake Issues to scan for potential problems before baking: - Degenerate brush (severity 2): near-zero thickness on any axis — blocks play. - Oversized brush (severity 1): very large dimensions — warning only. - Floating subtract (severity 1): a subtractive brush that doesn't intersect any additive brush. - Overlapping subtracts (severity 1): two subtractive brushes with intersecting AABBs. - Open edges (severity 1): edges shared by only one face — geometry is not watertight. - Non-manifold edges (severity 2): edges shared by 3+ faces — may cause bake artifacts. - Non-planar faces (severity 1): faces with 4+ vertices where a vertex drifts off the face plane beyond planarity_tolerance (default 0.01 units). Common in imported .map geometry with floating-point drift. - Occlusion missing (severity 1): occluder generation is enabled but no occluders were created (all surfaces below the minimum area threshold). - Occlusion coverage (severity 0, info): reports occluder count and estimated coverage as a percentage of baked AABB surface area. Appears when occluders exist. - Micro-gaps (severity 1): near-coincident but not-exactly-equal vertices across different brushes that would cause seam tearing after bake. Detected within weld_tolerance (default 0.001 units).

Auto-fix helpers (available via GDScript API on level_root.validation_system): - weld_brush_vertices(brush) — snaps near-coincident vertices to their average. Refreshes face normals and bounds automatically. - fix_non_planar_faces(brush) — projects drifting vertices back onto the face plane.

Both tolerances (weld_tolerance, planarity_tolerance) are configurable per-instance for noisy imported geometry.

Issues appear as color-coded toast notifications.

Non-Blocking Face Bakes

When Use Face Materials is enabled, full bakes yield back to the editor every 8 brushes so the UI stays responsive during large bakes. A progress label shows "Collecting faces N/M" as geometry is processed. The bake operates on a snapshot of brush state taken at the start, so editing brushes while a bake is running will not produce mixed results — changes are picked up on the next bake.

Bake Time Estimate

The Test tab shows an estimated bake time based on the last bake duration and current brush count. Frame-yield idle time during face bakes is excluded from the estimate so it reflects actual work, not editor frame pacing. If the level has more than 500 brushes, a "Chunking recommended" tip appears.

player_start properties (set in the Entity Properties panel): - primary (bool) -- preferred spawn when multiple exist. - angle (float, degrees) -- initial yaw rotation for the player. - height_offset (float) -- extra height above floor for safety.

Test tab → Spawn section: - Validate Spawn -- triggers a bake, then runs validation against real collision geometry and shows debug overlay (green/red capsule, floor ray, ceiling ray) for 10 seconds. - Create Default Spawn -- places a player_start at brush centroid if none exists. Fully undoable and redoable. - Preview Spawn Debug -- triggers a bake, then shows persistent overlay toggle (stays visible until unchecked).

Toast Notifications

Transient notifications appear in the dock for important events: - Save/load/export results (success or failure). - Bake completion or errors. - Operation errors with actionable hints (e.g. "Wall thickness 6 is too large — Use a thickness less than 5"). - Reference cleanup reports (e.g. "Removed 2 I/O connection(s) targeting deleted brush 'door1'"). - Autosave failures (also shown as a persistent red warning label). - Notifications auto-fade after 4-8 seconds depending on severity (INFO, WARNING, ERROR).

Context Hints

Each tab shows a contextual hint at the bottom guiding you through the workflow: - Build tab: start with Create Starter, then draw; selection reveals Hollow, Clip, and Extrude actions - Paint tab: "Draw some brushes first, then paint them here" - Objects tab: drag an object from the palette into the viewport - Test tab: use Test Level for the one-click path; check or bake separately only when needed

Object and Face Marquee Selection

In Select mode, click a visible surface or begin on empty viewport space and drag. Godot decides the click target, drag threshold, region hits, modifier meaning, transform/property-widget hits, and resulting EditorSelection; HammerForge does not approximate those private shapes with a circular dead zone. Brush gizmos register filled triangles from the real brush faces. Entity gizmos combine visible nested preview triangles with restrained local markers for any broken or line-only sibling, including top-level preview children, so one healthy component cannot hide an incomplete one. A truly geometry-less entity gets a one-unit marker at its origin; hidden previews and hidden parents leave no invisible target. Hold Shift for Godot's native additive/active-selection behavior. Ctrl/Cmd remain Godot-owned rather than acting as a HammerForge object toggle. Grouped HammerForge brushes are normalized as one unit after Godot finishes.

In Face Select mode, the saved object selection and its transform/resize gizmos are hidden, and HammerForge owns face click and marquee selection. Drag at least 6 pixels across one or more brushes. A candidate face must be on a canonical, visible brush and have its screen-projected center inside the rectangle; HammerForge then ray-picks that center and accepts the face only when the same brush/face is the frontmost visible hit. Hidden, back-facing, or occluded faces do not come along merely because their centers overlap the rectangle. Shift adds and Ctrl/Cmd toggles using the modifier state captured at LMB-down. Disable the mode to return to the prior object selection, leave Paint or choose an incompatible tool to close it cleanly, or select an object in the Scene tree to edit that object directly.

Resize Handles and Widget Protection

Selected non-custom brushes show six yellow face handles; custom face-defined shapes keep their truthful boundary outline without misleading box handles. A handle drag owns its full press/motion/release sequence, so it cannot also click an object, start a marquee, paint, or activate another tool. Godot's move/rotate/scale widget and native property gizmos receive the same protection and remain responsible for their own exact hit-testing.

Resize distances and grid snap are measured in world units. If a brush is below a rotated or non-uniformly scaled parent, the grabbed face follows the transformed local axis, the opposite face stays fixed in world space, and the local brush size is adjusted to produce the requested world extent. Sphere handles keep X/Y/Z equal. On cylinders, cones, and capsules, either X or Z handle changes the shared X/Z radius; Y changes height, but a capsule can never become shorter than its diameter. Odd-sided prisms and adjustable pyramids now fill their centered stored bounds, so their visible faces and handle planes agree. Other supported shapes keep independent axes. A collapsed or invalid transform axis is ignored instead of causing a jump. One completed resize creates one undo step; a click with no change, an explicit cancel, or a recovered lost release creates none. During lost-release recovery the original preview is restored and frozen; if Godot never sends its matching release callback, HammerForge releases the local input latch after the recovery turn and ignores a late callback, so the next handle gesture cannot remain blocked.

Picking Visibility and Depth

Click and hover picking ignores brushes, entities, and preview visuals hidden by a visgroup. Brush bounds are only a fast candidate check: the final hit uses the actual face triangles, so a ray through empty space inside a wedge, cone, pyramid, curved, or custom brush does not select or hide geometry behind it. Entity previews are picked from their visible geometry even when that geometry is stored as an internal editor child. When geometry overlaps in screen space, HammerForge compares brush and entity hits in the same world-space ray and chooses the genuinely nearest visible result, including when either object is scaled.

Surface placement uses the same exact brush-face fallback when editor draft brushes do not yet have physics bodies. Draw placement, entity/prefab drops, and other callers of the shared editor raycast land on the visible non-box surface rather than an AABB wall; when no geometry is hit, the forward ray falls back to the construction plane.

Selection Filters

Press Shift+F or click the Flt button on the context toolbar to open the Selection Filter popover. It provides bulk selection tools organized by category:

Category Filters Description
By Normal Walls, Floors, Ceilings Select faces by surface direction
By Material Same Material Select all faces matching the selected face's material
Select Similar Similar Faces, Similar Brushes Faces: match material + normal (15°). Brushes: match size (20% tolerance, orientation-agnostic)
By Visgroup (dynamic) One button per visgroup — select all members
By Type Detail, Structural func_detail vs worldspawn brushes

Select Similar

Press Shift+S to quickly select similar geometry without opening the filter popover: - When faces are selected: selects all faces in the level with matching material AND normal direction (within 15°). - When brushes are selected: selects all brushes with similar dimensions (within 20% tolerance, ignoring orientation/rotation).

Apply Last Texture

Press Shift+T to apply the last texture you sampled with the Texture Picker (T key) to the current selection. Works on both face and brush selections. This enables a fast pick-and-paint workflow: press T to sample a material from any face, then Shift+T to stamp it onto other faces or brushes.

Smart Contextual Toolbar

A floating mini-toolbar appears in the 3D viewport showing context-sensitive actions based on your current selection and tool state. It eliminates the need to switch dock tabs for common operations:

Each section uses small muted group labels (e.g. "Extrude", "Modify", "Select") to visually cluster related tools following Gestalt proximity principles.

  • Brushes selected → [Extrude] Ext▲/Ext▼ | [Modify] Hollow, Clip, Carve, Merge | Duplicate, Delete | [Select] All, ⌂, Similar, Filters | [Preview] Bake▷ toggle. Prefab buttons appear for instances. Shows "N brush(es) selected" count.
  • Faces selected → Material thumbnails (favorites strip) | [UV] Fit/Center/L/R/T/B | [Apply] All, Last | Select Similar. Shows "N faces on M brush(es)" count.
  • Entities selected → [Entity] I/O, Properties | Highlight toggle + I/O summary | Duplicate, Delete. Shows "N entities selected" count.
  • Draw mode (idle) → [Shape] Box/Cyl/Sph/Cone | Add/Subtract toggle. When pending cuts exist: Apply, Commit, Clear buttons + "N pending" badge.
  • Dragging → Live dimensions display | Axis Lock (X/Y/Z) | Cancel.
  • Vertex mode → [Mode] Vertex/Edge toggle | [Edit] Merge, Split, Convex | Exit.

If Godot's visible selection mixes HammerForge objects with ordinary Godot nodes, selection-dependent HammerForge sections are unavailable. Finish the edit on one domain at a time; this prevents a toolbar action from changing only the HammerForge subset.

An auto-mode hint bar appears during brush drawing, showing the current operation mode (e.g. "Drawing in Add mode — press Subtract to toggle") with a one-click toggle button.

Command Palette

Press Shift+? or F1 to open the command palette — a searchable list of all HammerForge actions with key bindings. Actions that cannot run in the current state are grayed out (e.g. Hollow is disabled when nothing is selected, paint tools are disabled outside paint mode). Type to filter, press Enter to execute the first matching action, Esc to close.

Selection-dependent managed actions are also grayed out for a mixed HammerForge/Godot selection. If selection changes between opening and invoking the palette, the final dispatcher repeats the same safety check.

Viewport Context Menu

Press Space to open a context-sensitive popup menu at the cursor position in the 3D viewport. The menu adapts to your current selection and tool state:

  • Brush selected → Extrude Up/Down, Hollow, Clip, Carve, Duplicate, Delete, grid snap presets, draw shapes
  • Face selected → UV operations (Fit, Center, Stretch, Tile, Left/Right/Top/Bottom justify), texture tools
  • Entity selected → I/O Connect, Properties, Duplicate, Delete
  • Draw mode (idle) → Shape selector, Add/Subtract toggle, grid snap presets
  • Vertex mode → Merge, Split, sub-mode toggle

Common footer (in every context): Select All, Deselect All, Grid Snap submenu (1/2/4/8/16/32/64), Quick Bake, Undo, Redo.

Highlight Connected appears as a check item — it reads the current state and toggles it.

The menu only activates when idle (no active drag, paint, or external tool operation). The keybinding is configurable via hf_keymap.gd.

With a mixed HammerForge/Godot selection, managed selection commands are unavailable. The final context-menu action handler also checks again before editing, so stale menu state cannot produce a partial change.

Radial Menu

Opt-in. This is one of the power-user overlays, off by default so the core loop stays quiet. Turn on Power-user overlays in the Console's Controls tab, or in the dock under Test -> Settings.

Press ` (backtick) to open an 8-sector pie menu centered on the cursor. Move the mouse to highlight a sector, then left-click to select:

Sector Action
Box Switch to Box shape
Cylinder Switch to Cylinder shape
Select Switch to Select tool
Paint Switch to Surface Paint
Vertex Enter Vertex Edit mode
Tex Pick Activate Texture Picker
Measure Activate Measure tool
Clip Activate Clip tool

Dead zone: Moving inside the inner ring (center area) deselects all sectors. Moving outside the outer ring also clears the selection — the cursor must be within the ring to select.

Dismiss: Press Escape, backtick, or right-click to close without selecting.

While the radial menu is open, it intercepts all viewport input. The keybinding is configurable via hf_keymap.gd.

Radial sectors that start a selection-dependent managed action, such as Clip or Vertex Edit, use the same mixed-selection guard as keyboard and contextual UI. General tool switches remain available when they do not mutate the selected subset.

Quick Property Popups

Double-tap a key to open a small inline editor for a numeric property:

Keys Property Controls
G G Grid Snap 1 SpinBox (snap size)
B B Brush Size 3 SpinBoxes (X, Y, Z dimensions)
R R Paint Radius 1 SpinBox (radius)

The popup appears at the cursor position. Type a value and press Enter to apply, or Escape to cancel. Clicking outside the popup dismisses it (the click is consumed and does not pass through to the scene).

Viewport Contextual Hints

When you switch tools, a brief instruction hint appears in the viewport overlay: - Draw: "Click to place corner → drag to set size → release for height" - Select: "Click to select; drag empty space for a box; drag widgets to edit" - Extrude Up/Down: "Click a face to start extruding upward/downward" - Paint Floor: "Click cells to paint, Shift+click to erase" - Paint Surface: "Click brush faces to apply material"

Hints auto-fade after 4 seconds. Once you dismiss a hint (by switching away), it won't appear again. Hint dismissal persists across sessions. To reset all hints, delete user://hammerforge_prefs.json or clear the hints_dismissed key.

Brush Visual Coding

HammerForge keeps operation types recognizable without covering ordinary geometry in triangle topology:

Operation Default Appearance
Additive (Union) Clean green-tinted surface; no always-on wireframe
Subtractive Red tint with one red semantic wireframe
func_detail entity Bright blue tint
trigger_* entity Medium blue tint
func_wall entity Muted blue tint
Other brush entity Slate blue tint

Hovering or selecting a brush adds one concise semantic outline. A box shows its 12 actual boundary edges, and wedges, pyramids, prisms, and polyhedra keep only true boundaries and creases—not diagonals introduced when faces are triangulated. Cylinder, cone, sphere, ellipsoid, capsule, and torus shapes use sparse profiles that communicate their silhouette without reproducing every render triangle or falling back to a box. Hover and the selected gizmo share this source, and a selected brush does not receive a second overlapping hover outline. Polygon, path, merged, and imported custom brushes follow their real face boundaries and do not show misleading box-resize handles. Full triangle topology remains available deliberately through Test → Advanced Bake → Preview Mode → Wireframe and the dedicated geometry-editing modes.

Rapid drawing or resizing should never leave nested outlines or a visual trail. HammerForge reuses its transient semantic overlays and cleans legacy duplicates automatically when affected brushes are rebuilt.

Grid Size Indicator

The viewport HUD shows the current grid snap value (e.g. "Grid: 16") persistently in the top-right panel. When the grid size changes — via the dock SpinBox, quick-property popup (G G), or the [ / ] hotkeys — the indicator briefly flashes bright yellow-white and fades back, providing instant feedback without leaving the viewport.

Grid size hotkeys: - [ — halve grid snap (e.g. 16 → 8), minimum 0.125 - ] — double grid snap (e.g. 16 → 32), maximum 512

Subtract Preview

Enable Subtract Preview in Test tab → Settings to see the live CSG cut between overlapping additive and subtractive DraftBrushes. A translucent red mesh shows the volume that will be removed; a wireframe AABB is used only while CSG is catching up or when too many subtractors are active. The preview updates when brushes are added, removed, or moved (0.15s debounce). It does not CSG the entire level.

Status bar

  • Shows current status ("Ready", "Baking...", errors in red, warnings in yellow).
  • Errors auto-clear after 5 seconds, success messages after 3 seconds.
  • Displays selection count ("Sel: N brushes" or "Sel: 3 brushes, 5 faces") when brushes/faces are selected, with a clear (x) button to deselect.
  • Live brush count with color-coded performance warnings.
  • Bake progress bar updates during chunked bakes.
  • Performance panel shows active brushes, paint memory, bake chunks, and last bake time.
  • Autosave warning: a red "Autosave failed!" label appears if a threaded save fails. Auto-hides after 30 seconds.

Snap Modes

HammerForge supports five snap modes that can be combined:

Mode Button Behavior
Grid G Snap to grid increments (default, always-on)
Vertex V Snap to the 8 transformed AABB corners of existing brushes
Center C Snap to the center point of existing brushes
Edge E Snap to the midpoint of an existing brush AABB edge
Perpendicular P Snap to the closest perpendicular projection on a brush AABB edge

Toggle modes independently using the G/V/C/E/P buttons below the Grid Snap row in the Build tab. When multiple modes are enabled, the closest candidate wins — a nearby brush corner will beat a farther grid point. The snap threshold (default 2.0 world units) determines how close you need to be to a geometry candidate for it to take effect.

Tip: Use Vertex for corner alignment, Center for centered placement, Edge for exact midpoints, and Perpendicular for a right-angle projection onto an edge.

Undo/Redo

  • All brush operations (draw, delete, nudge, resize, paint, hollow, clip) support undo/redo.
  • Command collation: rapid repeated operations (nudging with arrow keys, resizing via gizmo, painting brushes) are merged into a single undo entry within a 1-second window. One undo press reverses the entire sequence.
  • Multi-step operations (hollow, clip) use transactions for atomicity.

Entity Definitions

Brush entity classes (func_detail, func_wall, trigger_once, trigger_multiple) and point entities are data-driven. Definitions are loaded from entities.json (if present) or fall back to built-in defaults.

To add custom entity types: 1. Create res://addons/hammerforge/entities.json. 2. Add entries with classname, description, is_brush_entity, and optional color and properties. 3. The dock entity palette and brush entity class dropdown will auto-populate from these definitions.

Material Library

The material palette can be saved and loaded as a JSON library file: - Save: preserves resource paths of all palette materials. - Load: restores the palette from saved paths. - Usage tracking: materials in use by brushes are tracked; find_unused_materials() identifies cleanup candidates.

Prototype Textures

HammerForge includes 150 built-in SVG prototype textures organized as 15 patterns in 10 color variations. Click Refresh Prototypes in the Paint tab → Materials section to add them all to the palette. The Material Browser displays them as a visual thumbnail grid with search and pattern/color filters — no need to memorize names. Patterns include solid, brick, checker, cross, diamond, dots, hex, stripes (diagonal/horizontal), triangles, zigzag, and directional arrows (up/down/left/right).

For GDScript API usage, see docs/HammerForge_Prototype_Textures.md.

Pending Cuts Workflow

Subtractive brushes are staged as Pending Cuts until explicitly applied. This gives you a chance to preview, adjust, and batch your subtract operations before committing.

Applying cuts (three methods, all equivalent): 1. Context toolbar (recommended): When in Draw mode with pending cuts, the toolbar shows Apply / Commit / Clear buttons with a count badge. This is the fastest path — no tab switching needed. 2. Test tab → Actions: The Apply Cuts, Clear Pending Cuts, and Commit Cuts (Bake) buttons are always available. 3. Viewport context menu: Space → Apply Cuts (when in subtract context).

Button Action
Apply Move pending cuts to draft brushes (keeps them, doesn't bake)
Commit Apply + Bake as one undoable transaction
Clear Discard all pending cuts without applying

All cut buttons are disabled during active bakes to prevent race conditions. Commit does not consume a cut until its bake succeeds, and Undo/Redo restores both the editable brushes and the exact baked output, including its Full/Wireframe/Proxy preview mode.

Design Constraints (Summary)

  • DraftBrush previews are lightweight. Final geometry comes from bake.
  • Subtractive brushes are staged as Pending Cuts until applied.
  • Floor paint is grid-based; heightmaps displace floors only.
  • .map export/import is for blockouts and does not preserve per-face materials.

For details, see docs/HammerForge_Design_Constraints.md.

Data Portability

  • .hflevel is the source of truth for full-fidelity editing.
  • .map exchange is limited to basic brushes and point entities.
  • .glb export includes baked geometry only.

For full details, see docs/HammerForge_Data_Portability.md.

Install + Upgrade

For install steps, upgrade guidance, and cache reset help, see docs/HammerForge_Install_Upgrade.md.

Shortcut HUD

A single-row strip in the 3D viewport toolbar, next to the Console lamp. It updates with your current tool and mode, and shows the primary line for that context plus the grid size indicator; the full list for the context is on its tooltip. When a contextual hint is active it takes the row for the four seconds of its fade, because the toolbar is one row high.

Toggle it with Show HUD — in the Console's Controls tab, or in the dock under Test → Settings.

The contexts and what their full lists cover:

Context Shortcuts Shown
Draw (idle) Click+Drag, Shift/Alt modifiers, X/Y/Z axis lock, Ctrl+Scroll size, Ctrl+D, Delete
Draw (dragging base) Shift: Square, Alt+Shift: Cube, Click: Height stage, Right-click: Cancel. Live dimensions shown in banner
Draw (adjusting height) Mouse: Change height, Click: Confirm, Right-click: Cancel. Live dimensions shown in banner
Select Native click/Shift object selection; Face Select Shift-add/Ctrl-toggle; Escape, Delete, Ctrl+D, Arrow nudge, Ctrl+H Hollow, Shift+X Clip, Ctrl+Shift+F/C Floor/Ceiling
Extrude Up/Down (idle) Click face + drag, U/J tool switch, Right-click cancel
Extrude Up/Down (active) Move mouse to set height, Release to confirm, Right-click cancel
Floor Paint Click+Drag, B/E/R/L/K tool shortcuts
Surface Paint Click+Drag, radius/strength info
Vertex Edit Click vertex to select, drag to move, E: edge mode, Ctrl+W: merge, Ctrl+E: split
Polygon Tool Click to place verts, Enter: close, Escape: remove last
Path Tool Click to place waypoints, Enter: finalize, Escape: remove last

The HUD also shows current axis lock state (e.g. "[X Locked]"), and a Grid: N indicator that flashes when the snap changes. Fractional snaps display exactly (Grid: 0.125).

The full list is also available two other ways: the searchable shortcut dialog (? button in the dock toolbar) and the command palette (Ctrl+K).

Customizable Keyboard Shortcuts

All keyboard shortcuts are data-driven and can be customized. The default bindings match the shortcuts shown throughout this guide.

Default bindings:

Action Default Key Description
Draw tool D Switch to Draw mode
Select tool S Switch to Select mode
Extrude Up E / U Switch to Extrude Up mode (E skipped in paint/vertex modes)
Extrude Down Shift+E / J Switch to Extrude Down mode (Shift+E skipped in paint/vertex modes)
Delete Delete Delete selected brushes and DraftEntities
Duplicate Ctrl+D Duplicate selected brushes and DraftEntities
Group Ctrl+G Group selected brushes
Ungroup Ctrl+U Ungroup selection
Hollow Ctrl+H Convert brush to hollow room
Clip Shift+X Split brush along axis plane
Carve Ctrl+Shift+R Boolean-subtract from intersecting brushes
Move to Floor Ctrl+Shift+F Snap to nearest surface below
Move to Ceiling Ctrl+Shift+C Snap to nearest surface above
Measure M Multi-ruler tool (persistent rulers, angles, snap ref)
Decal N Place decal on surface with live preview
Polygon P Draw convex polygon, extrude to brush
Path ; Place waypoints, extrude corridor brushes
Edge sub-mode E Toggle vertex/edge sub-mode (in vertex mode)
Split edge Ctrl+E Insert midpoint on selected edge
Merge vertices Ctrl+W Merge selected vertices to centroid
Texture Picker T Eyedropper — sample face material
Apply Last Texture Shift+T Apply last picked texture to selection
Select All A Select all brushes and entities (clears face selection)
Deselect All Shift+A Deselect everything (brushes, entities, faces)
Select Similar Shift+S Select faces/brushes similar to current selection
Selection Filters Shift+F Open selection filter popover
Grid Size Down [ Halve grid snap (min 0.125)
Grid Size Up ] Double grid snap (max 512)
Axis Lock X/Y/Z X / Y / Z Constrain to axis
Paint tools B / E / R / L / K Bucket / Erase / Ramp / Line / Blend
Command palette Shift+? / F1 / Ctrl+K Searchable action palette with fuzzy search
Operation timeline Ctrl+Shift+T Toggle operation replay timeline

Rebinding: Edit user://hammerforge_keymap.json (created on first run). Each entry maps an action name to {"keycode": KEY_*, "ctrl": bool, "shift": bool, "alt": bool}. Restart the plugin after editing.

Toolbar labels and tooltips update automatically from the keymap, so custom bindings are always reflected in the UI. Press the ? button on the toolbar to open a searchable shortcut dialog showing all current keybindings grouped by category (Tools, Editing, Selection, Paint, Axis Lock).

User Preferences

HammerForge stores cross-session preferences in user://hammerforge_prefs.json, separate from per-level settings.

Preferences include: - Default grid snap size - Autosave interval - Recent file list (up to 10) - Collapsed section states (which dock sections are expanded/collapsed) - Last active tool - HUD visibility - Tutorial wizard visibility and progress step - Dismissed viewport contextual hints

Prefabs (Reusable Brush Groups)

Prefabs let you save a selection of brushes and entities as a reusable group and place copies anywhere in your level. The system supports variants, tags, live-linked instances, and visual debug overlays.

Saving a Prefab

  1. Select the brushes and/or entities you want to save.
  2. Open Test tab → Prefabs section.
  3. Enter a name and click Save (or Save Linked to enable live propagation).
  4. The prefab is saved as a .hfprefab JSON file in res://prefabs/.

Quick Save: Press Ctrl+Shift+P or click Pfb in the context toolbar to instantly save the current selection as a prefab with an auto-generated name. Also available via the context toolbar in both brush and entity selected contexts.

Instantiating a Prefab

  • Drag a prefab from the library list into the 3D viewport.
  • The brushes and entities are placed at the drop position with new unique IDs.
  • Entity I/O connections are automatically remapped to the new entity names.
  • Each placed instance is tracked in the prefab system for variant cycling and propagation.
  • Instance tracking covers brushes in DraftBrushes, PendingCuts, and CommittedCuts, plus point and tied brush entities. Source updates and removal warn when a recorded member is missing instead of silently leaving a partial instance.
  • The operation supports undo/redo.

Prefab Variants

Prefabs can contain multiple variants (e.g., different door styles: wooden, metal, ornate).

  • Adding a variant: Right-click a prefab in the library → Add Variant. Select the replacement geometry and name the variant.
  • Cycling variants: Select a placed prefab instance and press Ctrl+Shift+V or click Var▶ in the context toolbar. This cycles through all available variants in place.
  • Variant indicator: The library list shows [N variants] next to prefabs that have multiple variants.

Live-Linked Prefabs

When you save a prefab with Save Linked, all placed instances of that prefab maintain a link to the source file.

  • Push to source: Edit a placed instance, then click Push in the context toolbar to update the .hfprefab source file with the current state.
  • Propagate to all: Click Pull on any linked instance to propagate the current source file to all linked instances in the level.
  • Per-instance overrides (size, transform changes) are tracked and reapplied after propagation.
  • The context toolbar shows a [linked] badge on linked prefab instances.
  • Adding tags: Right-click a prefab in the library → Edit Tags. Enter comma-separated tags (e.g., door, architecture, interior).
  • Searching: Use the search bar at the top of the prefab library. Searches match both prefab names and tags.
  • Tag filtering: Use the Tag dropdown to filter the list to prefabs with a specific tag.

Visual Debug Overlay

When hovering over a node that belongs to a prefab instance in the 3D viewport, a cyan wireframe bounding box appears around the entire instance. If the instance has overrides relative to the source, orange sphere markers appear on modified nodes.

What's Captured

  • Brush geometry (shape, size, operation, material, transform relative to group centroid)
  • Entity data (type, class, properties, I/O connections, transform relative to centroid). Each entity receives a stable unique ID on instantiation — entity membership is tracked by UID, not scene name, so renaming nodes or having duplicate names will not break prefab tracking.
  • Brush IDs and group IDs are cleared on capture; new ones are assigned on instantiation.
  • Tags (metadata for search/filtering)
  • Variants (alternate brush/entity configurations stored alongside the base)

File Format

.hfprefab files are JSON with the same encoding as .hflevel (Vector3, Transform3D serialized via HFLevelIO). They support optional tags (string array) and variants (named alternate configurations) fields. They are portable and can be shared between projects.

These persist across editor restarts. Per-level settings (cordon, texture lock, materials) remain in .hflevel files.

Tool Availability (Poll System)

Some actions require specific conditions to run: - Hollow, Clip, Move to Floor/Ceiling require at least one brush selected. When nothing is selected, these buttons are grayed out with an inline hint ("Select a brush to use these tools") visible in the Selection Tools section. - Face-dependent controls (Assign to Selected Faces, UV editing) show "Enable Face Select Mode and click a face to edit" when no face is selected. - Extrude requires a LevelRoot in the scene. In extrude mode, a semi-transparent face highlight (green for up, red for down) previews which face you'll select before clicking. - External tools can define their own requirements via can_activate().

HammerForge managed edits are scoped to the visible selection. With only native Godot nodes selected, a keyboard shortcut passes through to Godot. With only HammerForge brushes/entities selected, HammerForge owns it. If the selection mixes both domains, HammerForge stops managed operations such as duplicate, delete, group, hollow, nudge, clip, carve, merge, texture, prefab, and variant actions and shows “Edit HammerForge and Godot nodes separately”. The same rule is enforced by the context toolbar, viewport context menu, hotkey palette, and selection-dependent radial actions; their managed commands are hidden or disabled where possible and checked again when invoked. Deselect one domain before retrying. This prevents generic editor commands or stale UI state from bypassing HammerForge IDs, caches, or undo state.

Only one HammerForge editing tool owns mouse input at a time. Activating an external tool such as Polygon, Path, Measure, or Decal cancels an unfinished built-in gesture, exits conflicting vertex/paint state, and gives that tool exclusive HammerForge pointer handling until it is completed, cancelled, or another tool is chosen. A missed surface does not leak the same click into Draw, Select, Paint, or Vertex mode. Native viewport navigation still works whenever the active tool deliberately passes the event through.

The mode indicator banner always shows the current tool and gesture stage. The status bar shows selection count with a clear button.

Brush Creation (CAD style)

1) Base drag: click and drag to define the base. 2) Height stage: release mouse, move up/down, click to commit.

Modifier keys - Shift: square base. - Shift + Alt: cube. - Alt: height-only. - X/Y/Z: axis locks (shown in HUD as "[X Locked]" etc.). - Right-click: cancel.

General keyboard shortcuts - Delete: remove selected brushes and DraftEntities. - Ctrl+D: duplicate selected brushes and DraftEntities. - Arrow keys: nudge selected brushes and DraftEntities (XZ plane). - PageUp/PageDown: nudge selected brushes and DraftEntities (Y axis). - Escape: clear selection. - Ctrl+Scroll: adjust brush size. - [ / ]: halve / double grid snap size.

Extrude shortcuts - U: Extrude Up tool. - J: Extrude Down tool.

Group shortcuts - Ctrl+G: Group selected brushes/entities. - Ctrl+U: Ungroup selected brushes/entities.

Paint tool shortcuts (active when Paint Mode is enabled) - B: Brush tool. - E: Erase tool. - R: Rectangle tool. - L: Line tool. - K: Bucket fill tool.

Vertex Editing

Vertex mode lets you select and move individual brush vertices for precision geometry editing.

Entering Vertex Mode

Press V (keyboard shortcut or the V toggle button in the toolbar) to enter vertex mode. Selected brushes show their vertices as crosses and edges as wireframe lines.

Vertex Sub-Mode

  • Vertex mode (default): click vertices to select them, drag to move.
  • Edge mode (press E to toggle): click edges to select them. Selected edges highlight orange; hovered edges highlight yellow.

Dragging Vertices and Edges

An unlocked drag follows a view-facing plane through the vertex or edge midpoint you grabbed. This makes the point track the cursor predictably in perspective and in front, side, and top orthographic views instead of forcing every drag onto world Y. Grid snap is applied to the resulting world-space movement.

Use X, Y, or Z to constrain the drag to that world axis. HammerForge chooses a camera-facing projection plane that contains the locked axis. If the camera is looking exactly along that axis and the cursor cannot express a stable movement, the update is ignored rather than making the geometry jump. Losing LMB during a focus change cancels the unfinished drag and restores its captured geometry.

Edge Operations

  • Split edge (Ctrl+E): select exactly one edge, then press Ctrl+E to insert a midpoint vertex. The two faces sharing the edge each gain the new vertex. Convexity is mathematically guaranteed.
  • Merge vertices (Ctrl+W): select 2+ vertices, then press Ctrl+W to merge them to their centroid. Merging is rejected if it would break convexity.

Convexity Enforcement

All vertex operations validate that the brush remains convex. If a move or merge would create a concave shape, the operation is rejected and the brush reverts to its previous state.

Clip to Convex

If a brush has been deformed into a non-convex shape (e.g., by external editing or import), use the Convex button in the vertex edit context toolbar to recompute its convex hull. This: 1. Computes the convex hull of all brush vertices. 2. Rebuilds faces from the hull planes. 3. Inherits UV settings (projection, scale, offset, rotation, material) from the closest original face for each new hull face.

This is a fallback repair tool, not a modeling operation — it discards any concave geometry.

Shortcuts

Key Action
V Enter vertex mode
E Toggle vertex/edge sub-mode
Ctrl+E Split selected edge
Ctrl+W Merge selected vertices

Polygon Tool

The polygon tool lets you draw arbitrary convex shapes and extrude them into brushes.

Workflow

  1. Press P to activate the Polygon tool.
  2. Click in the viewport to place the first vertex on the nearest exact visible surface. If no geometry is hit, placement uses the forward construction plane. The point passes through the shared Grid, Vertex, Center, Edge, Perpendicular, and reference-line snap pipeline.
  3. Place more vertices. Each cursor ray starts on the horizontal plane established by the first point, then passes through the shared snap pipeline.
  4. Each new vertex is validated for convexity -- concave placements are rejected.
  5. Close the polygon by clicking near the first vertex (within the auto-close threshold) or pressing Enter (requires 3+ vertices).
  6. Move the mouse up/down to set the extrusion height, then click to confirm.
  7. The brush is created with full undo/redo support.

Preview

During placement, a cyan outline shows the polygon shape. During height extrusion, green vertical edges and the top face outline appear.

Settings

Setting Default Description
auto_close_threshold 1.5 Distance to first vertex that triggers auto-close

Shortcuts

Key Action
P Activate Polygon tool
Left-click Place vertex / confirm height
Enter Close polygon (3+ verts) / confirm height
Escape / Right-click Remove last vertex / cancel

Path Tool

The path tool creates corridors by placing waypoints and extruding a rectangular cross-section along the path.

Workflow

  1. Press ; (semicolon) to activate the Path tool.
  2. Click in the viewport to place the first waypoint on the nearest exact visible surface. If no geometry is hit, placement uses the forward construction plane. The point passes through the shared Grid, Vertex, Center, Edge, Perpendicular, and reference-line snap pipeline.
  3. Place more waypoints. Each cursor ray starts on the horizontal plane established by the first point, then passes through the shared snap pipeline.
  4. Press Enter to finalize the path (requires 2+ waypoints).
  5. For each segment, an oriented-box brush is created. At interior corners, a miter joint brush fills the gap.
  6. All brushes are auto-grouped and created in a single undo action.

Preview

During placement, a cyan polyline shows the path with parallel offset lines indicating width and perpendicular ticks at waypoints.

Settings

Setting Default Description
path_width 4.0 Width of the corridor cross-section
path_height 4.0 Height of the corridor cross-section
miter_joints true Fill gaps at path corners with wedge brushes
path_extra None Auto-generate extras: None, Stairs, Railing, or Trim
stair_step_height 0.25 Step height for auto-stairs (only when path_extra = Stairs)
railing_height 1.0 Railing height above path surface
railing_thickness 0.1 Thickness of railing rails and posts
railing_post_spacing 2.0 Distance between railing posts
trim_width 0.2 Width of edge trim strips
trim_height 0.1 Height of edge trim strips
trim_material_idx -1 Material index for trim faces (-1 = default material)

Auto-Generated Extras

When path_extra is set to a value other than None, additional geometry is auto-generated after the base path segments:

  • Stairs: Step brushes along sloped path segments. Step count is derived from height difference / step height. Flat segments are skipped.
  • Railings: Top rail + posts on both sides of the path. Posts are spaced evenly along each segment. Both rails and posts share the group ID with path segments.
  • Trim: Edge strips run alongside both sides of the path. If trim_material_idx >= 0, all faces of trim brushes are assigned that material index.

Preview lines during placement: green ticks for stairs, yellow for railings, orange for trim.

Shortcuts

Key Action
; Activate Path tool
Left-click Place waypoint
Enter Finalize path (2+ waypoints)
Escape / Right-click Remove last waypoint / cancel

Visgroups (Visibility Groups)

Visgroups let you organize your map into logical groups and toggle their visibility.

  1. Open the Test tab in the dock.
  2. Type a name in the Visgroup field and click New to create a visgroup.
  3. Select brushes/entities in the viewport, then click Add Sel to add them to the visgroup.
  4. Click the visgroup name in the list to toggle between [V] (visible) and [H] (hidden).

Notes: - A node can belong to multiple visgroups. If ANY visgroup it belongs to is hidden, the node is hidden. - Nodes not in any visgroup are always visible. - Use Rem Sel to remove selected nodes from the visgroup, or Delete to remove the visgroup entirely. - Visgroups persist in .hflevel saves and undo/redo state.

Grouping

Groups let you persistently link brushes/entities so they select and move together.

  1. Select the brushes/entities you want to group.
  2. Press Ctrl+G (or click Group Sel in the Test tab → Visgroups & Groups section).
  3. Click any member of the group -- all members are selected automatically.
  4. Press Ctrl+U (or click Ungroup) to dissolve the group.

Notes: - Each node can belong to one group at a time. - Groups persist in .hflevel saves and undo/redo state.

Per-Face UV Controls

The Paint tab includes a UV Editor section for fine-tuning per-face UV settings:

Projection Mode

Select a UV projection mode from the dropdown: - Planar X/Y/Z: projects UVs along the specified axis. - Box UV: automatically picks the best axis per face (default for most workflows). - Cylindrical: wraps UVs around a cylinder (best for round shapes).

Click Re-project UVs to recompute UVs using the selected projection mode (resets scale/offset/rotation).

UV Transform

When a face is selected, adjust its UV parameters with the spinboxes: - Scale X/Y: texture repeat scale (default 1.0). - Offset X/Y: texture offset in UV space. - Rotation: texture rotation in degrees.

Changes are live-previewed and fully undoable. Rapid spinbox changes merge into a single undo step.

Material Browser Integration

Right-click a material thumbnail in the Material Browser and choose Apply + Re-project (Box UV) to assign the material and reset UV projection in one step.

Texture Lock

When Texture Lock is enabled, moving or resizing a brush automatically adjusts its face UVs so textures stay aligned.

  1. Check Texture Lock in the Build tab (enabled by default).
  2. Move or resize brushes normally -- UV alignment is preserved.
  3. Uncheck to disable (UVs will shift with transforms as before).

Notes: - Works with PLANAR_X, PLANAR_Y, PLANAR_Z, and BOX_UV projections. - CYLINDRICAL projection is not compensated (complex; future enhancement). - Applies to HammerForge move, nudge, floor/ceiling, and resize actions. Godot's native Node3D transform widget leaves the brush's face UV resources unchanged so native undo/redo remains truthful. - Persists in .hflevel settings.

Cordon (Partial Bake)

The cordon restricts bake output to an AABB region, useful for iterating on a specific area of a large map.

  1. Open the Test tab in the dock.
  2. Check Enable Cordon to activate.
  3. Set the min/max coordinates with the spinboxes, or select brushes and click Set from Selection.
  4. A yellow wireframe shows the cordon bounds in the viewport.
  5. Bake -- only brushes intersecting the cordon AABB are included.

Notes: - Disable cordon to bake the entire map. - Cordon settings persist in .hflevel saves.

Extrude (Up / Down)

The Extrude tools let you extend an existing brush by clicking one of its faces and dragging to create a new brush.

  1. Press U (Extrude Up) or J (Extrude Down), or click the toolbar buttons.
  2. Move the mouse over brush faces -- a semi-transparent hover highlight shows which face you'll select (green for up, red for down).
  3. Click on a brush face -- a semi-transparent preview appears.
  4. Drag the mouse vertically to set the extrude height (grid-snapped). The mode indicator shows "Extruding..." with numeric input if you type.
  5. Release the mouse to commit the new brush.

Notes - Extrude Up shows a green preview; Extrude Down shows a red preview. - The new brush inherits the source brush's material. - The extruded brush is a standard DraftBrush (box) and works with Bake, materials, and undo/redo. - Right-click cancels the extrude in progress.

Floor Paint

  1. Enable Paint Mode.
  2. Open the Paint tab → Floor Paint section.
  3. Choose tool, brush shape (Square or Circle), radius, and layer.
  4. Paint in the viewport.

Notes - Brush Shape: Square fills a full box of cells; Circle clips corners using Euclidean distance. - Live preview updates while dragging. - Bucket fills a contiguous region (click filled to erase). - Generated geometry appears under LevelRoot/Generated. - Generated flat floors/walls are DraftBrush nodes and are included in Bake.

Region Streaming (Large Worlds)

Region streaming keeps large paint grids responsive by loading only nearby regions. 1. Enable Streaming in the Paint tab → Regions section. 2. Set Region Size (cells) and Stream Radius (regions). 3. Toggle Show Region Grid to visualize loaded regions. 4. Paint normally; regions auto-load around the cursor.

Notes - Region data is saved to .hfr files in <level>.hfregions/. - The .hflevel stores a region index and layer settings.

Heightmap Terrain

Heightmaps add vertical displacement to painted floors: 1. Paint cells on a layer using Brush/Rect/Line/Bucket. 2. Click Import to load a PNG/EXR heightmap, or Generate for procedural noise. 3. Adjust Height Scale to control displacement amplitude. 4. Adjust Layer Y to set the base height of the layer.

When a layer has a heightmap, its floors are generated as displaced MeshInstance3D nodes (not DraftBrush). These live under Generated/HeightmapFloors and are baked directly (bypassing CSG) with trimesh collision shapes.

Material Blending

The Blend tool paints per-cell material blend weights on filled cells: 1. Fill cells first (Brush/Rect/etc.). 2. Switch to the Blend tool. 3. Choose a Blend Slot (B/C/D). 4. Adjust Blend Strength (0.0-1.0) in the dock. 5. Paint over filled cells to set blend weights.

Blend weights drive a four-slot shader (hf_blend.gdshader). Slot A is the implicit base, while slots B/C/D are controlled by the blend map (RGB) sampled on the UV2 channel.

Terrain slots: - Use Slot A-D texture pickers to assign textures for the terrain blend shader. - Slot Scale controls per-slot UV tiling.

Face Materials and UVs

  1. Open the Paint tab → Materials section.
  2. Click Refresh Prototypes to load all 150 built-in textures, or click Add to load a custom material resource (example: materials/test_mat.tres).
  3. Browse the visual thumbnail grid — use search, pattern dropdown, or color swatches to filter.
  4. Click a thumbnail to select a material. Hover to preview it on selected faces.
  5. Enable Face Select Mode.
  6. Use the Select tool and click faces in the viewport.
  7. Click Assign to Selected Faces, or right-click the thumbnail → "Apply to Selected Faces".
  8. Press T to use the Texture Picker — click any face to sample its material.

UV editing: - Open the Paint tab → UV Editor section after selecting a face. - Drag UV points to edit. - Use Reset Projected UVs to regenerate UVs from projection.

Notes: - Face data is stored per DraftBrush face. - Materials and UVs persist in .hflevel saves.

Surface Paint (3D)

  1. Enable Paint Mode.
  2. Open the Paint tab → Surface Paint section and set Paint Target = Surface (if needed).
  3. Pick a layer and assign a texture.
  4. Paint in the viewport.

Notes: - Radius is in UV space (0.0 to 1.0). - Surface paint updates the DraftBrush preview immediately. - Surface paint is separate from floor paint layers. - If paint affects the floor, set Paint Target = Surface in the Surface Paint section.

Displacement Surfaces

Displacement surfaces turn a flat quad face into a subdivided terrain grid that you can sculpt interactively, similar to Source Engine displacements.

Creating a Displacement

  1. Select a brush and enter Face Select Mode.
  2. Click a quad face (exactly 4 vertices).
  3. Open the Brush tab → Displacement section.
  4. Set Power (2 = 5x5, 3 = 9x9, 4 = 17x17 vertices).
  5. Click Create. The face becomes a subdivided grid.

Painting (Sculpting)

  1. Enable Paint Mode in the dock and ensure the Displacement section is expanded.
  2. Select a displaced face.
  3. Choose a Paint Mode: Raise, Lower, Smooth, Noise, or Alpha.
  4. Set Radius and Strength.
  5. Click and drag on the face in the viewport to sculpt.

Paint uses a circular brush with quadratic falloff. Strokes are continuous — the entire stroke commits as a single undo action when you release the mouse button.

Settings

  • Elevation: global height scale multiplier for the displacement grid.
  • Power: subdivision level (changing power resamples existing data via bilinear interpolation).
  • Sew Group: integer group ID. Click Sew to snap shared boundary vertices between adjacent displacements in the same sew group.

Destroying a Displacement

Click Destroy to revert a displaced face back to a flat quad.

Notes: - Displacement requires a quad face (4 vertices). Triangles and N-gons are not supported. - Displacement data is serialized in .hflevel saves. - The baker generates per-vertex normals for displaced faces (smooth shading).

Bevel and Face Inset

Edge Bevel (Chamfer)

Replace a sharp edge with a rounded profile: 1. Enter Vertex mode (V key) and switch to Edge sub-mode (E key). 2. Select one or more edges. 3. Open the Brush tab → Bevel section. 4. Set Segments (1-16) and Radius (distance the bevel cuts into the brush). 5. Click Bevel Edge.

The selected edges are replaced with bevel strip faces. Higher segment counts produce smoother curves.

Face Inset

Shrink a face inward and create connecting side faces: 1. Select a face in Face Select Mode. 2. Open the Brush tab → Bevel section. 3. Set Inset (distance to shrink inward) and optional Height (extrude along normal). 4. Click Inset Face.

Notes: - Inset distance cannot exceed the face's corner-to-centroid distance (the operation is rejected with a toast if too large). - Both bevel and inset operations are fully undoable.

Entities (early)

  • Place nodes under LevelRoot/Entities or set meta is_entity = true.
  • Entities are selectable and excluded from bake.
  • Entity palette supports drag-and-drop placement.

Entity definitions live in res://addons/hammerforge/entities.json. Example (billboard preview):

{
  "light_point": {
    "class": "OmniLight3D",
    "preview": {
      "type": "billboard",
      "path": "res://addons/hammerforge/icon.png",
      "color": "#ffff00"
    },
    "properties": [
      {"name": "range", "type": "float", "default": 10.0},
      {"name": "energy", "type": "float", "default": 1.0},
      {"name": "color", "type": "color", "default": "#ffffff"}
    ]
  }
}

Bake Output

Bake creates BakedGeometry: - If chunked baking is enabled, it adds BakedChunk_x_y_z nodes. - Collision shape type depends on Collision Mode (Inspector property on LevelRoot): - Mode 0 (default): Each chunk has a MeshInstance3D and StaticBody3D with a single ConcavePolygonShape3D (trimesh). - Mode 1: Each chunk has a StaticBody3D containing one ConvexPolygonShape3D per brush (convex hulls). Better for physics broadphase and navmesh generation. - Mode 2: Each visgroup gets its own StaticBody3D with convex hulls for all its member brushes. Ungrouped brushes share a default body. Best for room-based physics partitioning and bot navigation.

Generated flat floor paint brushes are included in the CSG bake. Heightmap floor meshes are duplicated directly into the baked output with trimesh collision shapes (they bypass CSG since they are already ArrayMesh). Heightmap collision is appended after visgroup partitioning (mode 2), so heightmap shapes are always preserved.

Use Face Materials (optional): - Enables the faster per-face material path when the level has no effective structural cuts. - Pending, applied, or frozen subtract brushes automatically use the CSG-safe path instead, preserving the cut in both rendered geometry and collision. - Bakes cooperatively (yields every 8 brushes) so the editor stays responsive on large levels.

Save/Load (.hflevel)

  • Save .hflevel stores brushes, entities, settings, materials palette, face data, and paint layers.
  • Paint layer data includes per-chunk material_ids, blend_weights (+ _2/_3), optional heightmap_b64, height_scale, and terrain slot settings.
  • Load .hflevel restores them. Missing heightmap/material fields default to zero (backward-compatible).
  • Autosave can write to a configurable path.

Capturing Exit-Time Errors

PowerShell command:

Start-Process -FilePath "C:\Godot\Godot_v4.7-stable_win64.exe" `
  -ArgumentList '--editor','--path','C:\hammerforge' `
  -RedirectStandardOutput "C:\Godot\godot_stdout.log" `
  -RedirectStandardError "C:\Godot\godot_stderr.log" `
  -NoNewWindow

Troubleshooting

No brushes appear - Ensure HammerForge is enabled. - Select LevelRoot. - Use Create Starter (or Create Floor) so raycasts hit something.

Subtract does nothing - Subtract only affects Add brushes and is visible after Bake. - Pending cuts appear in bright orange-red; once applied they turn standard red.

Paint preview looks wrong - Regenerate by deleting LevelRoot/Generated and paint again.

Dock not showing - Restart Godot after enabling the plugin.

Face selection not working - Enable Face Select Mode in the Paint tab → Materials section. - Use the Select tool (not Draw).

Material fails to load - Material .tres files must not have a UTF-8 BOM. If Godot reports "Expected '['" on a .tres file, re-save it without BOM (or create a fresh one via FileSystem -> New Resource -> StandardMaterial3D).

Heightmap mesh not appearing - Ensure the active layer has a heightmap assigned (use Import or Generate in the Paint tab → Heightmap section). - Confirm cells are painted first -- heightmap only displaces filled cells.

Blend shader shows only one slot - Paint blend weights using the Blend tool on already-filled cells. - Set a Blend Slot (B/C/D) and assign textures to Slot A-D.

Displacement create fails - The face must be a quad (exactly 4 vertices). Triangles and N-gons are not supported. - Ensure a face is selected in Face Select Mode.

Displacement paint does nothing - Enable Paint Mode in the dock. - Expand the Displacement section (it must be visible, not collapsed). - Ensure the face has a displacement (click Create first).

Bevel edge fails - Enter Vertex mode (V), then Edge sub-mode (E). Select an edge. - The edge must be shared by exactly 2 faces.

Inset face fails - The inset distance is too large relative to the face size. Use a smaller value. - Verify the blend_map texture is generated (requires cells with non-zero blend weights).