World Dimension Loader (WDL) 1.0.0
English README / Configuration Guide
Minecraft 1.20.1 / Forge 47.4.22 / Java 17

============================================================
0. Introduction
============================================================

World Dimension Loader (WDL) is a Forge mod that lets you register
external Minecraft worlds as dimensions that are loaded only when needed,
then enter them through configurable Gates.

Even if you register a large number of external worlds, WDL is designed
so that all of them are not kept active as ServerLevels at the same time.
Only worlds that are actually needed are mounted lazily.

This README begins with the shortest setup tutorial for:

    "Register one external world and enter it through a Gate"

After that, each configuration file and setting is explained in detail.


------------------------------------------------------------
Supported Environment
------------------------------------------------------------

Minecraft : 1.20.1
Forge     : 47.4.22
Java      : 17
Mod ID    : worlddimensionloader

Stable storage mode:
IMPORT

If AUTO is selected, WDL 1.0.0 uses the validated IMPORT path.

DIRECT is reserved for future / experimental work.
Do not use DIRECT as the stable storage mode in WDL 1.0.0.


------------------------------------------------------------
Important
------------------------------------------------------------

- Back up your worlds before adding or changing external worlds.
- WDL configuration files use TOML format.
- After changing configuration, run "/wdl scan" to reload the config
  and rebuild the external-world catalog.
- If Gate definitions are ambiguous, WDL disables the conflicting Gates
  for safety instead of choosing one based on file order.
- A DIMENSION Gate cannot send you from a WDL dimension back into that
  exact same WDL dimension.



------------------------------------------------------------
First-time users - you do NOT need to read everything
------------------------------------------------------------

You do not need to understand this entire README before using WDL.

For your first setup, only do this:

1. Install WDL and start the game/server once
2. Put one external world in WDL_custom_dimensions
3. Register that world in dimensions.toml
4. Register one Gate in gates.toml
5. Run /wdl scan and confirm READY with /wdl list
6. Build the frame and open it with a Basic Dimension Igniter

That is enough for the first successful test.

You normally do NOT need to edit common.toml for the first setup.

After one world works correctly, expand into:

- multiple dimensions
- LIST / ALL
- rarity / weight
- multiple Gate definitions on one frame
- Gate costs
- Auto-Unload


------------------------------------------------------------
Where do I install WDL and place the worlds?
------------------------------------------------------------

[SINGLEPLAYER]

WDL-1.0.0.jar:
.minecraft/mods/

Configuration:
.minecraft/config/worlddimensionloader/

External worlds:
.minecraft/WDL_custom_dimensions/


[DEDICATED SERVER]

WDL-1.0.0.jar:
server mods/ folder

Configuration:
server-root/config/worlddimensionloader/

External worlds:
server-root/WDL_custom_dimensions/


For multiplayer / dedicated-server use, install WDL on BOTH the server
and participating clients.

Using the same WDL version on the server and clients is strongly recommended.

Clients do not need their own copies of the external world folders.
The external worlds and WDL runtime lifecycle are managed by the server.


------------------------------------------------------------
Four names to understand first
------------------------------------------------------------

WDL uses several similar-looking names.

id
  WDL's internal dimension ID.
  Gate dimensions = [...] entries use this value.

folder
  The real folder name inside WDL_custom_dimensions.

display_name
  Human-readable name.

Gate id
  Unique ID of the Gate definition itself.


Example:

[[dimensions]]
id = "my_world"
display_name = "My World"
folder = "my_world"

The Gate uses:
"my_world"

The actual folder is:
WDL_custom_dimensions/my_world/


============================================================
============================================================
1. Quick Setup Tutorial
============================================================

This example registers an external world named:

    my_world

and creates an obsidian Gate that can open a path to it.


------------------------------------------------------------
STEP 0 : Pre-flight check
------------------------------------------------------------

Before starting, confirm:

- Minecraft 1.20.1
- Forge 47.4.22
- Java 17
- WDL 1.0.0
- A backup of the external world you plan to use

If the downloaded world is a ZIP archive, extract it first.

After extraction, you need:

my_world/level.dat


A very common mistake is a double folder such as:

my_world/my_world/level.dat




------------------------------------------------------------
STEP 1 : Start WDL once
------------------------------------------------------------

Put WDL in your mods folder and start Minecraft / the server once.

WDL will generate its configuration structure.

Main structure:

.minecraft/
├─ WDL_custom_dimensions/
└─ config/
   └─ worlddimensionloader/
      ├─ common.toml
      ├─ dimensions.toml
      └─ gates.toml


If WDL_custom_dimensions does not exist, WDL can create it.

On a dedicated server, the server launch directory is the game directory.
Edit the server-side config and place external worlds on the server.


------------------------------------------------------------
STEP 2 : Place the external world
------------------------------------------------------------

Put the Minecraft world you want to import inside:

.minecraft/WDL_custom_dimensions/


Example:

.minecraft/
└─ WDL_custom_dimensions/
   └─ my_world/
      ├─ level.dat
      ├─ region/
      ├─ data/
      └─ ...


Important:

level.dat must exist directly inside the my_world folder.

This nested layout will not be recognized correctly:

Incorrect:
WDL_custom_dimensions/my_world/my_world/level.dat

