Dungeon Auto-Generation Script + Plugin

Overview

This is a collection of GDScript scripts for automatically generating dungeons in the Godot editor/runtime.

Features

  • Configurable dungeon size, number of rooms, and minimum/maximum width/height for rooms and corridors.

  • Layout generation based on a seed.

  • Pre-create exterior/interior layout data and decorate/place objects using basic dungeon tiling patterns.

  • Visually configure minimum/maximum occurrence counts, frequency, and adjacency directions for each pattern.

  • Configure cell occupation settings, pattern coverage, and overwrite permissions per layer/pattern.
    By setting up multiple layers, you can create multi-layered decorations.


Usage Instructions

Although there are many settings, you will understand it smoothly if you download the sample project first.

1. Download the Sample Project

  1. Download the necessary files from the repository.
    https://github.com/ggg-shirokishi/procedural-layout-tools

  2. Place the addons and scripts directories directly under the project root.

2. Add the Layout Generator Node to the Scene

  1. Add a Node2D to any scene and attach the layout script room_rayout_generator from the scripts directory.

  2. Set various parameters of room_rayout_generator in the Inspector.

    • Map overall size: width, height
    • Number of rooms: room_count
    • Room size range: room_w_min / room_w_max, room_h_min / room_h_max
    • Corridor width parameters:
      • corridor_width
      • corridor_width_min / max
      • corridor_width_randomize_each_corridor
        • If corridor_width_randomize_each_corridor is enabled, the corridor width will be randomized between corridor_width_min and corridor_width_max.
    • Allow diagonal connections: connectivity_allow_diagonal
      • If connectivity_allow_diagonal is enabled, rooms will also connect diagonally.
    • Seed: seed
  3. Enabling editor_auto_generate / editor_live_update allows changes to various parameters to be reflected immediately in the editor.


3. Configure TileMapLayer and TerrainAtlasPatternPlacer

  1. Add a TileMapLayer and a Node2D (for executing the placement script) to the scene, and attach terrain_atlas_pattern_placer from the scripts directory to the Node2D.

    • The target tilemap layer and the placement Node2D have a 1:1 relationship, and you can add multiple pairs as needed.
    • There is no lower or upper limit to the number of layers, but in most cases, at least two sets of TileMapLayer + terrain_atlas_pattern_placer are required: one for exteriors (Terrain tile placement) and one for interiors.
      (In the sample project, these are TerrainTileLayer / TerrainTilePlacer and InteriorBaseLayer / InteriorBasePlacer)
  2. Set a TileSet for terrains on the TileMapLayer and register Terrains/Patterns.

  3. Set the following items on the node with the TerrainAtlasPatternPlacer script attached.

Main Settings for TerrainAtlasPatternPlacer

  • layout_node: Path to the room_rayout_generator node added in the previous section.
  • target_layer_path: Path to the TileMapLayer this Placer operates on.
  • target_kind: Cell type handled by this layer (WALLS / FLOORS)
    WALLS: Exterior / impassable terrain (Terrain is usually placed here)
    FLOORS: Interior
  • placement_type: Whether to paint with Terrain or place with Pattern (TERRAIN / PATTERN).
  • clear_before_place: Whether to clear the layer before each re-placement.
  • register_used_cells_to_layout: Whether to register used cells to the layout’s used_cells_mask.
    ※Enabling this option prevents overlapping placement by layers/patterns with larger execution_order when only_place_on_unoccupied is also On.
  • only_place_on_unoccupied: Restrict placement to unoccupied cells only.
  • auto_update_on_layout_signal: Whether to automatically re-place upon receiving a layout update signal.
  • pattern_coverage_ratio: Density of pattern placement over the entire area.
  • execution_order: Processing order when there are multiple TerrainAtlasPatternPlacer nodes.
    Smaller numbers are processed first. It is used in combination with only_place_on_unoccupied and register_used_cells_to_layout to control overlapping placement.

4. Detailed Pattern Settings (Editor Extension Inspector)

