NPC Placement and Alignment
NPC Placement and Alignment covers the files that decide where master and trainer NPCs stand and how a player's alignment changes the way each NPC treats them. Two related per-world JSON files do this, both under <world save>/dragonminez/npcs/, plus a datapack format for NPCs that live inside structures.
| File | What it controls |
|---|---|
placements.json |
Where master and trainer NPCs spawn (position, dimension, initial alignment or relation). |
alignment_rules.json |
How a player's alignment affects each NPC's hostility, friendliness and availability for interaction. |
Both files load at server start and reload with /dmzreload config (or /dmzreload all); see Reloading and Updating Changes. A reload also applies the placements again to every loaded dimension.
/dmzreload config.NPC placement
placements.json lists every NPC DragonMineZ places and where.
Source: src/main/java/com/dragonminez/server/world/npc/NPCPlacementManager.java.
{
"schema": 1,
"placements": [
{
"id": "master_roshi",
"entity": "dragonminez:master_roshi",
"dimension": "minecraft:overworld",
"structure": "roshi_house",
"x": 0.0,
"y": 0.0,
"z": 0.0,
"yaw": 225.0,
"pitch": 0.0,
"surface": true,
"relative_to_spawn": false,
"enabled": true,
"override": false
}
]
}
| Field | Type | What it does |
|---|---|---|
id |
String | Unique placement id. It is tagged onto the spawned entity so DragonMineZ can find and update it later. If two placements share an id, the last one in the file wins (a warning is logged). |
entity |
String | Registry id of the entity type. |
dimension |
String | Defaults to minecraft:overworld.
|
npc_id |
String | Only meaningful for dragonminez:quest_npc entities: links to the quest system's NPC id.
|
model / texture |
String | Only used for quest_npc entities.
|
structure |
String | If set, x, y and z become an offset from that structure's origin instead of world coordinates. Valid values: roshi_house, goku_house, elder_guru, timechamber, kamilookout, gero_lab. An unrecognized value falls back to treating x, y and z as raw world coordinates (with a warning in the log).
|
x, y, z |
Number | World coordinates, or the offset from the structure (see above). Defaults: 0.5, 64.0, 0.5.
|
yaw, pitch |
Number | Facing direction in degrees. |
surface |
Boolean | If true, snaps Y to the terrain surface at load time instead of using the given Y.
|
relative_to_spawn |
Boolean | If true, adds the world's spawn point to x and z (applied after any structure offset).
|
enabled |
Boolean | If false, this placement is skipped entirely.
|
override |
Boolean | If true, the entity is always respawned, even if one already exists for this id. Otherwise an existing entity is just updated in place.
|
alignment |
Integer (0–100) | Optional alignment for this specific NPC: above 60 it is friendly, from 41 to 60 neutral, and 40 or less hostile (unless an alignment rule makes it hostile first, see below). |
relation |
String | Optional override for this instance (HOSTILE, NEUTRAL or FRIENDLY), stored on the entity itself instead of being looked up from the alignment rules.
|
Unknown keys are reported in the JSON load report.
Default placements
The default file actively spawns these NPCs:
| Placement id | Entity | Where |
|---|---|---|
master_roshi |
dragonminez:master_roshi |
Roshi's house |
master_goku |
dragonminez:master_goku |
Goku's house |
master_karin, master_dende, master_popo |
dragonminez:master_karin, master_dende, master_popo |
Kami's Lookout |
master_gero |
dragonminez:master_gero |
Gero's lab |
master_guru |
dragonminez:master_guru |
Elder Guru's house (Namek) |
master_kaiosama |
dragonminez:master_kaiosama |
Otherworld, 54.5 299 1031.5
|
master_toribot |
dragonminez:master_toribot |
Otherworld, 50.5 298 1030.5
|
master_enma |
dragonminez:master_enma |
Otherworld, 0.5 150 17.5
|
master_baba |
dragonminez:master_uranai |
Otherworld, 9.5 150 3.5
|
master_grandkai |
dragonminez:master_grandkai |
Otherworld, -30.5 150 12.5
|
npc_hell_ogre |
dragonminez:quest_npc (npc_id hell_ogre) |
Otherworld, 9.5 150 16.5
|
master_otherworld_announcer |
dragonminez:master_otherworld_announcer |
Otherworld Tournament grounds, -25.5 352 -1164.5 (only placed once the tournament grounds have been built)
|
Quest NPCs and master NPCs
Quest NPCs (Bulma, Krillin, Yamcha, Tien, Piccolo, Gohan, Vegeta, Trunks, Chi-Chi, Videl, Shin and the Namek Elder) appear in the default file too, but with "enabled": false: they are no longer spawned at runtime through this system. They are baked directly into the structure NBT, so they live at fixed, hand-placed spots instead of piling up at the world spawn. Their entries here are for reference only. NPCs added to a structure after its NBT was made come from structure NPC files instead (Chi-Chi in Goku's House is one).
The Otherworld NPCs (master_kaiosama, master_enma, master_baba, master_toribot, master_grandkai, master_otherworld_announcer and npc_hell_ogre) always force override: true internally, whatever the file says, since they need to exist reliably in a generated dimension. See Otherworld.
Structure NPCs
Structure NPC files place NPCs inside a DragonMineZ structure without editing its .nbt file. Unlike the files above, these are datapack files: data/<namespace>/structure_npcs/*.json, one per structure, loaded with the datapacks (and by /reload).
{
"structure": "dragonminez:goku_house",
"npcs": [
{
"id": "npc_chi_chi",
"entity": "dragonminez:quest_npc",
"npc_id": "chi_chi",
"model": "saga_videl",
"texture": "saga_chichi",
"pos": [67.5, 5.0, 50.5],
"yaw": 90.0
}
]
}
| Field | Required | What it does |
|---|---|---|
structure |
Yes | Id of the structure the NPCs belong to. |
id |
Yes | Unique id of this NPC inside the structure. It is also the tracking key, so don't rename it once worlds use it. |
entity |
Yes | Entity type to spawn (for example dragonminez:quest_npc or a master's entity id).
|
npc_id |
No | Quest NPC id, for dragonminez:quest_npc.
|
model, texture |
No | Model and texture names for quest NPCs. |
template |
No | Which template of the structure the position is relative to, for structures made of several pieces. |
pos |
Yes | Position relative to the structure's template, so it stays right whatever rotation the structure spawned with. |
yaw |
No | Facing, also relative to the template (default 0).
|
alignment, relation |
No | Initial alignment and relation, as in placements.json.
|
Each NPC spawns once per generated structure when its chunk loads, including structures that were generated before the file existed, and the spawn is remembered: an NPC that dies doesn't come back.
To get the coordinates, stand where the NPC should be and run /dmzstructure here: it prints the structure, its template and your position and yaw relative to the template, with a Copy NPC JSON button that copies a ready-made entry. /dmzstructure npcs lists the NPCs of the structure you are in and whether each one has spawned yet. Both commands need the dragonminez.dmzstructure permission (see Permissions).
NPC alignment rules
alignment_rules.json decides how each NPC reacts to the player's alignment.
Source: src/main/java/com/dragonminez/common/alignment/NpcAlignmentRules.java.
{
"npcs": {
"goku": {
"default_relation": "FRIENDLY",
"interaction": { "min_alignment": 61 },
"hostile_below": 25
},
"gero": {
"default_relation": "NEUTRAL",
"interaction": { "max_alignment": 60 }
}
}
}
The keys in npcs are NPC ids with any namespace stripped (dragonminez:roshi becomes the key roshi).
| Field | Type | What it does |
|---|---|---|
default_relation |
HOSTILE / NEUTRAL / FRIENDLY |
Base relation when none of the thresholds below overrides it. Defaults to NEUTRAL.
|
hostile_below |
Integer | If the player's alignment is below this value, the NPC turns hostile regardless of default_relation.
|
hostile_above |
Integer | The same, but for an alignment above this value. |
interaction.min_alignment |
Integer | The player needs at least this alignment to talk to the NPC. Even if the NPC isn't hostile, a low enough alignment still blocks interaction. It can also be written directly on the rule, without the interaction wrapper.
|
interaction.max_alignment |
Integer | The same, but as an upper bound. |
All four threshold fields are optional: leave out whichever don't apply. Reading the goku entry above as an example: below 25 alignment Goku is hostile; from 25 to 60 he is present but won't talk (the alignment is under the min_alignment of 61); at 61 or more he is friendly and can be talked to.
NpcDispositionService.getRelation() checks the relation in this order:
- A
relationset on the placement (placements.json) wins. - The rule's
hostile_belowandhostile_abovethresholds. - An
alignmentset on the placement. - The rule's
default_relation.
Master NPCs
For master and trainer NPCs the rule file decides hostility, but their alignment gate is a fixed rule instead of interaction: masters can always be talked to, but Goku, Gohan, King Kai, Old Kai, Roshi and Krillin only unlock their Skills, Train and new quests at an alignment of at least 61, and Cell and Frieza at 40 or less. Every other master has no alignment gate. See Masters.
NPC ids covered by default
The default file covers goku, roshi, karin, guru, dende, popo, kingkai, gero, enma, baba, toribot, grandkai, otherworld_announcer, bulma, krillin, yamcha, tien, chiaotzu, gohan, trunks, chi_chi, videl, namek_elder, shin, piccolo and vegeta.
- Most default to
FRIENDLYwithmin_alignment: 41(or61for Goku, Guru, Dende, King Kai and the Namek Elder) andhostile_below: 25. gerodefaults toNEUTRALwithmax_alignment: 60.enma,baba,toribot,grandkai,otherworld_announcerandvegetadefault toNEUTRALwith no thresholds.piccolodefaults toNEUTRALwith its own thresholds (min_alignment: 41,hostile_below: 20).
Reload and validate
- Edit the files under
<world save>/dragonminez/npcs/. - Validate the JSON syntax (see How to JSON).
- Run
/dmzreload config(or/dmzreload all); see Reloading and Updating Changes. - Check that the NPC spawned or moved as expected, and that hostility and interaction based on alignment behave as configured (test at a couple of alignment values if you can).