Correct:
WDL_custom_dimensions/my_world/level.dat


------------------------------------------------------------
STEP 3 : Register the world in dimensions.toml
------------------------------------------------------------

Open:

.minecraft/config/worlddimensionloader/dimensions.toml

and add:


[[dimensions]]
id = "my_world"
display_name = "My World"
enabled = true
folder = "my_world"
rarity = "COMMON"
weight = 100

[dimensions.destination]
prefer_anchor = true
prefer_world_spawn = true
fallback_x = 0
fallback_y = 80
fallback_z = 0
fallback_yaw = 0.0
fallback_pitch = 0.0

[dimensions.respawn]
mode = "INHERIT"

[dimensions.return_scroll]
enabled = true
xp_level_cost = 5


id:
The internal WDL dimension ID.
It must be unique.

folder:
The actual world folder name inside WDL_custom_dimensions.


------------------------------------------------------------
STEP 4 : Rescan WDL
------------------------------------------------------------

In-game, with permission level 2 or higher, run:

/wdl scan

Then run:

/wdl list


If everything is correct, the world should appear similar to:

[READY] my_world -> ...


Common statuses:

READY
  The world is available for WDL use.

DISABLED
  enabled = false in dimensions.toml.

MISSING_FOLDER
  The configured world folder does not exist.

MISSING_LEVEL_DAT
  level.dat is not present directly inside the configured world folder.

INVALID_PATH
  The configured folder resolves outside the allowed dimension root.


------------------------------------------------------------
STEP 5 : Register a Gate in gates.toml
------------------------------------------------------------

Open:

.minecraft/config/worlddimensionloader/gates.toml

and add:


[[gates]]
id = "my_world_gate"
display_name = "My World Gate"
enabled = true
gate_type = "DIMENSION"

frame_block = "minecraft:obsidian"
corner_block = "minecraft:crying_obsidian"

min_inner_width = 2
min_inner_height = 3
max_inner_width = 8
max_inner_height = 8

allowed_igniters = [
  "worlddimensionloader:basic_dimension_igniter"
]

selection_mode = "LIST"
dimensions = ["my_world"]

open_time_seconds = 10


This example does not use an activation cost.

To add an XP-level cost, append:

[[gates.costs]]
type = "XP_LEVEL"
amount = 5


After editing gates.toml, run:

/wdl scan


------------------------------------------------------------
STEP 6 : Build the Gate frame
------------------------------------------------------------

With the example above:

Corner blocks:
minecraft:crying_obsidian

Other frame blocks:
minecraft:obsidian


The smallest valid interior size is 2 x 3.

Example:

◆■■◆
■  ■
■  ■
■  ■
◆■■◆

◆ = crying_obsidian
■ = obsidian
blank = Gate interior


The Gate must be a vertical rectangle.

Larger Gates are also valid as long as their interior dimensions are
inside the configured min/max range.


------------------------------------------------------------
STEP 7 : Open the Gate with an Igniter
------------------------------------------------------------

This example allows:

worlddimensionloader:basic_dimension_igniter


For testing, you can obtain one with:

/give @s worlddimensionloader:basic_dimension_igniter


Hold the Igniter and use it on the configured Gate frame.

If the Gate is valid, WDL Portal blocks will appear inside the frame.

Entering the portal transfers you to my_world.

If my_world is not currently loaded, WDL will Lazy Mount it when needed.


------------------------------------------------------------
STEP 8 : Destination position
------------------------------------------------------------

The destination position inside a WDL dimension is normally chosen in
this order:

1. Dimensional Anchor
2. Imported world's original spawn
3. Fallback coordinates from dimensions.toml


When no Anchor has been placed yet, the imported world's spawn is normally
used first.



------------------------------------------------------------
If you reached this point successfully
------------------------------------------------------------

Your basic WDL setup is complete if all four are true:

- /wdl list shows the target as READY
- the Igniter opens the Gate
- entering the portal transfers you to the registered world
- you arrive at the imported spawn or configured destination

After that, you only need to read the detailed sections for features you
actually want to configure.


============================================================
2. Configuration File Overview
============================================================

WDL mainly uses three configuration files:


config/worlddimensionloader/
├─ common.toml
├─ dimensions.toml
└─ gates.toml


common.toml
  Global WDL settings.
  Runtime behavior, Auto-Unload, Return Scroll defaults, rarity weights, etc.

dimensions.toml
  Per-world registration.
  Folder, rarity, destination rules, respawn rules, Return Scroll rules, etc.

gates.toml
  Gate frames, Igniters, destination pools, random selection, costs, etc.


============================================================
3. common.toml Reference
============================================================

------------------------------------------------------------
[general]
------------------------------------------------------------

strict_validation = true

Controls strict validation for imported worlds.

true:
  If WDL cannot safely use the external world's world-generation data,
  it refuses the unsafe mount rather than silently replacing it with the
  host world's generator.

false:
  Some compatibility fallback behavior is allowed.
  Newly generated chunks may differ from the source world.

Recommended:
true


debug_logging = false

Enables additional WDL diagnostic logging.

Normal use:
false

Troubleshooting:
true


default_gate_open_time_seconds = 10

Default Gate open duration when a Gate definition does not explicitly
specify open_time_seconds.

