Developer API

HyCitizens exposes a code-first API for creating, updating, and controlling citizens at runtime. This guide focuses on the real integration flow used in production plugins.

API

Audience

This section is for Java plugin developers. If you are configuring citizens in-game, start with the User Guide.

1. Add Dependency

Declare HyCitizens as a runtime dependency so your plugin loads after it:

{
  "Dependencies": {
    "electro:HyCitizens": "*"
  }
}

Also include the HyCitizens jar as a compile dependency in your build so your IDE resolves API types.

2. Get The Manager

CitizensManager manager = HyCitizensPlugin.get().getCitizensManager();

CitizensManager is the entry point for almost all runtime work.

3. Core Mental Model

Use a two-step flow:

StepWhat you do
Edit data Modify a CitizenData object.
Apply update Call the matching CitizensManager update method to push changes to the live entity.

4. Pick The Right Update Method

MethodUse for
updateCitizen(citizen, save) Full respawn (NPC plus nametag representation).
updateCitizenNPC(citizen, save) NPC-only changes: combat, detection, path behavior, skin/model internals.
updateCitizenHologram(citizen, save) Name and nametag presentation changes. This now updates either inline NPC nameplate or separate hologram entities automatically.
updateCitizenNPCItems(citizen) Equipment changes without respawning.

5. Nametag Rendering Rules

HyCitizens now uses adaptive nametag rendering:

  • Inline NPC Nameplate when all are true: NPC visible, exactly one non-empty name line, nametag offset is 0.
  • Separate nametag entities when any are true: hideNpc=true, multiple non-empty name lines, or non-zero nametag offset.
  • hideNametag=true disables both inline and separate nametag rendering.

For name, hideNametag, hideNpc, or nametagOffset changes, call updateCitizenHologram(citizen, true).

6. Minimal Create Example

CitizensManager manager = HyCitizensPlugin.get().getCitizensManager();

CitizenData citizen = new CitizenData(
    "town_captain",
    "Captain Rhea",
    "Player",
    worldUuid,
    new Vector3d(0, 70, 0),
    new Vector3f(0, 0, 0),
    1.0f,
    null,
    new ArrayList<>(),
    "",
    "",
    List.of(),
    true,
    false,
    "Simon",
    null,
    0L,
    true
);

citizen.setMessagesConfig(new MessagesConfig(
    List.of(new CitizenMessage("{GOLD}Welcome to the city.", "F_KEY", 0f)),
    "SEQUENTIAL",
    true
));

manager.addCitizen(citizen, true);

Where To Go Next

PageWhy read it
CitizensManager Full runtime lifecycle and method-by-method behavior.
CitizenData Every field, update requirements, and runtime state notes.
Events Interaction/death hooks and cancellation patterns.
Full Example End-to-end setup with messages, combat, patrol, and listeners.
Production tip: batch multiple field edits, then call one update method and one save call. This avoids extra respawns and disk writes.