When you link a tilemap layer to TerrainAtlasPatternPlacer, a panel listing patterns from the TileSet is added to the Inspector.
You can set the following items for each pattern.

  • pattern_required_cells: Required adjacent cells
    (Cells within the pattern that “must touch the edge”)
    Set in combination with pattern_adjacent_dirs described below.
    ※You can set this by checking the cells below the thumbnail.

  • pattern_weights: Appearance frequency.

  • pattern_min_counts, pattern_max_counts: Minimum/maximum occurrence counts (unlimited by default).

  • pattern_adjacent_dirs: Adjacency directions
    (Which of the up, down, left, right directions require adjacent cells)

    Example:
    If pattern_required_cells is set to the top 2 cells and pattern_adjacent_dirs is set to “Up”, it will only be placed on terrains where the top 2 cells are guaranteed to be adjacent.

  • pattern_register_used_cells_override: Cell occupation registration override
    You can set whether to occupy cells on a per-pattern basis.

    • Inherit global settings (same as TerrainAtlasPatternPlacer settings)
    • Force On
    • Force Off
  • pattern_only_place_on_unoccupied_override: Place only on unoccupied cells override

    • Inherit global settings (same as TerrainAtlasPatternPlacer settings)
    • Force On
    • Force Off

After setting these items roughly, press run_on_editor_button to generate the layout.


Runtime Regeneration Settings (Optional)

  • If you want to regenerate the dungeon via key input during execution, attach a script equivalent to RuntimeLayoutKeyboardController to a Node.

Main Settings

  • layout_node_path: Layout generator node.
  • input_action_name: InputMap action name used for regeneration (e.g., regen_dungeon).
  • randomize_layout_size / randomize_room_count / randomize_room_size / randomize_corridor_width: Whether to randomize various parameters for each execution.
  • move_target_node_path: Node to move after regeneration (e.g., player).
  • move_target_tilemap_layer_path: TileMapLayer used for floor collision detection.
  • move_after_generation: Whether to move the target to an empty cell after regeneration.
  • zoom_camera_path: Camera whose limit you want to adjust according to the layout.

After starting the game, pressing the specified action key will

  1. Change the seed
  2. Regenerate the layout
  3. Automatically move the player and adjust the camera as needed

Multi-Layer Decoration with Multiple Layers

By sharing the same layout node with multiple TerrainAtlasPatternPlacer nodes and controlling the processing order using execution_order, you can achieve multi-layered decorations such as the following:

  • Layer 1: Exterior (base tiles for walls/floors)
  • Layer 2: Interior (patterns for pillars, windows, beams, etc.)
  • Layer 3: Objects (furniture, debris, decorations)

By toggling

  • register_used_cells_to_layout
  • only_place_on_unoccupied

for each layer, or using pattern-side overrides, you can control

  • “Stack on top without breaking the base”
  • “Overwrite only specific parts”

Tips and Notes

  • Tilemap layers and TileSet sizes must be unified.

  • If you want to place game objects randomly:
    Add a Scene Collection to the TileSet, place objects on the tilemap, and then incorporate them into patterns for placement.
    (You can check the relevant settings in GameObjectLayer and InteriorBaseLayer within the sample project.)

Details of Various Scripts

room_rayout_generator.gd

Usage Overview

This is a layout-specific generator to be attached to a Node2D.
It does not write to any TileMap.

The generation results are held as properties.

  • grid: int 2D array
    CELL_WALL = 0, CELL_FLOOR = 1, CELL_DOOR = 2
  • rooms: Array[Rect2i] (room rectangles)
  • centers: Array[Vector2i] (room centers)
  • room_id_grid: Room ID for each cell (identification per room)
  • corridor_id_grid: Corridor ID for each cell
  • used_cells_mask: Mask of “used cells” registered from outside (Placer)

External API for Layout Generation

  • generate_now()
    Performs synchronous layout generation and emits generation_finished(success: bool) upon completion.
  • generate_async() -> Signal
    Performs asynchronous generation. It checks for busy status via _is_generating, executes processing with await, and finally returns the result via the same generation_finished signal.

Signals

  • layout_updated(grid, rooms, centers)
    Fires when the grid and room information are updated.
  • generation_finished(success)
    Notifies whether the overall generation was successful.

TerrainAtlasPatternPlacer, etc., reference the generated grid and share “empty/used cells on the layout” via
register_used_cells() / get_free_cells().

In the editor, editor_auto_generate / editor_live_update / editor_generate_button allow you to control

  • Automatic generation on scene load
  • Automatic regeneration when parameters are changed in the Inspector

Main Variables and Properties