Unit:
seconds


default_min_inner_width = 2
default_min_inner_height = 3
default_max_inner_width = 32
default_max_inner_height = 32

Default Gate interior-size limits when a Gate definition does not provide
its own values.

WDL 1.0.0 Gate interior limits:

Width:
2 to 32

Height:
3 to 32


------------------------------------------------------------
[paths]
------------------------------------------------------------

dimension_root_folder = "WDL_custom_dimensions"

Root folder for external worlds.

Default:

.minecraft/WDL_custom_dimensions/


You may change this folder name, but the default is recommended unless
you have a specific reason to use another location.


------------------------------------------------------------
[runtime]
------------------------------------------------------------

storage_mode = "AUTO"

Available values:

AUTO
IMPORT
DIRECT


AUTO:
In WDL 1.0.0, AUTO resolves to the validated IMPORT behavior.

IMPORT:
Prepares the external world in WDL's runtime storage and mounts it as a
dimension when needed.

DIRECT:
Reserved for future / experimental work.
Not a stable WDL 1.0.0 storage path.


max_loaded_dimensions = 4

Maximum number of live WDL dimensions allowed at the same time.

Minimum:
1

Default:
4


Important:

This is NOT a limit on the number of dimensions you can register.

Example:

Registered worlds:
300

max_loaded_dimensions:
4

WDL can still keep all 300 worlds in its catalog.
Only the number of live ServerLevels is limited.


auto_unload = false

Controls whether unused WDL dimensions are automatically unloaded.

true:
Automatically unload eligible WDL dimensions.

false:
Do not automatically unload them.


unload_delay_seconds = 300

How long a dimension must remain unload-eligible before Auto-Unload occurs.

Unit:
seconds

Minimum:
10 seconds


Example:

auto_unload = true
unload_delay_seconds = 300

means an eligible dimension will normally be unloaded after about
five minutes.


vs_remount_cooldown_ticks = 100

Safety cooldown used by the Valkyrien Skies 2.4.11 same-ID remount
compatibility path.

Unit:
ticks

20 ticks is approximately 1 second.

Default:
100 ticks, approximately 5 seconds

Minimum:
20


If you use Valkyrien Skies, do not reduce this aggressively without a
specific testing reason.


------------------------------------------------------------
[respawn]
------------------------------------------------------------

mode = "OVERWORLD"

Available values:

OVERWORLD
VANILLA


OVERWORLD:
When a player dies inside a WDL imported dimension, WDL redirects
respawn to the Overworld.

VANILLA:
WDL does not override normal respawn behavior.


prefer_overworld_player_spawn = true

When OVERWORLD mode is active, prefer the player's valid personal spawn
in the Overworld.


fallback_to_overworld_world_spawn = true

If the personal spawn cannot be used, fall back to the Overworld world spawn.


------------------------------------------------------------
[return_scroll]
------------------------------------------------------------

default_xp_level_cost = 5

Default Return Scroll XP-level cost.

This is an XP LEVEL cost, not raw XP points.

0:
Free

5:
Consumes 5 XP levels


This value may be overridden per dimension in dimensions.toml.


------------------------------------------------------------
[rarity_weights]
------------------------------------------------------------

Default values:

COMMON = 100
UNCOMMON = 60
RARE = 25
EPIC = 10
LEGENDARY = 3


These values are used by DIMENSION Gate LIST / ALL weighted random selection.

Higher numbers mean a dimension is more likely to be selected.

0:
Excluded from weighted random selection.


Example:

COMMON = 100
LEGENDARY = 3

makes LEGENDARY dimensions much less likely to be selected than COMMON ones.

These values are weights, not direct percentages.

The actual probability depends on the combined effective weight of every
eligible dimension in the current Gate pool.


============================================================
4. dimensions.toml Reference
============================================================

Create one [[dimensions]] block for each external world.


Basic example:


[[dimensions]]
id = "ancient_city"
display_name = "Ancient City"
enabled = true
folder = "ancient_city"
rarity = "RARE"
weight = 25

[dimensions.destination]
prefer_anchor = true
prefer_world_spawn = true
fallback_x = 0
fallback_y = 80
fallback_z = 0
fallback_yaw = 0.0
fallback_pitch = 0.0

[dimensions.respawn]
mode = "INHERIT"

[dimensions.return_scroll]
enabled = true
xp_level_cost = 10


------------------------------------------------------------
id
------------------------------------------------------------

Example:

id = "ancient_city"

Unique WDL internal ID.

Do not register multiple dimensions with the same ID.

Gate dimensions = [...] lists use this ID.


------------------------------------------------------------
display_name
------------------------------------------------------------

Example:

display_name = "Ancient City"

Human-readable display name.


------------------------------------------------------------
enabled
------------------------------------------------------------

enabled = true

true:
Enabled and available when valid.

false:
Stored in the catalog as DISABLED and normally unavailable for gameplay.


------------------------------------------------------------
folder
------------------------------------------------------------

folder = "ancient_city"

Folder path relative to common.toml's dimension_root_folder.

Example:

dimension_root_folder = "WDL_custom_dimensions"
folder = "ancient_city"

Actual location:

.minecraft/WDL_custom_dimensions/ancient_city/


