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 Class | Category | What It Controls |
|---|
PlacementSettings | Root | Aggregates all sub-settings, update loop mode |
PlacementGridSettings | Grid | Cell size, tile dimensions |
HotbarInputSettings | Input | Mode-switching action names |
PlacementUpdateLoopSettings | Loop | _Process vs _PhysicsProcess |
TileMapSyncSettings | Sync | TileMap sync behavior, chunk size |
Benefits
- Cohesion — Each class has one purpose. Changing cursor input doesn’t risk accidentally changing grid dimensions.
- Reusability —
HotbarInputSettings can be reused by any system that needs cursor control. - Testability — Unit tests can mock individual settings without pulling in unrelated dependencies.
- Editor UX — Godot’s inspector loads small
.tres files faster than large ones. Games can override individual settings without copying everything. - 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;
|
| Property | Type | Default | Description |
|---|
UpdateLoop | PlacementUpdateLoopSettings? | null | Update loop settings (lazy-created via EnsureUpdateLoop()) |
TileMapSync | TileMapSyncSettings? | null | TileMap sync settings (lazy-created via EnsureTileMapSync()) |
Grid | PlacementGridSettings? | null | Grid settings (lazy-created via EnsureGrid()) |
Hotbar | HotbarInputSettings? | null | Hotbar input settings (lazy-created via EnsureHotbar()) |
PlacementGridSettings#
1
| settings.EnsureGrid().CellSize = 64; // 64×64 pixel tiles
|
| Property | Type | Default | Description |
|---|
CellSize | int | 32 | Tile size in pixels for grid-to-world conversion |
1
2
3
| settings.EnsureHotbar().MoveAction = "move";
settings.EnsureHotbar().PlaceAction = "place";
settings.EnsureHotbar().DemolishAction = "demolish";
|
| Property | Default | Description |
|---|
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;
|
| Property | Type | Default | Description |
|---|
UpdateMode | GridPlacementBootstrapUpdateMode | Process | Which 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;
|
| Property | Type | Default | Description |
|---|
Enabled | bool | true | Whether TileMap sync is enabled |
ChunkSize | int | 16 | Chunk 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#
- In Godot Editor: New Resource → PlacementSettings
- Expand properties and configure sub-resources
- Save as
res://path/to/settings.tres - Assign to
PlacementContext.Settings in your scene