Output and State

  • signal layout_updated(grid: Array, rooms: Array, centers: Array)
    A signal that notifies the outside of the current layout information.
  • signal generation_finished(success: bool)
    Notifies success/failure when generation is complete.
  • const CELL_WALL: int = 0
    Value representing “wall” in the grid.
  • const CELL_FLOOR: int = 1
    Value representing “floor” in the grid.
  • const CELL_DOOR: int = 2
    Value representing “door candidate cell” in the grid.
  • var rng: RandomNumberGenerator
    Instance for random number generation. Seeded from seed and _seed_internal.
  • var _is_generating: bool
    Flag indicating whether asynchronous generation is in progress. Becomes true during generate_async and false upon completion.
  • var grid: Array
    2D array of grid[y][x]. Values are one of the CELL_* constants.
  • var rooms: Array[Rect2i]
    Array of room rectangles that were successfully generated.
  • var centers: Array[Vector2i]
    Array of center cell coordinates for each room.
  • var room_id_grid: Array
    room_id_grid[y][x] holds which room ID the cell belongs to (e.g., -1 if not part of a room).
  • var corridor_id_grid: Array
    corridor_id_grid[y][x] holds the corridor ID (e.g., -1 if not a corridor).
  • var _next_corridor_id: int
    Internal counter used for assigning corridor IDs.
  • var used_cells_mask: Array
    2D array of used_cells_mask[y][x] = bool representing “whether the cell is a used cell registered from the TilePlacer side.”
    Set to true via register_used_cells(cells: Array[Vector2i]).
    get_free_cells(kind: int) returns only cells that are false as “empty cells.”

Map Size and Room Parameters

  • @export var width: int = 80
    Layout width (number of cells). _set_width() prevents values less than 8, and regeneration occurs on change in the editor.
  • @export var height: int = 60
    Layout height (number of cells). _set_height() ensures it does not become less than 8.
  • @export var cell_padding: int = 1
    Margin from the outer perimeter. Rooms will not be placed within this number of cells from the outer frame.
  • @export var room_count: int = 18
    Target number of rooms to attempt generation. The actual number generated may be lower due to collisions, etc.
  • @export var room_w_min: int = 5 / room_w_max: int = 14
    Minimum/maximum width (number of cells) for rooms. The setter ensures room_w_min <= room_w_max.
  • @export var room_h_min: int = 4 / room_h_max: int = 12
    Minimum/maximum height (number of cells) for rooms. Consistency is maintained via the setter.

Corridor Parameters

  • @export var corridor_width: int = 1
    Base value for corridor width. This fixed width is used if random width is not used.
  • @export var corridor_width_min: int = 0
    Minimum value for random corridor width.
  • @export var corridor_width_max: int = 1
    Maximum value for random corridor width.
  • @export var corridor_width_randomize_each_corridor: bool = true
    When true, the width is randomly determined individually for each corridor (segment) from the range corridor_width_min to corridor_width_max.
  • @export var corridor_use_diagonal_path: bool = false
    When true, diagonal paths are allowed in the digging of corridors connecting room centers (a zigzag path moving diagonally).
  • @export var connectivity_allow_diagonal: bool = false
    When true, diagonal (8-directional) connections are considered “connected” during connectivity checks (verifying all rooms are connected).

Randomness, Retry, and Asynchronous

  • var _seed_internal: int = 123456
    Internal seed actually passed to the RNG.
  • @export var seed: int = 123456
    Public seed for layout generation. The setter updates _seed_internal, and if editor_live_update is true in the editor, it regenerates immediately.
  • @export var max_retry: int = 25
    Maximum number of retries when room generation or corridor connection fails, changing the seed each time.
  • @export var async_yield_rows: int = 6
    Represents how many rows to split processing by during asynchronous generation using await process_frame, etc.
    Larger values dig more at once but block the main thread for longer.

Logging and Editor

  • @export var log_enabled: bool = true
    When true, outputs logs via _log().
  • @export var log_verbosity: int = 1
    Log detail level. Higher values produce more detailed logs.
  • @export var editor_auto_generate: bool = true
    Flag for automatically generating the layout on scene load, etc.
  • @export var editor_live_update: bool = true
    Whether to automatically regenerate on the spot when parameters are changed in the editor.
  • @export var editor_generate_button: bool = false
    Flag for the “generate once” trigger in the Inspector.
    _generate_editor_safe() is called only at the moment it is set to true, and it is immediately reset to false.

terrain_atlas_pattern_placer.gd (TerrainAtlasPatternPlacer)

Usage Overview

