Troubleshooting

Grid Building 5.0.8 troubleshooting is mostly about understanding the maintenance wiring patterns:

  • Injector/container composition.
  • State-first signal flows.
  • Preview/targeting interactions.

Start here:

If your issue involves targeting previews being cleared unexpectedly, see:

\n**Version note: This guide is validated for Grid Building 5.0.8. Many crash-class bugs from 5.0.3 are resolved in this release. See Patch Notes for the full list.


5.0.8-Specific Checks

TargetingShapeCast2D Does Not Detect Placed Objects (Move/Demolish/Highlight)

This is the most common targeting issue. Two things to check:

1. Collision Flags (CRITICAL)

TargetingShapeCast2D will NOT detect any objects unless collision flags are set. In your GridPositioner scene:

1
2
3
TargetingShapeCast2D:
  collide_with_areas: true   # For Area2D targets
  collide_with_bodies: true  # For StaticBody2D targets (most placed objects)

Without these, the shapecast detects nothing even if layers are correct.

2. Collision Layer on Placed Objects

Your placed objects must have collision_layer set to the targeting layer:

1
2
StaticBody2D:
  collision_layer: 1, 10    # MUST include layer 10

Having collision_mask = 10 is NOT enough - that only lets the object DETECT layer 10, it doesn’t make the object VISIBLE to the shapecast.

3. Only the Root Should Own the Targeting Layer

If your scene hierarchy has multiple nodes with the targeting layer, the shapecast may detect the wrong node. Only the scene root should have the targeting layer - child physics bodies should NOT:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Correct: Only root has targeting layer
GeyserPump (root):
  collision_layer: 1, 10
  StaticBody2D:
    collision_layer: 1        # No targeting layer on child

# Wrong: Causes targeting to pick wrong node
GeyserPump (root):
  collision_layer: 1, 10
  StaticBody2D:
    collision_layer: 1, 10     # Child also has targeting layer - shapecast may hit this instead

When both parent and child have the targeting layer, the shapecast detects whichever is closest - which may not be the intended target.

See Targeting Flow: Collision Layer vs Collision Mask for Targeting for full details.

Move Fails with “not movable”

In 5.0.4, try_move() enforces is_movable() before move starts.

  • Verify the target has a valid Manipulatable component.
  • Verify its ManipulatableSettings allow movement (movable = true).
  • Ensure the Manipulatable.root property is correctly assigned to the scene root.

Rotation / Flip Not Preserved After Move

5.0.4 preserves accumulated transform on successful placement. If this still appears broken:

  • Verify your placement flow uses try_move(...) followed by try_placement(...).
  • Verify no custom script resets transform after placement.
  • Verify your test/object is not being replaced by unrelated scene logic after placement.

Save Data Contains Temporary Preview Objects

In 5.0.4, preview/manipulation copies are marked with gb_preview metadata on the parent node.

  • When saving, skip any placed object whose parent/root has gb_preview metadata.
  • Query placed nodes by their membership in the PlaceableInstance group.
1
2
3
func should_skip_preview(node: Node) -> bool:
    var parent_node = node.get_parent()
    return parent_node != null and parent_node.has_meta("gb_preview")

Web Export: Placement Rules Not Loading

\n5.0.4 update: Web exports work correctly on Godot 4.6.2 stable. The main issue is embedded SubResource(...) entries — these fail to load on web. Use external .tres files instead.

  • Verify base rules in GBSettings are external .tres files, not embedded subresources.
  • Both plain and typed array syntax work on Godot 4.6.2. If arrays are empty on older versions, try plain array syntax as a workaround.
  • Verify CollisionsCheckRule.messages is serialized explicitly or that _ensure_messages() is being triggered.
  • See Web Export Guide for full details.

Web Export: Nested Resource Defaults Missing

  • Save CollisionsCheckRule.messages and fail_visual_settings explicitly in the .tres file.
  • Use _ensure_messages() lazy-loading safeguard as a fallback.
  • See Web Export Guide.

Crash During Active Move (Source Deleted)

\n5.0.4 update: Fixed hard crash when the manipulation source is deleted during an active move.

If you are on 5.0.3 and cannot upgrade:

  • Ensure cancel_interaction() is called before freeing a manipulated object.
  • Manually remove the ManipulationParent from the scene tree before freeing it.

Stale Collision Shapes After Move

\n5.0.4 update: Fixed stale move copies causing collision interference.

If you are on 5.0.3 and cannot upgrade:

  • Call cancel_interaction() before starting a new manipulation.
  • Verify old preview nodes are freed and removed from the tree.

Null Logger Crash

\n5.0.4 update: IndicatorFactory now has a fallback logger when none is passed.

If you are on 5.0.3 and cannot upgrade:

  • Always pass a valid GBLogger to IndicatorFactory constructors.

CollisionMapper Asserts in Release Builds

\n5.0.4 update: Replaced assert() calls with push_error() + early returns. Asserts are compiled out in release builds, so release builds would silently continue with bad state.

If you are on 5.0.3 and cannot upgrade:

  • Build in debug mode to catch assertion failures, or patch CollisionMapper to use null guards.

General Troubleshooting Steps

  1. Check the Output Panel for errors and warnings.
  2. Verify injectionGBInjectorSystem.composition_container must be assigned before systems are used.
  3. Verify level contextGBLevelContext.target_map and objects_parent must be assigned.
  4. Verify ownerGBOwner.owner_root must be assigned.
  5. Run validation — Call injector.run_validation() after scene setup.
  6. Check collision layers — Ensure placed objects have collision_layer (what the object IS) set to the targeting layer, not just collision_mask. TargetingShapeCast2D uses collision_mask to find objects, but those objects must have matching collision_layer. See “TargetingShapeCast2D Does Not Detect Placed Objects” above.
  7. Check for preview leaks — Use the Orphan Nodes debugger panel to spot leaked preview/manipulation nodes.