Skip to content
majikayogames edited this page Sep 19, 2024 · 21 revisions

Welcome to the SimpleDungeons wiki!

This wiki will document the API and basic usage. There is also a tutorial video here: https://www.youtube.com/watch?v=v58l05FsdPs

Basic usage

  1. Clone this repo or download as a zip.
  2. Copy the contents of the addons folder to your project's addons directory.
  3. Enable the plugin in Project Settings > Plugins > SimpleDungeons.
  4. Add a new DungeonGenerator3D to your scene.
  5. Create the room scenes of your dungeon. All rooms must inherit DungeonRoom3D (you can create custom DungeonRoom3D classes as long as they inherit DungeonRoom3D).
  • Upon creating a DungeonRoom3D, you will see a voxel grid appear, and you can change the dimensions of the room in voxels image
  • To add doors to your dungeon room so it can be connected to the rest of the dungeon, add nodes with names prefixed by DOOR for required or DOOR? for optional image
  1. Create the corridor room scene of your dungeon. The corridor room must be 1x1x1 in voxels and have 4 optional doors, one on each side. The corridor room will be used when pathfinding, to connect all rooms together.
  2. Ensure the voxel scale of your DungeonGenerator3D matches the voxel scale on each of your DungeonRoom3Ds. If the voxel scale is not the same, the room Node3Ds will be scaled, perhaps even non-uniformly, so that the voxel scale matches. A warning will be printed in the console if your voxel scales do not match.
  3. Add all room scenes to your dungeon. You can select multiple in the Godot FileSystem tab and drag them onto the room scenes property on the DungeonRoom3D.
  4. Either call generate() manually on the DungeonGenerator3D or use the generate on ready checkbox to generate as soon as your level starts.

DungeonGenerator3D API

Signals

signal done_generating()

Emitted when the DungeonGenerator3D completes its generation.

signal generating_failed()

Emitted when the DungeonGenerato3D fails its generation, and no retries are left. If you properly construct your dungeon, this shouldn't happen. You can increase the max_retries or max_safe_iterations values if it is failing, but realistically it should never really need to retry more than once. If it is failing frequently, you may need to adjust your dungeon so rooms can separate and connect properly.

Functions

generate(seed : int = int(generate_seed) if generate_seed.is_valid_int() else randi()) -> void

Call this function to begin the generation phase. It takes 1 optional parameter, the generation seed which must be an integer. If it is not provided, it will look to the property generate_seed which you can set in editor. If that is also not provided, it will just use a random integer for the generation.

One thing to note, the reason why generate_seed was set to be a string, I noticed sometimes Godot was not letting me put very large integers into int export properties, so I made it a string to avoid any glitchiness.

Also, once all the DungeonRoom3Ds are spawned in, they will be contained in a Node3D with the name "RoomsContainer" which is created as a direct child of the DungeonGenerator3D.

abort_generation() -> void

If currently generating, calling this function will abort the current generation and cause it to fail. This function is thread safe.

get_room_at_pos(grid_pos : Vector3i) -> DungeonRoom3D

After generating, you can call this function to check what DungeonRoom3D occupies a particular grid square/voxel. This might be useful for changing the appearance of a dungeon post generation.

Variables

  • @export var room_scenes : Array[PackedScene] - Array of room scenes for the dungeon. Each must inherit DungeonRoom3D.
  • @export var corridor_room_scene : PackedScene - The corridor room scene, which must be 1x1x1 in voxels and used to connect rooms.
  • @export var dungeon_size : Vector3i - Size of the dungeon in voxel units. Default is Vector3i(10, 10, 10).
  • @export var voxel_scale : Vector3 - Scale of each voxel in world units. Default is Vector3(10, 10, 10).
  • @export var generate_seed : String - Seed for dungeon generation. Leave blank for a random seed.
  • @export var generate_on_ready : bool - If true, generates the dungeon on the Node3D's ready signal. Default is true.
  • @export var max_retries : int - Maximum retries for dungeon generation. Default is 1.
  • @export var max_safe_iterations : int - Maximum iterations per stage in the generation loop. Default is 250.
  • @export var generate_threaded : bool - If true, generates the dungeon on a separate thread. Default is false.
  • @export var editor_button_generate_dungeon : bool - Button to generate the dungeon in the editor.
  • @export var abort_editor_button : bool - Button to abort the dungeon generation in the editor.
  • @export var astar_heuristic : AStarHeuristics - Heuristic for AStar algorithm. Default is AStarHeuristics.EUCLIDEAN.
  • @export var heuristic_scale : float - Scale for the heuristic used in AStar. Default is 1.0.
  • @export var corridor_cost_multiplier : float - Cost multiplier for corridors in pathfinding. Default is 0.25.
  • @export var room_cost_multiplier : float - Cost multiplier for rooms in pathfinding. Default is 0.25.
  • @export var room_cost_at_end_for_required_doors : float - Cost multiplier for rooms during final pathfinding stage. Default is 2.0.
  • @export var show_debug_in_editor : bool - If true, shows debug information in the editor. Default is true.
  • @export var show_debug_in_game : bool - If true, shows debug information in the game. Default is false.
  • @export var place_even_if_fail : bool - If true, places rooms even if generation fails. Default is false.
  • @export var visualize_generation_progress : bool - If true, visualizes generation progress. Default is false.
  • @export var hide_debug_visuals_for_all_generated_rooms : bool - If true, hides debug visuals after generation. Default is true.
  • @export var cycle_debug_draw_when_press_n : bool - If true, cycles debug draw modes when N is pressed. Default is false.
  • @export_range(0, 1000, 1, "or_greater", "suffix:ms") var visualize_generation_wait_between_iterations : int - Wait time in milliseconds between generation iterations for visualization. Default is 100.