------------------------------------------------------------
rarity
------------------------------------------------------------

Supported values:

COMMON
UNCOMMON
RARE
EPIC
LEGENDARY
CUSTOM


When no explicit per-dimension weight is set, WDL uses the matching
common.toml rarity weight.

CUSTOM has no standard rarity weight entry in common.toml.

If you use CUSTOM in random Gate selection, explicitly setting weight
is recommended.


------------------------------------------------------------
weight
------------------------------------------------------------

Example:

weight = 25

Per-dimension Gate-selection weight.

If an explicit weight exists, it overrides rarity_weights.

0:
Excluded from weighted random selection.


If weight is omitted:

rarity
  ↓
common.toml [rarity_weights]
  ↓
effective weight


------------------------------------------------------------
[dimensions.destination]
------------------------------------------------------------

Controls arrival-location selection.


prefer_anchor = true

If true, a registered Dimensional Anchor is the highest-priority destination.


prefer_world_spawn = true

If no Anchor is used, prefer the imported world's original spawn point.


fallback_x = 0
fallback_y = 80
fallback_z = 0

Fallback coordinates when Anchor / World Spawn are not used or unavailable.


fallback_yaw = 0.0
fallback_pitch = 0.0

Player orientation when fallback coordinates are used.


Normal destination priority:

1. Dimensional Anchor
2. Imported world spawn
3. fallback_x/y/z


------------------------------------------------------------
[dimensions.respawn]
------------------------------------------------------------

mode = "INHERIT"

Available values:

INHERIT
OVERWORLD
VANILLA


INHERIT:
Use common.toml [respawn].

OVERWORLD:
Force WDL Overworld respawn behavior for this dimension.

VANILLA:
Do not apply WDL's respawn override in this dimension.


------------------------------------------------------------
[dimensions.return_scroll]
------------------------------------------------------------

enabled = true

true:
Return Scroll may be used in this dimension.

false:
Return Scroll is sealed / disabled in this dimension.


xp_level_cost = 5

Per-dimension Return Scroll cost.

0:
Free

Omitted:
Use common.toml default_xp_level_cost.


============================================================
5. gates.toml Reference
============================================================

Create one [[gates]] block per Gate definition.


Basic example:


[[gates]]
id = "city_gate"
display_name = "City Gate"
enabled = true
gate_type = "DIMENSION"

frame_block = "minecraft:obsidian"
corner_block = "minecraft:crying_obsidian"

min_inner_width = 2
min_inner_height = 3
max_inner_width = 8
max_inner_height = 8

allowed_igniters = [
  "worlddimensionloader:basic_dimension_igniter"
]

selection_mode = "LIST"
dimensions = ["ancient_city", "giant_city"]

open_time_seconds = 10


------------------------------------------------------------
id
------------------------------------------------------------

Unique Gate-definition ID.

Do not reuse the same Gate ID.


------------------------------------------------------------
display_name
------------------------------------------------------------

Human-readable Gate name.


------------------------------------------------------------
enabled
------------------------------------------------------------

true:
Active.

false:
Excluded from the Gate Resolver.


------------------------------------------------------------
gate_type
------------------------------------------------------------

Available values:

DIMENSION
RETURN


DIMENSION:
Travels to registered WDL dimensions.

RETURN:
Returns to the Overworld.


------------------------------------------------------------
frame_block
------------------------------------------------------------

Example:

frame_block = "minecraft:obsidian"

Block ID used for the Gate edges.


------------------------------------------------------------
corner_block
------------------------------------------------------------

Example:

corner_block = "minecraft:crying_obsidian"

Block ID used for the four corners.

frame_block and corner_block may use the same block if desired.


------------------------------------------------------------
min_inner_width / max_inner_width
------------------------------------------------------------

Allowed Gate interior-width range.

Limits:
2 to 32


------------------------------------------------------------
min_inner_height / max_inner_height
------------------------------------------------------------

Allowed Gate interior-height range.

Limits:
3 to 32


------------------------------------------------------------
allowed_igniters
------------------------------------------------------------

List of item IDs that may activate the Gate.

Example:


allowed_igniters = [
  "worlddimensionloader:basic_dimension_igniter",
  "worlddimensionloader:advanced_dimension_igniter"
]


Built-in WDL Igniters:

worlddimensionloader:basic_dimension_igniter
worlddimensionloader:advanced_dimension_igniter
worlddimensionloader:creative_dimension_igniter


If allowed_igniters is empty, WDL's three standard Igniters are allowed.


------------------------------------------------------------
selection_mode
------------------------------------------------------------

Used by DIMENSION Gates.

Available values:

LIST
ALL


LIST:
Only dimension IDs listed in dimensions = [...] are considered.

ALL:
All eligible dimensions in the WDL catalog are considered.


------------------------------------------------------------
dimensions
------------------------------------------------------------

Used by LIST mode.

Example:

dimensions = [
  "world_a",
  "world_b",
  "world_c"
]


Each entry must match an id from dimensions.toml.


------------------------------------------------------------
open_time_seconds
------------------------------------------------------------

Example:

open_time_seconds = 10

Keeps the Gate open for 10 seconds.


open_time_seconds = -1

Creates a permanent Gate session.


