Skip to content

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 pos1 and /ems select pos2 record 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 glowing BlockDisplay entities (12 edges plus corner markers), visible within view distance and destroyed when you leave the world or the session times out
  • Use select adjust to nudge the box by direction; use select clear to remove the selection and its highlight
  • An idle selection ends automatically after selection.session_timeout (default 30m); on timeout the highlight is destroyed and the session released
  • The selection is limited by generate.size_limit and 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:

CheckError key
Name is lowercase letters, digits, underscore, hyphen; starts with a letter or digit; length ≤ 64error.name.invalid
Selection within generate.size_limit and the export limiterror.export.too_large
At least one exportable block in the selectionerror.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:

  1. Template and size check: missing template reports error.template.not_found; a size over generate.size_limit reports error.generate.rejected_by_limit
  2. Journal: create the journal/ snapshot log; if it cannot be created the generation is rejected (error.generate.journal_failed)
  3. Ground support: evaluated per generate.ground_mode (see Configuration); failing reports error.generate.ground_unsupported and aborts
  4. 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
  5. Entities and mobs: template entities follow generate.entity_policy, then spawns/ companion file entries run
  6. 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.nbt reads only spawns/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 / region use 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, and select echoes 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 facing field 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 reload after creating or editing a spawn file; re-exporting the same structure with /ems structure export refreshes 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 ignored

Parameters ​

FieldTypeRequiredRangeDescription
versionintNo1Reserved field, not validated today
enabledbooleanNotrue / falseFile-level switch, defaults to true; false disables the whole file
spawns[].typestringYesminecraft: / mythicmobs: / emakimobs: prefixMob type; the latter two need the matching plugin present, otherwise the entry fails with a warning
spawns[].poslist<int>One of pos / regionInside the template per axisFixed point in local coordinates; exactly one of pos or region must be given
spawns[].regionmapOne of pos / regionmin / max of 3 ints, min <= max and inside the templateRandom point in region, mutually exclusive with pos
spawns[].radiusintNo0–64Valid for pos entries only: random point inside a sphere around pos, the sphere must fit in the template; ignored in region entries
spawns[].countintYes1–16Number of mobs produced by this entry
spawns[].chancedoubleNo0.0–1.0, default 1.0Entry-level roll, evaluated once: on a miss the whole count is skipped, never a partial spawn
spawns[].facingstringNonorth / south / east / westMob facing, stacked with the structure's facing; omitted means the structure's facing
spawns[].levelintNoIntegerMob level, passed through for mythicmobs: types only

Limits and interactions ​

ItemDescription
spawn.enabled: falseMaster 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: noneDisables 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: passiveVanilla 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)
RollbackPoint mobs are written to the transaction journal and removed when a generation is rolled back

Common issues and errors ​

SymptomCause and fixError key
No mobs after placement and nothing in the consoleNo matching spawns/<template>.yml, or spawn.enabled: false, or generate.entity_policy: none—
Edits to the spawn file have no effectParsed results are cached; run /ems reload (or re-export the same structure)—
Point rejected as out of boundspos outside the template's local size; check the echoed size and the selection minimum cornererror.spawn.pos_out_of_bounds
Whole file rejectedTotal count over spawn.max_per_generation, or an illegal file nameerror.spawn.total_exceeded / error.name.invalid
An entry is skippedPer-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 spawnDependency plugin missing, or the world rules rejected the spawnconsole.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 export

On 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