This is a script for Node2D with class_name TerrainAtlasPatternPlacer.

Its role is
“To reference the grid of RoomLayoutGenerator and apply Terrain or Pattern to the specified TileMapLayer.”

Main prerequisites:

  • Set layout_node to reference a node that holds grid and emits layout_updated / generation_finished, such as room_rayout_generator.gd.
  • Set target_layer_path to specify the TileMapLayer to apply to.

Target cell types:

  • When target_kind = WALLS, target CELL_WALL cells.
  • When target_kind = FLOORS, target CELL_FLOOR + CELL_DOOR cells.

Application method:

  • When placement_type = TERRAIN,
    Paint Terrain using set_cells_terrain_connect().
  • When placement_type = PATTERN,
    Apply using TileMapPattern from the TileSet.

Other behaviors:

  • If auto_update_on_layout_signal is true, it automatically re-applies upon receiving layout_updated / generation_finished from the layout_node.
  • register_used_cells_to_layout determines whether to register cells used during placement to layout_node.register_used_cells(cells) and reflect them in used_cells_mask.
  • only_place_on_unoccupied allows restricting placement to “cells that are unoccupied on both the layout and the TileMapLayer.”
    You can further override this behavior on a per-pattern basis using pattern_*_override.
  • When multiple Placers share the same layout, you can control execution order using execution_order (executed in ascending order of value).

Signals

  • signal placement_finished(success: bool)
    Emitted when the placement process is complete.

Main Variables and Properties

Basic and Types

  • signal placement_finished(success: bool)
    Notifies whether placement is complete.
  • const CELL_WALL: int = 0 / CELL_FLOOR: int = 1 / CELL_DOOR: int = 2
    Value definitions for the layout grid. Corresponds to the RoomLayoutGenerator side.
  • enum TargetKind { WALLS, FLOORS }
    Specifies which cell type to target.
  • enum PlacementType { TERRAIN, PATTERN }
    Mode for Terrain painting or Pattern placement.

Layout Reference and Target Layer

  • @export var layout_node: NodePath
    Path to the layout generation node (e.g., RoomLayoutGenerator).
    The setter _set_layout_node caches it internally in _layout_ref.
  • var _layout_ref: Node
    Actual reference to the layout node.
  • var _grid: Array
    Internal array for caching the currently used layout grid.
  • @export var target_layer_path: NodePath
    Path to the TileMapLayer to apply to.
  • var _target_layer: TileMapLayer
    Reference to the actual tile placement target layer.

Execution Control and Linking

  • @export var clear_before_place: bool = true
    When true, executes TileMapLayer.clear() before starting placement.
  • @export var register_used_cells_to_layout: bool = true
    When true, passes the list of cells used during placement to layout_node.register_used_cells(cells).
  • @export var only_place_on_unoccupied: bool = false
    When true, targets only “cells that are unoccupied on the layout and empty on the TileMapLayer.”
    Judgment is made by combining the layout’s get_free_cells(kind) with TileMapLayer cell checks.
  • @export var run_on_editor_button: bool = false
    Flag for the editor button trigger. The moment it is set to true, _set_run_on_editor_button() is called, which
    • Executes layout.generate_now()
    • Performs processing equivalent to place_now() afterward
      and resets the flag to false upon completion.
  • @export var auto_update_on_layout_signal: bool = true
    When true, automatically links with the layout_updated / generation_finished signals of layout_node.
  • @export var auto_update_in_editor_only: bool = true
    When true, updates automatically only during editor execution, not during game execution.
  • @export var auto_update_debounce_frames: int = 1
    How many frames to buffer for batch updates during automatic updates.
    Even if 0, it waits at least 1 frame.
  • @export var log_enabled: bool = true
    Whether to output logs.
  • @export var log_verbosity: int = 1
    Log detail level.
  • @export var execution_order: int = 0
    Specifies execution order among multiple Placers referencing the same layout_node.
    Executed in ascending order of value; if values are the same, sorted by ascending instance_id.
  • var _pending_auto_update_local: bool
  • var _last_used_cells: Array[Vector2i]
  • var _last_pattern_force_register: bool
    Internal variables holding the pending state for batch updates and the most recent placement information.