Valid values:

-1
or
1 and above


0 and values below -1 are invalid.


============================================================
6. Random Selection / Rarity / Weight
============================================================

A single DIMENSION Gate can contain multiple candidate dimensions and
choose between them using weighted random selection.


Example:


[[gates]]
id = "random_gate"
display_name = "Random Gate"
enabled = true
gate_type = "DIMENSION"

frame_block = "minecraft:obsidian"
corner_block = "minecraft:crying_obsidian"

min_inner_width = 2
min_inner_height = 3
max_inner_width = 8
max_inner_height = 8

allowed_igniters = [
  "worlddimensionloader:basic_dimension_igniter"
]

selection_mode = "LIST"
dimensions = [
  "normal_world",
  "rare_world",
  "legendary_world"
]

open_time_seconds = 10


dimensions.toml:


[[dimensions]]
id = "normal_world"
...
rarity = "COMMON"

[[dimensions]]
id = "rare_world"
...
rarity = "RARE"

[[dimensions]]
id = "legendary_world"
...
rarity = "LEGENDARY"


With the default common.toml weights:

COMMON    = 100
RARE      = 25
LEGENDARY = 3

those are the values used for weighted selection.


------------------------------------------------------------
Explicit weight override
------------------------------------------------------------

Even if a dimension is LEGENDARY:

weight = 50

makes its effective Gate-selection weight 50.

Explicit per-dimension weight overrides rarity.


------------------------------------------------------------
The current dimension is automatically excluded
------------------------------------------------------------

Example:

Current location:
world_a

Gate pool:
dimensions = ["world_a", "world_b", "world_c"]

Actual candidates:

world_b
world_c


world_a is removed before weighted selection.

This prevents a Gate from being used as a same-dimension spawn warp.


If LIST contains only:

dimensions = ["world_a"]

while the player is already inside world_a, the Gate will not open.

The failed activation does not consume Gate costs or the Igniter.


============================================================
7. Multiple Gate Definitions on the Same Physical Frame
============================================================

WDL 1.0.0 allows multiple Gate definitions to share the same
frame_block / corner_block configuration.

For example, the exact same physical frame can behave like:

Basic Igniter
  → Gate A
  → Random selection from world_a / world_b

Advanced Igniter
  → Gate B
  → Random selection from world_c / world_d


Example:


[[gates]]
id = "basic_pool"
enabled = true
gate_type = "DIMENSION"

frame_block = "minecraft:obsidian"
corner_block = "minecraft:crying_obsidian"

min_inner_width = 2
min_inner_height = 3
max_inner_width = 8
max_inner_height = 8

allowed_igniters = [
  "worlddimensionloader:basic_dimension_igniter"
]

selection_mode = "LIST"
dimensions = ["world_a", "world_b"]

open_time_seconds = 10


[[gates]]
id = "advanced_pool"
enabled = true
gate_type = "DIMENSION"

frame_block = "minecraft:obsidian"
corner_block = "minecraft:crying_obsidian"

min_inner_width = 2
min_inner_height = 3
max_inner_width = 8
max_inner_height = 8

allowed_igniters = [
  "worlddimensionloader:advanced_dimension_igniter"
]

selection_mode = "LIST"
dimensions = ["world_c", "world_d"]

open_time_seconds = 10


Because the Igniters are different, WDL can resolve the Gate definition
unambiguously.


------------------------------------------------------------
Gate definition conflict rules
------------------------------------------------------------

Two enabled Gate definitions are ambiguous when all of the following overlap:

- same frame_block
- same corner_block
- overlapping width range
- overlapping height range
- at least one shared allowed_igniter


WDL does NOT use "first definition wins" or config order.

For safety, conflicting Gate definitions are excluded from the runtime Gate list.

The log contains:

WDL GATE_CONFIG_AMBIGUOUS


Example:

Gate A:
Width 2 to 8
Basic Igniter

Gate B:
Width 2 to 8
Basic Igniter

Same frame / corner

→ Ambiguous


But:

Gate A:
Basic Igniter

Gate B:
Advanced Igniter

→ Valid, because the Igniters differ.


Or:

Gate A:
Width 2 to 4

Gate B:
Width 6 to 8

Same Igniter

→ Valid, because the size ranges do not overlap.


Important:

Even if one Gate is DIMENSION and the other is RETURN,
they are still considered ambiguous when their physical activation
conditions and Igniter overlap.


============================================================
8. Gate Cost Reference
============================================================

A Gate may require multiple costs.

WDL validates all costs first.
Only after the activation is confirmed does it consume the transaction.

This prevents partial payment when another Gate condition fails.


Supported cost types:

ITEM
XP_LEVEL
XP_POINTS
HEALTH
HUNGER


------------------------------------------------------------
ITEM
------------------------------------------------------------

Fixed amount:


[[gates.costs]]
type = "ITEM"
item = "minecraft:ender_pearl"
amount_mode = "FIXED"
amount = 2


Random amount range:


[[gates.costs]]
type = "ITEM"
item = "minecraft:ender_pearl"
amount_mode = "RANGE"
min = 1
max = 3


With RANGE, the required amount is selected between min and max for each
activation.


------------------------------------------------------------
XP_LEVEL
------------------------------------------------------------

