Chris' Tutorials
Docs/Grid Placement

Grid Placement v6.0

Logger Configuration

Configure and override the PlacementLogger singleton without modifying plugin source.

StatusDraft
Versionv6.0
UpdatedDevelopment docs generated from GDScript source

This is unreleased documentation in active development. APIs, class names, and behavior may change before the final release.

Draft — Unreleased:This page is in active development. APIs, class names, and behavior may change before the release is finalized. Use it as a preview of what's coming — not as a stable integration target.

The Grid Placement plugin uses a static singleton logger (PlacementLogger) that can be configured and overridden at any point without modifying plugin source code.

Version note: This guide is validated for Grid Placement 6.0.0.

Quick Start

The logger is initialized automatically during plugin setup (via PlacementSession composition). No action is needed for basic logging output.

# Anywhere in the plugin — zero boilerplate, zero null checks:
PlacementLogger.debug("Terrain painted at cell %s" % str(cell))
PlacementLogger.trace("Validation details: %s" % str(details))
PlacementLogger.warn("Deprecated API called")
PlacementLogger.error("Failed to place: %s" % error)

Controlling Log Verbosity

Adjust the log level on the PlacementDebugSettings resource passed to the logger during initialization. Levels, from quietest to noisiest:

Level What you see
ERROR Only PlacementLogger.error()
WARNING Errors + warnings
INFO Errors, warnings, and PlacementLogger.info()
DEBUG All of the above + debug messages (default for development)
VERBOSE Includes setup reports and detailed placement reports
TRACE Everything — including per-frame diagnostics (very noisy)
# Reduce noise in production:
PlacementLogger.set_instance_log_level(PlacementLogger.LogLevel.WARNING)

# Or configure via the debug settings resource in your composition container:
var settings := PlacementDebugSettings.new()
settings.level = PlacementLogger.LogLevel.ERROR

Throttling and "Once" Logging

To prevent console spam during high-frequency operations (like _process or _input), the logger provides instance-based throttling.

Throttled Logs

Prints at most once every 250ms per object instance.

# Inside a node's _process()
_logger.log_debug_throttled(self, "Current position: %s" % str(global_position))

Log Once

Prints exactly once per object instance per session. Useful for one-time initialization warnings.

# Inside resolve_placement_dependencies()
_logger.log_info_once(self, "System successfully initialized.")

Overriding the Logger at Game Time

You can replace the plugin's logger entirely at any point. All existing PlacementLogger.debug() calls throughout the plugin automatically pick up the new instance.

Replace with a custom logger

# Create your own logger with custom settings
var my_debug_settings := PlacementDebugSettings.new()
my_debug_settings.level = PlacementLogger.LogLevel.WARNING
var my_logger := PlacementLogger.new(my_debug_settings)

# Optional: wire up a custom log sink (e.g., to your game's HUD or file)
my_logger.set_log_sink(func(level: int, context: String, message: String) -> void:
    my_game_hud.log("[GB] %s: %s" % [context, message])
)

# Swap it in — all plugin logging now routes through your logger
PlacementLogger.set_instance(my_logger)

Completely disable plugin logging

PlacementLogger.clear_instance()
# All PlacementLogger.debug/trace/warn/error calls become no-ops.

Restore the original logger

# Keep a reference before replacing:
var original_logger := PlacementLogger.new(original_settings)
# ... later ...
PlacementLogger.set_instance(original_logger)

Custom Log Sink

Route all plugin log output to a custom destination (console overlay, file, analytics):

logger.set_log_sink(func(level: int, context: String, message: String) -> void:
    match level:
        PlacementLogger.LogLevel.ERROR:
            your_error_handler.push(message)
        PlacementLogger.LogLevel.WARNING:
            your_warning_handler.push(message)
        _:
            your_debug_handler.append("[%s] %s" % [context, message])
)

When a log sink is set, the default push_error/push_warning/print output is suppressed.

Test Isolation

In GdUnit4 test suites, clear the singleton between tests to prevent state leakage:

extends GdUnitTestSuite

var _mock_logger: PlacementLogger

func before_test() -> void:
    _mock_logger = PlacementLogger.new(PlacementDebugSettings.new())
    PlacementLogger.set_instance(_mock_logger)

func after_test() -> void:
    PlacementLogger.clear_instance()

API Reference

Static Methods

Method Description
PlacementLogger.set_instance(logger) Register the plugin-wide logger instance
PlacementLogger.clear_instance() Clear the instance (disables all logging)
PlacementLogger.debug(msg) Log at DEBUG level
PlacementLogger.trace(msg) Log at TRACE level
PlacementLogger.info(msg) Log at INFO level
PlacementLogger.warn(msg) Log at WARNING level
PlacementLogger.error(msg) Log at ERROR level
PlacementLogger.verbose(msg) Log at VERBOSE level

All static methods silently no-op when no instance is registered (i.e., after clear_instance()).

Source

docs/v6-0/guides/logger-configuration.md

Plugin docs root:gdscript/plugins/grid_placement_dev/docs