DungeonRoom3D API

Signals

signal dungeon_done_generating()

Emitted when the DungeonGenerator3D completes its generation. You can use this signal for example to hide unused door models and replace them with walls. See the script example in addons/SimpleDungeons/sample_dungeons/with_dev_textures_rooms/corridor.tscn. The RemoveUnusedDoors node contains a script which connects to the dungeon_done_generating signal to remove the door nodes. Another example is in res://addons/SimpleDungeons/sample_dungeons/lowpoly_kit_1_rooms/corridor.gd, where we have an inherited DungeonRoom3D class, which basically does the same thing just using an alternate method, you could do either one. But in the low poly kit corridor script, we also hook the dungeon_done_generating signal to remove unused collision pieces and hide unused door/wall models.

Functions

get_grid_aabbi(include_doors : bool) -> AABBi

Returns the integer AABBi (custom helper class) for this DungeonRoom3D as it lies on the DungeonGenerator3D grid. If include_doors is true, it will expand the AABBi to include all required doors. For stair rooms, all doors are considered to be required, I feel this makes more sense for stair rooms, to encourage them to be more likely to connect, as optional doors may end up flush with the dungeon grid borders and unable to connect two floors.

get_grid_pos() -> Vector3i

Alias of get_grid_aabbi(false).position.

get_doors() -> Array

Returns an array of Door types. Door is a helper class in DungeonRoom3D. See the further description of it below for how these may be used.

get_door_nodes() -> Array

Returns an array of the Node3Ds which comprise the Door objects for the room. Every door has a corresponding Node3D prefixed by DOOR (required) or DOOR? (optional). The position of that door on the voxels of the room is dependent on that node's position within the room.

get_door_by_node(node : Node3D) -> Door

Given a door's Node3D, return the Door object. The door object has various helper functions, such as checking which other DungeonRoom3D it leads to, if any, which can be helpful for modifying the appearance of a DungeonRoom3D post generation. See below for a detailed list of functions/variables on the Door class.

Variables

  • @export var size_in_voxels : Vector3i - Size of the room in voxel units. Default is Vector3i(1, 1, 1).
  • @export var voxel_scale : Vector3 - Scale of each voxel in world units. Default is Vector3(10, 10, 10).
  • @export var min_count : int - Minimum number of this room type to spawn in the dungeon. Default is 2.
  • @export var max_count : int - Maximum number of this room type to spawn in the dungeon. Default is 5.
  • @export var is_stair_room : bool - If true, designates this room as a stair room for floor connections. Default is false.
  • @export var force_align_with_grid_button : bool - Button to align the room's position and scale with the dungeon's voxel grid in the editor.
  • @export var show_debug_in_editor : bool - If true, shows debug information in the editor. Default is true.
  • @export var show_debug_in_game : bool - If true, shows debug information in the game. Default is false.
  • @export var show_grid_aabb_with_doors : bool - If true, shows the grid's axis-aligned bounding box with doors for debugging. Default is false.

Door class

The Door class is a helper class contained inside the DungeonRoom3D.gd file. There is a difference between the 'Door' class and door nodes. Door nodes are Node3Ds prefixed with DOOR (required) or DOOR? (optional). These govern the positions of the doors in voxel space. It is also important to note a 'door' doesn't have to be strictly a door. It is just a way of marking a wall of the DungeonRoom3D as being able to be pathfinded through via the AStar algorithm, or required to be pathfinded through.

Functions

fits_other_door(other_room_door : Door) -> bool

Returns true if this door fits some other room's door.

get_room_leads_to() -> DungeonRoom3D

Returns the DungeonRoom3D this door leads to, if any. Will be null, if for example it is an optional door which does not lead to any room. In this case, you might want to hide the door model and change the collision shape of your final room.

Variables

  • local_pos : Vector3i - Door position in local voxel space (local to the room).
  • grid_pos : Vector3i - Door position in the parent DungeonGenerator3D's voxel space.
  • exit_pos_local : Vector3i - Door's exit position in local voxel space (local the room).
  • exit_pos_grid : Vector3i - Door's exit position in the parent DungeonGenerator3D's voxel space. Could maybe be used in conjunction with DungeonGenerator3D's get_room_at_pos function. But Door.get_room_leads_to is probably easier.
  • optional : bool - Whether the door is optional, or required to be connected.
  • door_node : Node3D - The placed Node3D (prefixed with DOOR or DOOR?) corresponding to the Door object.