[[gates.costs]]
type = "XP_LEVEL"
amount = 5


Consumes 5 XP levels.


------------------------------------------------------------
XP_POINTS
------------------------------------------------------------

[[gates.costs]]
type = "XP_POINTS"
amount = 100


Consumes raw XP points.

XP_POINTS and XP_LEVEL are different cost types.


------------------------------------------------------------
HEALTH
------------------------------------------------------------

[[gates.costs]]
type = "HEALTH"
amount = 4


Subtracts Health from the player.

For safety, WDL refuses the activation if paying the cost would reduce the
player to 0 Health or below.

In normal Minecraft terms:

2 Health = 1 heart

So:

amount = 4

normally equals 2 hearts.


------------------------------------------------------------
HUNGER
------------------------------------------------------------

[[gates.costs]]
type = "HUNGER"
amount = 4


Subtracts from the player's Food Level.

Normal Minecraft maximum Food Level is 20.


------------------------------------------------------------
Multiple costs
------------------------------------------------------------

Example:


[[gates.costs]]
type = "XP_LEVEL"
amount = 5

[[gates.costs]]
type = "ITEM"
item = "minecraft:ender_pearl"
amount_mode = "FIXED"
amount = 2


This Gate requires both:

5 XP levels
+
2 ender pearls


============================================================
9. RETURN Gate
============================================================

A RETURN Gate sends the player back to the Overworld.


Example:


[[gates]]
id = "return_gate_default"
display_name = "Return Gate"
enabled = true
gate_type = "RETURN"

frame_block = "minecraft:stone_bricks"
corner_block = "minecraft:emerald_block"

min_inner_width = 2
min_inner_height = 3
max_inner_width = 32
max_inner_height = 32

allowed_igniters = [
  "worlddimensionloader:basic_dimension_igniter",
  "worlddimensionloader:advanced_dimension_igniter",
  "worlddimensionloader:creative_dimension_igniter"
]

open_time_seconds = -1

[[gates.costs]]
type = "ITEM"
item = "minecraft:emerald"
amount_mode = "FIXED"
amount = 1


open_time_seconds = -1 creates a permanent Gate.

However, even permanent Gates are closed if their required frame or
portal structure becomes invalid.


============================================================
10. Gate Lifecycle / Broken Gate Handling
============================================================

While a Gate is OPEN, WDL validates the loaded frame, corner, and portal
structure.

Examples of invalidating changes:

- breaking a required frame_block
- breaking a corner_block
- removing or replacing a WDL Portal block


When this happens:

Portal removed
→ Active Gate Session cleared
→ Gate fully closed


WDL also revalidates stale OPEN states when an Igniter is used.

This prevents a broken portal from leaving an invisible "already open"
session that can never be reopened.

After restoring a valid frame, the same Gate can be activated again.


============================================================
11. Dimensional Anchor
============================================================

Item ID:

worlddimensionloader:dimensional_anchor


Use it inside a WDL imported dimension to store the current position and
orientation as the destination Anchor for that dimension.

Future transfers to that dimension prefer the Anchor first.


Normal use:
Register the current position as the Anchor.

Shift-use:
Remove the Anchor for that dimension.


An Anchor cannot be registered in the Overworld or arbitrary non-WDL
dimensions.


View registered Anchors:

/wdl anchors


============================================================
12. Return Scroll
============================================================

Item ID:

worlddimensionloader:return_scroll


The Return Scroll returns the player to the Overworld from an eligible
WDL imported dimension.

It cannot be used in the Overworld.


Cost selection:

dimensions.toml contains xp_level_cost
  ↓
use the per-dimension value

otherwise
  ↓
common.toml default_xp_level_cost


Creative Mode:
XP-level cost is waived.


In dimensions.toml:

[dimensions.return_scroll]
enabled = false

seals the Return Scroll in that dimension.


============================================================
13. Respawn Configuration
============================================================

common.toml:

[respawn]
mode = "OVERWORLD"
prefer_overworld_player_spawn = true
fallback_to_overworld_world_spawn = true


With OVERWORLD mode, death inside a WDL imported dimension uses:

1. Valid personal Overworld spawn
2. Overworld world spawn fallback


Per dimension, you may use:

[dimensions.respawn]
mode = "INHERIT"

OVERWORLD

VANILLA


============================================================
14. Registering Many External Worlds
============================================================

WDL separates:

"number of registered dimensions"

from:

"number of currently live ServerLevels"


For example:

WDL_custom_dimensions/
├─ world_001/
├─ world_002/
├─ world_003/
├─ ...
└─ world_300/

does not mean all 300 worlds are kept active as ServerLevels.


Basic architecture:

DimensionCatalog
  ↓
lightweight config / path / status data

Only when needed:
  ↓
Lazy Mount
  ↓
ServerLevel


The live-dimension limit is controlled by:

[runtime]
max_loaded_dimensions = 4


To automatically unload unused dimensions:

[runtime]
auto_unload = true
unload_delay_seconds = 300


============================================================
15. WDL Commands
============================================================

Most WDL commands require permission level 2 or higher.


/wdl scan

Reloads WDL configuration and rescans the external-world catalog.

This is the most useful command after editing configuration files.


/wdl list