Placement Mode and Terrain

  • @export var target_kind: TargetKind = TargetKind.WALLS
    Specifies which cell type on the layout to target (wall or floor).
  • @export var placement_type: PlacementType = PlacementType.TERRAIN
    Selects between Terrain mode or Pattern mode.
  • @export var terrain_set_index: int = 0
    Index of the Terrain set to use.
  • @export var terrain_index: int = 0
    Index of the Terrain to use within the above set.

Pattern-Related Settings

  • @export var pattern_indices: PackedInt32Array = PackedInt32Array()
    List of indices for TileMapPattern to use. If empty, all available patterns are targeted.
  • @export var pattern_avoid_overlap: bool = true
    When true, places patterns so they do not overlap each other.
  • @export var pattern_coverage_ratio: float = 0.1
    Target percentage of the total target cells to be covered by patterns (0.0–1.0).
  • @export var pattern_weights: Dictionary = {}
    Appearance weight per pattern.
    • Key: pattern_index
    • Value: float (weight)
  • @export var pattern_adjacent_dirs: Dictionary = {}
    Adjacency direction bitmask per pattern.
    • Key: pattern_index
    • Value: int bitmask
      • Bit values: 1 = U (Up), 2 = R, 4 = D, 8 = L
  • @export var pattern_required_cells: Dictionary = {}
    “Required adjacent cells” definition per pattern.
    • Key: pattern_index
    • Value: Array[Vector2i] (array of pattern internal cell coordinates)
  • @export var pattern_min_counts: Dictionary = {}
    Minimum placement count per pattern.
  • @export var pattern_max_counts: Dictionary = {}
    Maximum placement count per pattern. -1 or unset means “no limit.”
  • @export var pattern_register_used_cells_override: Dictionary = {}
    Per-pattern override for register_used_cells_to_layout.
    • Value: 0 = Inherit (inherit global settings)
    • Value: 1 = Force On (always register as used cell)
    • Value: 2 = Force Off (always exclude from used cell registration)
  • @export var pattern_only_place_on_unoccupied_override: Dictionary = {}
    Per-pattern override for only_place_on_unoccupied.
    • Value: 0 = Inherit (inherit global settings)
    • Value: 1 = Force On (place this pattern only on “unoccupied cells”)
    • Value: 2 = Force Off (place this pattern even on used cells)

terrain_pattern_placer_inspector.gd + plugin.gd / plugin.cfg

Usage Overview

Via plugin.cfg and plugin.gd,
it is registered as the “Terrain Pattern Tools” plugin in the Godot editor.

Contents of plugin.cfg:

  • name="Terrain Pattern Tools"
  • description="Custom inspector for TerrainAtlasPatternPlacer (pattern weights / adjacency)."
  • script="plugin.gd"

plugin.gd inherits EditorPlugin and in _enter_tree()

  • Creates terrain_pattern_placer_inspector.gd via Script.new() and
  • Registers the inspector extension via add_inspector_plugin(_insp).

In _exit_tree(), it does the opposite via remove_inspector_plugin(_insp).

When you enable this plugin from project settings,
selecting a node with TerrainAtlasPatternPlacer attached will

  • Add a per-pattern settings UI in addition to the standard Inspector.

Content Editable in the Added UI

For each TileMapPattern:

  • Thumbnail of the raw tile appearance
  • Grid thumbnail showing cell placement within the pattern
  • Appearance weight (SpinBox)
  • Adjacency directions (U/R/D/L checkboxes)
  • Required adjacent cells (buttons to toggle cells within the pattern by clicking)
  • Minimum placement count (Min)
  • Maximum placement count (Max, -1 for unlimited)
  • Per-pattern override for register_used_cells_to_layout (Reg)
  • Per-pattern override for only_place_on_unoccupied (Unocc)

All of these directly rewrite the following properties on TerrainAtlasPatternPlacer:

  • pattern_weights
  • pattern_adjacent_dirs
  • pattern_required_cells
  • pattern_min_counts
  • pattern_max_counts
  • pattern_register_used_cells_override
  • pattern_only_place_on_unoccupied_override

class PatternPreviewControl extends Control

A Control class dedicated to pattern preview rendering.

  • var tileset: TileSet
    TileSet used for the preview.
  • var pattern: TileMapPattern
    Pattern to preview.
  • var preview_size: Vector2
    Display size inside the scroll view.

It generates a TileMapLayer internally, applies the pattern via set_cell(), etc., and displays the appearance as-is in _draw().

