Configuration
AstralRoomEditor has no config.yml — its behavior is entirely driven by three folders of definition files under the plugin's data folder, loaded (and reloaded, atomically per-folder) by AstralRoomEditor#loadConfiguration():
Folder | Loads | Service |
|---|---|---|
| One |
|
| One optional |
|
|
| core |
Defaults for all of these are shipped as plugin resources and copied to disk on first run (AstralRoomEditor#saveDefaultDefinitions()), only if the target file doesn't already exist.
Component definitions
Each file in components/ maps to one ComponentDefinition (Configurate @ConfigSerializable, camelCase Java fields → kebab-case YAML keys):
Key | Type | Description |
|---|---|---|
| string | The component's id — how it's referenced from a layout's |
| string | One of |
| boolean | Default |
| How the hotbar tool item is built. | |
| How the in-world preview is drawn. |
A definition is skipped entirely (with a warning logged) if id, primitive, item, or render is missing, or if primitive, render.type, or item.type names something not registered.
Strategy spec
item and render are both a strategy spec: type selects a registered strategy by name, and every other key under the block is passed through as that strategy's raw options node (no fixed schema — see each strategy's option table below).
Built-in item strategies (ComponentService's constructor registers these):
| Options | Behavior |
|---|---|---|
|
| Unbreakable item with a green |
Built-in render strategies: see Overview: component rendering for the full block-display/entity/cuboid-outline option tables.
Shipped component definitions
|
|
| Item | Render |
|---|---|---|---|---|
|
| – |
|
|
|
| – |
|
|
|
| – |
|
|
|
| – |
|
|
|
| – |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Layout and gamemode definitions
layouts/<gamemode>/ is one folder per gamemode; the folder name is the gamemode id (it is not read from YAML). Inside:
An optional
gamemode.yml(GamemodeDefinition) supplies a displaynameand defaultsaveblock. If it's absent, the gamemode's name falls back to its id, and its default save dirs becomerooms/<gamemode-id>andschematics/<gamemode-id>.Every other
.yml/.yamlfile in the folder is oneLayoutDefinition— itssaveblock is merged field-by-field with the gamemode's defaults (the layout's own keys win; anything it omits is filled from the gamemode).
GamemodeDefinition
Key | Type | Description |
|---|---|---|
| string | Display name for the gamemode. Defaults to the folder name if omitted/absent. |
| Defaults inherited by every layout in this folder. |
LayoutDefinition
Key | Type | Description |
|---|---|---|
| string | The layout's id within its gamemode — passed as |
| list\<string\> | Component ids the layout permits placing; drives which hotbar tools are given on session start. |
| list\<string\> | Component types that must be present (by type, not by session key) before |
| Overrides the gamemode's defaults field-by-field. |
A layout definition is skipped if id or save is missing/null, if save.serializer doesn't name a registered BlueprintSerializer, or if save.schematic-format isn't one of sponge_v3, sponge_v2, mcedit (case-insensitive).
Save settings
Key | Type | Default | Description |
|---|---|---|---|
| string |
| One of |
| string |
| Folder (relative to the data folder) the blueprint YAML is written into. |
| string |
| Folder (relative to the data folder) the |
| string |
| Blueprint YAML filename ( |
| list\<string\> |
| Component session keys dropped from the persisted blueprint on save (still used live, e.g. for the bounds cuboid). |
| string |
| Registered |
| string |
| Session key of the |
Shipped gamemodes and layouts
Gamemode | Layouts | Required components |
|---|---|---|
|
|
|
|
|
|
Room blueprints
A saved room is a RoomBlueprint — name, gamemode, layout, the relative schematicPath to its .schem, and a components map keyed by session key (component id, or <componentId>_<n> for id-requiring components). Unlike the definition files above, RoomBlueprint and the RoomComponent impls have no @Setting annotations, so their multi-word fields serialize as raw camelCase, not kebab-case (schematicPath, typeId — not schematic-path/type-id). It's written under <rooms-dir>/<filename>.yml by the layout's serializer:
RoomComponentTypeSerializer writes the component-type discriminator (its own explicit node("component-type") key, unrelated to the field-naming point above) so the loader can pick the right RoomComponent implementation from RoomEditorRegistries.primitives() when reading it back. Blueprint positions are stored relative to the bounds component's lower-north-east corner — BlueprintService loads every rooms/**/*.yml (recursively, so nested per-gamemode folders work) on startup/reload, and SessionService#load offsets a blueprint's components to the loading player's current location before opening a new session with them.