English
Structure Templates
A structure template is a vanilla .nbt structure file stored at plugins/EmakiStructure/structures/<name>.nbt. You use the same template in three places: placing it (place), previewing it in place (get), and replacing vanilla structures (replace_rules)
Selection and highlight
- Two-corner selection:
/ems select pos1and/ems select pos2record your current position as the first / second corner; both corners must be in the same world - Once ready, the game shows the coordinates and size (
X × Y × Z) and outlines the region with glowingBlockDisplayentities (12 edges plus corner markers), visible within view distance and destroyed when you leave the world or the session times out - Use
select adjustto nudge the box by direction; useselect clearto remove the selection and its highlight - An idle selection ends automatically after
selection.session_timeout(default30m); on timeout the highlight is destroyed and the session released - The selection is limited by
generate.size_limitand rejected beyond it (error.selection.too_large)
Export validation
When you run /ems structure export <name>, the plugin validates each check before writing the file; if any check fails, it rejects the export and tells you why:
| Check | Error key |
|---|---|
| Name is lowercase letters, digits, underscore, hyphen; starts with a letter or digit; length ≤ 64 | error.name.invalid |
Selection within generate.size_limit and the export limit | error.export.too_large |
| At least one exportable block in the selection | error.export.no_blocks |
Raw file ≤ template.import_max_file_bytes (default 32 MiB) | error.template.file_too_large |
Palette ≤ template.palette_limit (default 4096) | error.template.palette_exceeded |
Each block-entity payload ≤ template.block_entity_max_bytes (default 64 KiB) | error.template.block_entity_too_large |
Unresolvable block states handled per template.legacy_policy (reject whole file / skip and place air) | error.template.legacy_block_rejected, console.template_legacy_skipped |
A successful export echoes block count, size, furniture entry count (with out-of-bounds skips), and the file path. The file is written in one shot — no temp-file round-trip
Placement
When you run /ems structure place <template> <facing>, the plugin works through the following steps in order:
- Template and size check: missing template reports
error.template.not_found; a size overgenerate.size_limitreportserror.generate.rejected_by_limit - Journal: create the
journal/snapshot log; if it cannot be created the generation is rejected (error.generate.journal_failed) - Ground support: evaluated per
generate.ground_mode(see Configuration); failing reportserror.generate.ground_unsupportedand aborts - Queued write: blocks are written across ticks under
generate.max_blocks_per_tick, subject to the queue timeout (generate.queue_timeout) and TPS-adaptive throttling; a timeout aborts (error.generate.queue_timeout) and rolls back - Entities and mobs: template entities follow
generate.entity_policy, thenspawns/companion file entries run - Settle: success echoes position, facing, and overwritten block count; trapped players get an exit hint (
error.generate.player_trapped)
Interrupted generation (reload / stop / mid-run) is recovered by transaction rollback: at startup, any uncommitted journal is rolled back first and generation stays unavailable until that finishes (console.rollback_recovering / console.rollback_recovered). A transaction that cannot be fully rolled back is renamed rollback-partial and is not retried automatically; you can inspect it with /ems debug
/ems get <template> [facing] simply puts a temporary copy 3 blocks in front of you, so you can check that the position and facing look right
Mob spawn companion file
The mob spawn companion file binds a set of "spawn this mob at this spot" entries to one specific structure template. The file lives at plugins/EmakiStructure/spawns/<template>.yml, where <template> must match structures/<template>.nbt exactly; when you place that template, the plugin picks up the file by name automatically
- One-to-one binding, no shared file: placing
castle.nbtreads onlyspawns/castle.yml; without a matching file no spawn points run, another structure's points are never reused, and there is no global spawn file - Coordinate system:
pos/regionuse template-local coordinates whose origin is the minimum corner of the selection at export time; each axis must fall in[0, sizeX)/[0, sizeY)/[0, sizeZ); convert with local = world − selection minimum corner (a successful export echoes the size, andselectechoes both corners) - Facing follows the structure: points rotate with the structure's facing (same transform as block placement), so mobs land at the matching position under any cardinal or mirrored facing; a
facingfield stacks on top of the structure's facing - When it runs: executed in the settle stage after blocks and furniture are placed, on every placement of that structure (no cooldown); spawned mobs join the transaction journal and are removed on rollback
- Applying changes: parsed results are cached, so run
/ems reloadafter creating or editing a spawn file; re-exporting the same structure with/ems structure exportrefreshes the spawn and furniture caches automatically
Configuration example
spawns/castle.yml (for structures/castle.nbt):
yaml
version: 1 # always 1, not validated today
enabled: true # false disables the whole file
spawns:
- type: "minecraft:skeleton" # namespace prefix required
pos: [4, 1, 4] # fixed point (template-local coordinates)
count: 2 # 1-16
chance: 1.0 # 0.0-1.0, evaluated once per entry
facing: "north" # north/south/east/west, optional
level: 5 # optional, used by mythicmobs: types only
- type: "minecraft:zombie"
pos: [6, 1, 6] # only pos entries can use radius
radius: 3 # 0-64, random point inside a sphere around pos; the sphere must fit in the template
count: 3
- type: "emakimobs:elite_zombie"
region: # random point inside the region; min <= max and inside the template
min: [0, 1, 0]
max: [15, 1, 15]
count: 4 # radius in a region entry is ignoredParameters
| Field | Type | Required | Range | Description |
|---|---|---|---|---|
version | int | No | 1 | Reserved field, not validated today |
enabled | boolean | No | true / false | File-level switch, defaults to true; false disables the whole file |
spawns[].type | string | Yes | minecraft: / mythicmobs: / emakimobs: prefix | Mob type; the latter two need the matching plugin present, otherwise the entry fails with a warning |
spawns[].pos | list<int> | One of pos / region | Inside the template per axis | Fixed point in local coordinates; exactly one of pos or region must be given |
spawns[].region | map | One of pos / region | min / max of 3 ints, min <= max and inside the template | Random point in region, mutually exclusive with pos |
spawns[].radius | int | No | 0–64 | Valid for pos entries only: random point inside a sphere around pos, the sphere must fit in the template; ignored in region entries |
spawns[].count | int | Yes | 1–16 | Number of mobs produced by this entry |
spawns[].chance | double | No | 0.0–1.0, default 1.0 | Entry-level roll, evaluated once: on a miss the whole count is skipped, never a partial spawn |
spawns[].facing | string | No | north / south / east / west | Mob facing, stacked with the structure's facing; omitted means the structure's facing |
spawns[].level | int | No | Integer | Mob level, passed through for mythicmobs: types only |
Limits and interactions
| Item | Description |
|---|---|
spawn.enabled: false | Master switch in the main config; spawns/ is then ignored entirely (no load, no warning) while template entities are unaffected |
spawn.max_per_generation (default 32) | Cap on total point mobs per placement; exceeding it rejects the whole file with a warning (error.spawn.rejected) |
spawn.batch_per_tick (default 8) | Spawn batches per tick; the rest queues to the next tick |
generate.entity_policy: none | Disables the spawn companion file as well: the companion file shares this policy with template entities, so nothing spawns even with spawn.enabled: true |
generate.entity_policy: passive | Vanilla hostile mobs are removed right after spawning; whether third-party mobs (mythicmobs: / emakimobs:) follow suit is decided by spawn.respect_entity_policy (false lets them through, true skips them) |
| Rollback | Point mobs are written to the transaction journal and removed when a generation is rolled back |
Common issues and errors
| Symptom | Cause and fix | Error key |
|---|---|---|
| No mobs after placement and nothing in the console | No matching spawns/<template>.yml, or spawn.enabled: false, or generate.entity_policy: none | — |
| Edits to the spawn file have no effect | Parsed results are cached; run /ems reload (or re-export the same structure) | — |
| Point rejected as out of bounds | pos outside the template's local size; check the echoed size and the selection minimum corner | error.spawn.pos_out_of_bounds |
| Whole file rejected | Total count over spawn.max_per_generation, or an illegal file name | error.spawn.total_exceeded / error.name.invalid |
| An entry is skipped | Per-entry warning with the reason (missing type, bad prefix, pos and region both given or both missing, count / chance / facing / radius out of range, region order or bounds) | console.spawn_entry_issue plus error.spawn.* |
| An entry fails to spawn | Dependency plugin missing, or the world rules rejected the spawn | console.spawn_entry_failed |
WARNING
Re-exporting a template under the same name changes its size; old spawn points are not shifted automatically — update the coordinates in spawns/<template>.yml whenever the template size changes
Furniture companion file
furniture/<template>.yml is written by four-source furniture recognition (ItemsAdder / Oraxen / Nexo / CraftEngine) during export: the plugin detects furniture placed by those four plugins, skips anything outside the selection, and counts it in the export echo as "out-of-bounds skips"
yaml
version: 1
enabled: true
furniture:
- id: "itemsadder:myplugin:chair" # prefix limited to itemsadder/oraxen/nexo/craftengine
pos: [3, 1, 5] # must be inside the template
yaw: 90.0 # 0.0-360.0
facing: "east" # derived from yaw, written on exportOn placement the four-source furniture is put back by facing (after block members, before mob spawning); entries whose plugin is missing are skipped with a warning (console.furniture_source_absent). During rollback the plugin first tries the furniture plugin's own removal, falling back to deleting the entity. Setting furniture.enabled: false disables the whole feature