Dictionary Access Helpers

  • Retrieves each Dictionary via _get_dict_safe(placer, "pattern_weights"), etc., updates it during UI operations,
    and writes it back like placer.set("pattern_weights", d).

runtime_rayout_controller.gd (RuntimeLayoutKeyboardController)

Usage Overview

A runtime controller to be attached to a Node.

Role:

  • When the specified input action is pressed,
    • Randomly update the layout node’s seed,
    • (Optionally) randomize layout parameters (width/height/room count/room size/corridor width),
    • Trigger generate_now() on the layout_node to regenerate the layout.
  • After regeneration, you can perform the following:
    • Move the node specified by move_target_node_path to one of the “empty cells.”
    • Automatically adjust the limit_* of the camera specified by zoom_camera_path to match the layout’s outer frame.

Prerequisites

  • Set layout_node_path to the Node2D with room_rayout_generator.gd attached.

Input Monitoring

  • Monitors Input.is_action_just_pressed(input_action_name) within _process(),
    and calls _regenerate_with_random_seed() when the action is pressed.

Movement and Camera

  • If move_after_generation is true, movement is performed via _move_target_to_free_cell() after layout updates.
  • If zoom_camera_path is set, limit_left / right / top / bottom are recalculated via _update_camera_limits().

Main Variables and Properties

Basic Settings

  • const CELL_WALL: int = 0 / const CELL_FLOOR: int = 1
    Value definitions for the layout grid (same as RoomLayoutGenerator).
  • enum MoveTargetKind { MOVE_ON_FLOORS, MOVE_NEAR_WALLS }
    Enumeration representing how to select the destination cell.
    • MOVE_ON_FLOORS: Move onto floor cells.
    • MOVE_NEAR_WALLS: Select candidates using logic that prioritizes floor cells near walls.
  • @export var layout_node_path: NodePath
    Path to the layout node (RoomLayoutGenerator).
  • @export var input_action_name: String = "dungeon_regen"
    InputMap action name used as the trigger for layout regeneration.
  • @export var log_enabled: bool = true
    When true, outputs internal processing logs via print() / push_warning(), etc.
  • var layout_node: Node = null
    Actual reference to the layout node. Retrieved from layout_node_path in _ready().
  • var _rng: RandomNumberGenerator = RandomNumberGenerator.new()
    RNG used for randomization during each layout regeneration.

Randomization of Layout Parameters

  • @export var randomize_layout_size: bool = false
    When true, randomly changes the layout width and height for each regeneration.
  • @export var layout_width_range: Vector2i = Vector2i(80, 80)
    Random range for width. (x = min, y = max)
  • @export var layout_height_range: Vector2i = Vector2i(60, 60)
    Random range for height.
  • @export var randomize_room_count: bool = false
    When true, randomly changes room_count for each regeneration.
  • @export var room_count_range: Vector2i = Vector2i(18, 18)
    Random range for room_count.
  • @export var randomize_room_size: bool = false
    When true, randomly changes the room size range for each regeneration.
  • @export var room_width_range: Vector2i = Vector2i(5, 14)
    Original random range for room width. Internally, it draws two values to determine min/max.
  • @export var room_height_range: Vector2i = Vector2i(4, 12)
    Original random range for room height.
  • @export var randomize_corridor_width: bool = false
    When true, randomly changes the corridor width for each regeneration.
  • @export var corridor_width_range: Vector2i = Vector2i(0, 3)
    Original random range for corridor width. Two values are drawn from here to set min/max, or to select a fixed width.

Movement Target and Camera Related

  • @export var move_target_node_path: NodePath
    Path to the target node to move after layout updates (e.g., player character).
  • @export var move_target_tilemap_layer_path: NodePath
    Path to the TileMapLayer corresponding to the layout.
    From here, it determines which cells are floors or walls to obtain candidate destination cells.
  • @export var move_target_kind: MoveTargetKind = MoveTargetKind.MOVE_ON_FLOORS
    Specifies how to select the destination cell using the above enumeration.
  • @export var move_after_generation: bool = true
    When true, executes _move_target_to_free_cell() after layout regeneration.
  • @export var cell_size: Vector2 = Vector2(16.0, 16.0)
    Pixel size of one cell in the layout grid.
    Used to calculate world coordinates from coordinates on the grid.
  • @export var zoom_camera_path: NodePath
    Path to the Camera2D / ZoomCamera2D whose limit_left / right / top / bottom are automatically adjusted after regeneration.
1 Like