Mode State and Enums (6.0)

This guide documents how GridBuilding 6.0 represents build modes and how it maps from the legacy GDScript enums used in GBEnums and BuildingMode to the new canonical C# enum GridMode.

It is intended for:

  • Existing GDScript projects migrating from GBEnums.Mode / BuildingMode.
  • New 6.0 projects that should only depend on GridMode and IModeService.

Canonical mode enum in 6.0

In 6.0, there is one canonical gameplay/tool mode enum for the GridBuilding system:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
namespace GridBuilding.Core.Types
{
    /// <summary>
    /// Primary mode enum for the grid building system.
    /// Represents the current high-level tool/mode the system is in.
    /// </summary>
    public enum GridMode
    {
        /// <summary>System is disabled / no building interaction.</summary>
        Off = 0,
        /// <summary>Information mode - hover/inspect.</summary>
        Info = 1,
        /// <summary>Placement mode - placing new objects.</summary>
        Place = 2,
        /// <summary>Move mode - relocating existing objects.</summary>
        Move = 3,
        /// <summary>Remove mode - removing objects (demolish / sell / delete semantics).</summary>
        Remove = 4,
    }
}

Key points:

  • GridMode is the only mode enum that represents the current tool / gameplay mode.
  • The mode service (GridBuilding.Core.Services.Mode.IModeService) exposes the current GridMode and emits mode-change events.
  • Godot UI (for example, UIManager and GBCursorChanger) synchronizes with GridMode and uses it as the source of truth.

Any older enums that tried to describe “modes” (such as BuildingMode, ManipulationMode, ApplicationMode, EditMode, etc.) are now marked [Obsolete] and should be treated as legacy only.


Legacy GDScript mode enums (pre‑6.0)

Historically, the Godot side used a centralized GDScript class GBEnums:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# addons/grid_building/core/base/gb_enums.gd
class_name GBEnums

## Defines what building operation is being performed
enum Mode {
    OFF,        # Building systems are offline
    INFO,       # Targeting objects for information purposes only
    BUILD,      # Objects currently being placed
    MOVE,       # Changing Position, Rotation, or Size of Existing Objects
    DEMOLISH    # Destroying destructible objects from the scene
}

## Actions that can be taken within the building system
enum Action {
    BUILD,
    MOVE,
    ROTATE,
    FLIP_H,
    FLIP_V,
    DEMOLISH
}

On the C# side, an early port introduced a BuildingMode enum that intentionally mirrored GBEnums.Mode:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// Legacy, now [Obsolete]
[Obsolete("BuildingMode is deprecated. Use GridMode (GridBuilding.Core.Types.GridMode) instead.")]
public enum BuildingMode
{
    Off = 0,
    Info = 1,
    Build = 2,
    Move = 3,
    Demolish = 4,
}

6.0 note: BuildingMode exists only as a historical artifact and is not used by the 6.0 core at runtime. New C# code must depend directly on GridMode and must not introduce new usages of BuildingMode.

In 6.0, both GBEnums.Mode and BuildingMode are considered legacy representation of mode for migration purposes only. The new, stable enum is GridMode.


Mode mapping: GDScript → 6.0 C#

The following table documents how old GDScript modes map onto GridMode in 6.0.

This is useful when migrating GDScript code or older C# wrappers that still think in terms of GBEnums.Mode or BuildingMode.

Primary build modes

