Settings Architecture (6.0)

GridPlacement uses focused, category-specific Godot Resource classes for configuration. Each settings class has one reason to change.

Why Separate Settings Resources?

Settings ClassCategoryWhat It Controls
PlacementSettingsRootAggregates all sub-settings, update loop mode
PlacementGridSettingsGridCell size, tile dimensions
HotbarInputSettingsInputMode-switching action names
PlacementUpdateLoopSettingsLoop_Process vs _PhysicsProcess
TileMapSyncSettingsSyncTileMap sync behavior, chunk size

Benefits

  1. Cohesion — Each class has one purpose. Changing cursor input doesn’t risk accidentally changing grid dimensions.
  2. ReusabilityHotbarInputSettings can be reused by any system that needs cursor control.
  3. Testability — Unit tests can mock individual settings without pulling in unrelated dependencies.
  4. Editor UX — Godot’s inspector loads small .tres files faster than large ones. Games can override individual settings without copying everything.
  5. Overrideability — Games can swap only HotbarInputSettings while keeping PlacementGridSettings at default values.

Resource Hierarchy#

1
2
3
4
5
PlacementSettings (root)
├── UpdateLoop   → PlacementUpdateLoopSettings { get; set; }
├── TileMapSync  → TileMapSyncSettings        { get; set; }
├── Grid         → PlacementGridSettings     { get; set; }
└── Hotbar       → HotbarInputSettings      { get; set; }

PlacementSettings is the aggregate root. It exposes sub-resources via [Export] properties and lazily creates them via Ensure*() methods.

Godot Resource Details#

PlacementSettings (Root)#

1
2
3
var settings = new PlacementSettings();
settings.EnsureUpdateLoop().UpdateMode = GridPlacementBootstrapUpdateMode.PhysicsProcess;
context.Settings = settings;
PropertyTypeDefaultDescription
UpdateLoopPlacementUpdateLoopSettings?nullUpdate loop settings (lazy-created via EnsureUpdateLoop())
TileMapSyncTileMapSyncSettings?nullTileMap sync settings (lazy-created via EnsureTileMapSync())
GridPlacementGridSettings?nullGrid settings (lazy-created via EnsureGrid())
HotbarHotbarInputSettings?nullHotbar input settings (lazy-created via EnsureHotbar())

PlacementGridSettings#

1
settings.EnsureGrid().CellSize = 64;  // 64×64 pixel tiles
PropertyTypeDefaultDescription
CellSizeint32Tile size in pixels for grid-to-world conversion

HotbarInputSettings#

1
2
3
settings.EnsureHotbar().MoveAction = "move";
settings.EnsureHotbar().PlaceAction = "place";
settings.EnsureHotbar().DemolishAction = "demolish";
PropertyDefaultDescription
MoveAction"MovingMode"InputMap action for Move mode
PlaceAction"BuildMode"InputMap action for Place mode
DemolishAction"DemolishMode"InputMap action for Remove mode
InfoAction"InfoMode"InputMap action for Info mode
OffAction"OffMode"InputMap action for Off mode
RotateRightAction"RotateRight"Rotation action
RotateLeftAction"RotateLeft"Rotation action
FlipHorizontalAction"FlipHorizontal"Flip action
FlipVerticalAction"FlipVertical"Flip action
ConfirmAction"CursorConfirm"Placement confirm
CancelAction"CursorCancel"Placement cancel

PlacementUpdateLoopSettings#

1
settings.EnsureUpdateLoop().UpdateMode = GridPlacementBootstrapUpdateMode.Process;
PropertyTypeDefaultDescription
UpdateModeGridPlacementBootstrapUpdateModeProcessWhich update loop to use

GridPlacementBootstrapUpdateMode enum:

  • Process = 0 — Placement systems update in _Process (normal frame loop)
  • PhysicsProcess = 1 — Placement systems update in _PhysicsProcess (physics frame loop)

TileMapSyncSettings#

1
2
settings.EnsureTileMapSync().Enabled = true;
settings.EnsureTileMapSync().ChunkSize = 16;
PropertyTypeDefaultDescription
EnabledbooltrueWhether TileMap sync is enabled
ChunkSizeint16Chunk size for grouping TileMap sync operations

Usage in Code#

Accessing Settings via PlacementContext#

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
var context = GetNode<PlacementContext>("/root/PlacementContext");

// Ensure settings are initialized
var settings = context.EnsureSettings();

// Access sub-settings
var gridSettings = settings.EnsureGrid();
gridSettings.CellSize = 64;

var inputSettings = settings.EnsureHotbar();
inputSettings.MoveAction = "my_move";

Creating Custom Settings#

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
// Inherit from Godot Resource
[GlobalClass]
public partial class MyCustomSettings : Resource
{
    [Export] public bool EnableFeature { get; set; } = true;
    [Export] public float Threshold { get; set; } = 0.5f;
}

// Add to PlacementSettings
public partial class PlacementSettings
{
    [Export] public MyCustomSettings? MyCustom { get; set; }

    public MyCustomSettings EnsureMyCustom()
    {
        return MyCustom ??= new MyCustomSettings();
    }
}

Using as a .tres file#

  1. In Godot Editor: New Resource → PlacementSettings
  2. Expand properties and configure sub-resources
  3. Save as res://path/to/settings.tres
  4. Assign to PlacementContext.Settings in your scene