Shows catalog dimensions and their current status.


/wdl status

Shows summary information such as catalog count, READY count,
loaded count, and runtime settings.


/wdl anchors

Lists registered Dimensional Anchors.


/wdl loaded

Shows runtime states such as:

STAGING
STAGED
LOADED
MOUNT-QUEUED
UNLOAD-QUEUED
VS-CLEANUP


/wdl load <id>

Prepares an external world for runtime use.


/wdl mount <id>

Mounts a prepared WDL dimension as a ServerLevel.


/wdl unload <id>

Unloads the specified WDL dimension.


/wdl tp <id>

Teleports directly to an already mounted WDL dimension.

Mainly intended for administration and testing.


/wdl probe <id>

Shows internal runtime diagnostic information.


In normal gameplay, Gates perform Lazy Mount automatically.
You do not need to manually use /wdl load or /wdl mount every time.



============================================================
16. Built-in WDL Items / Survival Recipes
============================================================

WDL 1.0.0 includes standard items for opening Gates, fixing arrival
positions, and returning to the Overworld.


------------------------------------------------------------
Basic Dimension Igniter
------------------------------------------------------------

ID:
worlddimensionloader:basic_dimension_igniter

Purpose:
Basic Gate activation item.

Stack size:
Up to 16

Consumption:
One Basic Igniter is consumed after a Gate successfully opens.


Crafting:

[ ][A][ ]
[E][F][E]
[ ][A][ ]

A = Amethyst Shard
E = Ender Pearl
F = Flint and Steel


Test command:

/give @s worlddimensionloader:basic_dimension_igniter


------------------------------------------------------------
Advanced Dimension Igniter
------------------------------------------------------------

ID:
worlddimensionloader:advanced_dimension_igniter

Purpose:
Reusable higher-tier Igniter.

Maximum durability:
100

Consumption:
Loses 1 durability after a successful Gate opening.


Crafting:

[ ][D][ ]
[N][S][N]
[ ][D][ ]

D = Diamond
N = Nether Star
S = Basic Dimension Igniter


------------------------------------------------------------
Creative Dimension Igniter
------------------------------------------------------------

ID:
worlddimensionloader:creative_dimension_igniter

Purpose:
Creative / administration / testing.

Crafting:
No recipe

Uses:
Unlimited


Example command:

/give @s worlddimensionloader:creative_dimension_igniter


Important:
allowed_igniters may explicitly reference non-WDL item IDs.

WDL 1.0.0 automatically consumes/damages only its built-in
Basic and Advanced Igniters.

The Creative Igniter is unlimited.
Other explicitly allowed third-party items are not automatically consumed
or damaged by WDL.


------------------------------------------------------------
Dimensional Anchor
------------------------------------------------------------

ID:
worlddimensionloader:dimensional_anchor

Purpose:
Stores a preferred arrival position for a WDL imported dimension.

Consumption:
Not consumed.


Crafting:

[ ][A][ ]
[E][C][E]
[ ][A][ ]

A = Amethyst Shard
E = Eye of Ender
C = Compass


Normal use:
Store current position + yaw / pitch.

Shift-use:
Remove the Anchor for the current WDL dimension.


------------------------------------------------------------
Return Scroll
------------------------------------------------------------

ID:
worlddimensionloader:return_scroll

Purpose:
Return to the Overworld.

Crafting:
Shapeless

Book x1
Emerald x1

Consumption:
The Return Scroll item itself is reusable and is not consumed.

XP cost:
Configured through common.toml or dimensions.toml.


Important:
In the WDL 1.0.0 implementation, the Return Scroll is rejected in the
Overworld and attempts an Overworld return from other dimensions.

For WDL imported dimensions, dimensions.toml-specific Return Scroll rules
(enabled / xp_level_cost) are applied.


============================================================
17. Common Configuration Examples
============================================================

------------------------------------------------------------
Example 1 : Fixed connection to one world
------------------------------------------------------------

selection_mode = "LIST"
dimensions = ["world_a"]


------------------------------------------------------------
Example 2 : Random selection from three worlds
------------------------------------------------------------

selection_mode = "LIST"
dimensions = ["world_a", "world_b", "world_c"]


Selection uses each dimension's effective rarity / weight.


------------------------------------------------------------
Example 3 : Random selection from all eligible dimensions
------------------------------------------------------------

selection_mode = "ALL"


WDL considers enabled, READY dimensions with positive effective weight.

The current WDL dimension is automatically excluded.


------------------------------------------------------------
Example 4 : Rare dimension
------------------------------------------------------------

dimensions.toml:

[[dimensions]]
id = "secret_world"
rarity = "LEGENDARY"


common.toml:

LEGENDARY = 3


------------------------------------------------------------
Example 5 : Override rarity with explicit weight
------------------------------------------------------------

[[dimensions]]
id = "special_world"
rarity = "LEGENDARY"
weight = 50


The effective weight is 50.


------------------------------------------------------------
Example 6 : Use different Igniters on the same frame
------------------------------------------------------------

Same physical frame:

Basic Igniter
  → normal dimension pool

Advanced Igniter
  → rare dimension pool


Make sure the allowed_igniters rules remain unambiguous.


============================================================
18. Troubleshooting
============================================================