Legacy enum (GDScript / C#)6.0 enum (C#)Notes
GBEnums.Mode.OFFGridMode.OffSystems disabled / no interaction.
GBEnums.Mode.INFOGridMode.InfoInfo / inspect mode (hover for details, no edits).
GBEnums.Mode.BUILDGridMode.PlaceBuilding / placement of new objects.
GBEnums.Mode.MOVEGridMode.MoveMoving existing objects.
GBEnums.Mode.DEMOLISHGridMode.RemoveGeneric removal: demolish / sell / delete any object.
BuildingMode.OffGridMode.OffLegacy C# mirror of GBEnums.Mode.OFF.
BuildingMode.InfoGridMode.InfoLegacy C# mirror of GBEnums.Mode.INFO.
BuildingMode.BuildGridMode.PlaceLegacy C# mirror of GBEnums.Mode.BUILD.
BuildingMode.MoveGridMode.MoveLegacy C# mirror of GBEnums.Mode.MOVE.
BuildingMode.DemolishGridMode.RemoveLegacy C# mirror of GBEnums.Mode.DEMOLISH.

Actions vs. modes

GBEnums.Action represented discrete actions (build, move, rotate, flip, demolish). In 6.0 these map to operation types, not global modes:

Legacy enum (GDScript)6.0 conceptNotes
GBEnums.Action.BUILDGridMode.Place + placement servicesPerformed while in a placement-oriented mode.
GBEnums.Action.MOVEGridMode.Move + move servicesPerformed while in move mode.
GBEnums.Action.ROTATEOperation within placement / moveRotation is typically a sub-action while placing or moving.
GBEnums.Action.FLIP_HOperation within placement / moveHorizontal flip sub-action.
GBEnums.Action.FLIP_VOperation within placement / moveVertical flip sub-action.
GBEnums.Action.DEMOLISHGridMode.Remove + remove servicesRemoval of objects (demolish / sell / delete).

Guideline: In 6.0 you should treat GridMode as the high-level tool state, and treat rotations / flips / specific building commands as domain operations invoked while in that mode, rather than as separate global modes.


How mode state flows in 6.0

At a high level, mode state works like this in a 6.0 project:

  1. Core service layer keeps the authoritative GridMode via IModeService.
  2. Godot UI (UIManager) maps UI interactions (e.g. placement toolbar, hotkeys) into GridMode values.
  3. Systems & tools read the current GridMode and decide whether they are active.
  4. Cursor / highlight visuals (e.g. GBCursorChanger, highlight settings) respond to GridMode changes to update visual feedback.

Example: reading GridMode from a Godot node

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
using Godot;
using GridBuilding.Core.Services.Mode;
using GridBuilding.Core.State.Mode;
using ModeEnum = GridBuilding.Core.Types.GridMode;
using GridBuilding.Godot.Services.DI;

public partial class ModeDebugLabel : Label
{
    private IModeService? _modeService;

    public override void _Ready()
    {
        // Resolve the global mode service
        _modeService = ServiceCompositionRoot.GetGlobalService<IModeService>();

        if (_modeService != null)
        {
            _modeService.ModeChanged += OnModeChanged;
            Text = $"Mode: {_modeService.Current}";
        }
        else
        {
            Text = "Mode service not available";
        }
    }

    private void OnModeChanged(object? sender, ModeChangedEvent e)
    {
        Text = $"Mode: {e.NewMode}";
    }
}

This pattern keeps GridMode as the single source of truth while allowing Godot UI nodes to react to mode changes.

This is conceptually similar to the old GBEnums.Mode, but:

  • The enum is owned by C# Core instead of GDScript.
  • There is exactly one canonical mode enum (GridMode).
  • Legacy multi-enum state (ApplicationMode, UIMode, EditMode, ViewMode, GameMode, BuildingMode, ManipulationMode) is kept only for compatibility and is marked [Obsolete].

Migration tips

When migrating an existing GDScript project that used GBEnums.Mode:

  1. Identify mode usage

    • Search for GBEnums.Mode.* and GBEnums.Action.* in your GDScript.
  2. Switch to service-based mode access

    • Use Godot integration (e.g. UIManager, mode service access) to query the current GridMode instead of tracking GBEnums.Mode yourself.
  3. Apply the mapping table

    • Replace old cases according to the table above, e.g.:
      • GBEnums.Mode.BUILDGridMode.Place
      • GBEnums.Mode.DEMOLISHGridMode.Remove
  4. Keep UI text free to change

    • Even though the enum member is Remove, your UI can still label the tool as Demolish, Sell, or Remove depending on context.
  5. Avoid new usage of legacy enums

    • Treat BuildingMode, ManipulationMode, ApplicationMode, etc. as read-only legacy. Do not introduce new code that depends on them.

For more background on the overall architecture and migration: