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