------------------------------------------------------------
The Gate does not open
------------------------------------------------------------

Check:

1. Run /wdl scan
2. Run /wdl list
3. Confirm the destination dimension is READY
4. Confirm frame_block / corner_block
5. Confirm Gate interior size is inside the configured range
6. Confirm the held Igniter is in allowed_igniters
7. Confirm you can pay all configured costs
8. In LIST mode, confirm dimensions contains valid WDL IDs
9. Confirm the current dimension is not the only remaining candidate
10. Check latest.log for GATE_CONFIG_AMBIGUOUS


------------------------------------------------------------
MISSING_FOLDER
------------------------------------------------------------

Check that dimensions.toml folder matches the real folder name inside
WDL_custom_dimensions.


------------------------------------------------------------
MISSING_LEVEL_DAT
------------------------------------------------------------

Confirm level.dat exists directly inside the configured external world folder.


------------------------------------------------------------
Gate definitions are conflicting
------------------------------------------------------------

Search latest.log for:

WDL GATE_CONFIG_AMBIGUOUS


To resolve a conflict between two Gates:

- use different Igniters
or
- separate their valid size ranges
or
- use different frame / corner blocks


------------------------------------------------------------
I am worried about newly generated chunks
------------------------------------------------------------

Normally use:

strict_validation = true


WDL is designed to read the source world's WorldGenSettings / LevelStem
so newly generated chunks continue using the imported world's generator.

Keeping strict_validation=true is recommended if you do not want WDL to
fall back to the host world's generator when source world-generation data
cannot be safely decoded.


------------------------------------------------------------
I registered many worlds and want to reduce memory usage
------------------------------------------------------------

Example:

[runtime]
max_loaded_dimensions = 4
auto_unload = true
unload_delay_seconds = 300


Registered-world count and live-dimension count are separate.

There is usually no reason to make max_loaded_dimensions extremely large.



------------------------------------------------------------
Dedicated server config changes are not taking effect
------------------------------------------------------------

Check:

1. You edited the SERVER config, not only the client config
2. You edited server-root/config/worlddimensionloader/
3. External worlds are in server-root/WDL_custom_dimensions/
4. You ran /wdl scan on the server
5. /wdl list reflects the expected status


------------------------------------------------------------
Multiplayer connection problems / missing WDL items
------------------------------------------------------------

Install WDL on both the server and participating clients.

Avoid version mismatches.
Using the same WDL 1.0.0.jar on both sides is recommended.


============================================================
19. Recommended Initial Settings
============================================================

For a first setup, the following conservative settings are recommended:


[general]
strict_validation = true
debug_logging = false

[paths]
dimension_root_folder = "WDL_custom_dimensions"

[runtime]
storage_mode = "AUTO"
max_loaded_dimensions = 4
auto_unload = false
unload_delay_seconds = 300
vs_remount_cooldown_ticks = 100

[respawn]
mode = "OVERWORLD"
prefer_overworld_player_spawn = true
fallback_to_overworld_world_spawn = true

[return_scroll]
default_xp_level_cost = 5

[rarity_weights]
COMMON = 100
UNCOMMON = 60
RARE = 25
EPIC = 10
LEGENDARY = 3


After confirming normal operation with a larger collection of worlds,
you may enable:

auto_unload = true


============================================================
20. Important WDL 1.0.0 Behavior Summary
============================================================

- Place external worlds in WDL_custom_dimensions.
- Register one [[dimensions]] entry per external world.
- Gate behavior is fully configurable through gates.toml.
- Both LIST and ALL selection modes are supported.
- Weighted random selection supports rarity and explicit weight.
- Explicit weight overrides rarity.
- Weight 0 removes a dimension from random selection.
- The current WDL dimension is excluded from DIMENSION Gate candidates.
- Multiple Gate definitions may share the same physical frame.
- Gate resolution uses physical frame size + Igniter.
- Ambiguous Gate definitions are disabled for safety.
- Gate costs are consumed only after validation succeeds.
- Breaking a Gate frame / portal clears the active session.
- Stale OPEN sessions self-repair.
- Dimensional Anchor can be the highest-priority arrival point.
- Return Scroll supports per-dimension cost and sealing.
- Respawn may be redirected to the Overworld.
- Registered dimension count is separated from live ServerLevel count.
- IMPORT is the stable WDL 1.0.0 storage path.
- AUTO uses IMPORT behavior in WDL 1.0.0.
- DIRECT is reserved for future / experimental work.


============================================================
21. Final Notes
============================================================

WDL is designed for setups where many external worlds are registered,
but only the dimensions that are actually needed are mounted at runtime.

If you are new to WDL, you do not need to understand every section before starting.
Complete the Section 1 tutorial with one world first, then return to the detailed
reference only when you need additional features.

For the easiest setup process, begin with:

1 world
+
1 Gate

Then expand gradually into:

- multiple dimensions
- LIST random selection
- ALL selection
- rarity / weight
- multiple Gate definitions on one frame
- Gate costs
- Auto-Unload


When troubleshooting, begin with:

/wdl scan
/wdl list
/wdl status
/wdl loaded


Then inspect latest.log / debug.log if necessary.


World Dimension Loader (WDL) 1.0.0
End of English README
