Grid Placement

Logging (C# Godot Layer)

Logging (C# Godot Layer)

GridPlacement 6.0 is C#-first and keeps Core logic as deterministic as possible.

Scope

This guide covers:

  • The logging contract (ILogger).
  • The default Godot logger implementation (GodotLogger).
  • How a game overrides logging by registering its own logger.

This guide does not cover:

  • Verbose per-frame debugging patterns (keep these out of Core).
  • Editor-only diagnostics.

Design rule: log at the engine-glue boundary

  • Core services should not depend on Godot.
  • Logging is treated as an engine-glue concern.
  • Prefer returning reports/diagnostics objects from Core over side-effect logging.

The logging contract

GridPlacement uses a small interface that games can replace:

  • GridBuilding.Core.Interfaces.ILogger

Key behaviors:

  • A LogLevel property controls filtering.
  • Call sites use LogDebug, LogInfo, LogWarning, LogError (and the general Log(level, message)).

Default logger: GodotLogger

The plugin provides a simple default logger for Godot:

  • GridBuilding.Godot.Services.Logging.GodotLogger

It maps log calls onto Godot built-ins:

  • Error/Critical: GD.PushError(...)
  • Warning: GD.PushWarning(...)
  • Info/Debug/Trace: GD.Print(...)

This is intended to be:

  • Stable
  • Minimal
  • Easy for demos

How the default is registered

ServiceCompositionRoot is responsible for registering engine-side services.

During RegisterGodotServices() it will:

  • Check whether ILogger is already registered
  • If not registered, register GodotLogger

This preserves a strict override rule:

  • Game logger wins (if registered first)
  • Plugin default is fallback

Overriding logging in a game

To replace logging behavior, register your own ILogger implementation before the plugin registers defaults.

Recommended places:

  • Your game-owned scope root / composition root
  • A per-user scope registry setup (multiplayer)

Pattern:

  • Create your ServiceRegistry
  • Register your logger as ILogger
  • Then let GridPlacement register the rest of its services

Multiplayer and per-user scopes

If your game uses one scope per user/player:

  • Register a separate logger instance per scope (if desired)
  • Keep log filtering/configuration on the per-scope logger

If your game uses a global shared scope:

  • Register one logger instance, but ensure it is safe for multiple users.

Checklist

  • Ensure you have a ServiceRegistry per user (recommended).
  • Register your game logger as ILogger before GridPlacement defaults.
  • Verify warnings/errors appear via Godot editor output.
  • Keep Core clean: prefer returning reports over logging.