For NPCs that stand still and do something when clicked - a shopkeeper, a server selector in the lobby, a quest giver - use a packet-based plugin such as FancyNpcs: it is free, simple, and costs the server almost nothing because the NPCs do not exist as real entities. For NPCs that walk, follow paths, fight, guard or run scripts, use Citizens: it creates real entities with real AI, it has an ecosystem (Sentinel for guards, Denizen for scripting), and it costs ticks accordingly. Both give you player-shaped NPCs with any skin, both run console or player commands on click, and both work fine on Paper. The mistakes people make are mostly about skins, click commands that run with too much power, and using a fully simulated NPC for a job a hologram could do.
This guide compares the two, covers the commands that matter, and explains what each costs. If you want floating text rather than a character, holograms, scoreboards and TAB is the better fit.
Real entities versus packet NPCs#
Every NPC plugin takes one of two approaches, and the choice determines what the NPC can do and what it costs.
Real entities. The plugin creates an entity on the server. For a player-shaped NPC that means a fake player object; for other types, an ordinary mob with its AI controlled by the plugin. The server ticks it, tracks it, collides with it and saves it. It can pathfind, take damage, hold items, be pushed, fight. This is Citizens.
Packet NPCs. The plugin sends the client packets describing an entity that does not exist on the server. The client draws a player standing there; the server only knows to listen for clicks at that spot. Nothing ticks, nothing collides, nothing is saved in the world. It cannot move on its own or fight, but it can look at players, wear armour, play animations and react to clicks. This is FancyNpcs, ZNPCsPlus and similar.
| Citizens | FancyNpcs | |
|---|---|---|
| Price | Free dev builds, paid on Spigot | Free |
| How NPCs exist | Real entities | Client-side packets |
| Movement and pathing | Yes, waypoints and paths | No |
| Combat and guards | Yes, with Sentinel | No |
| Scripting | Denizen and many integrations | Action system for clicks |
| Server cost per NPC | Ticks like an entity | Near zero |
| Survives plugin removal | Leaves nothing in the world | Leaves nothing in the world |
| Best for | Quests, guards, moving NPCs, RPG | Lobbies, selectors, shopkeepers |
On a lobby with forty selector NPCs, FancyNpcs is the obvious answer. On an RPG server where NPCs patrol a town, fight bandits and talk to players through scripted dialogue, Citizens is the only real option.
Citizens: installing and the commands you need#
Citizens is distributed two ways: paid on SpigotMC, which supports the developer, and free development builds from the project's own build server. Both are the same plugin. Download the build matching your Minecraft version - Citizens is tied closely to server internals and an old build on a new server fails to load.
The workflow is select-then-edit. Most /npc commands act on the NPC you have selected.
/npc create Blacksmith/npc select/npc skin Notch/npc lookclose/npc equip/npc tphere/npc list/npc removeThe ones you will use most:
/npc create <name>creates an NPC at your position and selects it./npc selectselects the nearest NPC you are looking at, or by ID./npc skin <player>uses a player's skin by name;/npc skin --url <url>uses a skin image URL, which is how you use a custom skin that does not belong to an account./npc lookclosetoggles whether the NPC turns to look at nearby players./npc equipopens an editor to put armour and held items on the NPC./npc type <entity>changes the NPC from a player to a villager, zombie or any other entity type.
NPCs are saved in plugins/Citizens/saves.yml. Back it up with the rest of the server; a lobby that took an evening to set up should not be one file corruption away from gone.
Commands on click
Citizens has a built-in command trait that runs commands when the NPC is clicked:
/npc command add warp shop -p/npc command add -r eco give <p> 10 --cooldown 1d/npc command add -l say Do not hit me, <p>/npc command add -p kit starter --permission server.kit.starterThe flags are the important part:
| Flag | Effect |
|---|---|
-p | Run as the clicking player instead of the console |
-o | Run as the player with temporary operator rights |
-l / -r | Only on left click / right click |
--permission <node> | Require a permission to trigger |
--cooldown <time> | Per-player cooldown |
--gcooldown <time> | Global cooldown across all players |
--n <number> | Limit uses per player |
--delay <ticks> | Delay before running |
<p> is replaced with the player's name and <npc> with the NPC's ID. Commands without -p run as the console, with full power. That is what you want for rewards (eco give <p> 10) and dangerous if the command can be influenced by the player in any way.
FancyNpcs: installing and the commands you need#
FancyNpcs is a single free plugin for Paper. NPCs are created with /npc (if Citizens is also installed, the two fight over that command; use one or the other, or the /fancynpcs namespace).
/npc create Selector/npc skin Selector Notch/npc turn_to_player Selector true/npc displayname Selector <gold>Survival/npc glowing Selector gold/npc equipment Selector set/npc list/npc remove SelectorFancyNpcs commands name the NPC on each command rather than relying on a selection, which makes them easy to script and copy. skin accepts a player name, a URL, or @mirror, which shows each viewer their own skin - a nice touch for a lobby. turn_to_player makes the NPC watch nearby players. Display names use MiniMessage formatting.
Click behaviour uses an action system with triggers and actions:
/npc action Selector right_click add send_to_server survival/npc action Shopkeeper any_click add message <green>Welcome to the shop/npc action Shopkeeper right_click add console_command eco give {player} 5/npc action Shopkeeper right_click add player_command warp shopTriggers are right_click, left_click, any_click and custom. Actions include message, console_command, player_command, player_command_as_op, send_to_server (move the player to another backend on a proxy network), wait, need_permission and play_sound. Actions run in order, so a need_permission action followed by a player_command is a permission-gated command. {player} is the clicking player's name in console commands; message actions also take PlaceholderAPI placeholders. The same warning applies to player_command_as_op as to Citizens' -o.
send_to_server is the reason FancyNpcs is so common in network lobbies: a row of NPCs, one per game mode, each sending the player to the right backend through the proxy. A Velocity proxy network covers the proxy side.
ZNPCsPlus is another free packet-based plugin in the same category, with a similar feature set. The comparison above applies to it as well.
Skins without the headaches#
Skins are where most NPC complaints come from. A player NPC's skin is a signed texture from Mojang's servers. When you set a skin by player name, the plugin looks up that player's current skin and caches the signed texture.
Things that go wrong:
- The player changes their skin. Name-based skins can update to the new skin when the cache refreshes. For a permanent look, use a URL or file-based skin, or a plugin option that stores the texture permanently.
- Rate limits. Mojang rate-limits skin lookups. Creating fifty NPCs with different skins in a minute can fail partway; spread them out or use stored textures.
- URL skins need signing. A skin from a URL has to be uploaded to a signing service (MineSkin is the common one, and the plugins use it behind the scenes) before clients will display it. If it fails, the NPC shows a default skin.
- Offline-mode servers. On a server with
online-mode=falsewithout a proxy doing authentication, skin handling is unreliable and you have bigger problems; see server security checklist. - Bedrock players. Through Geyser, player NPCs usually display, but skins and some effects may differ from what Java players see.
The practical rule: for important NPCs, set the skin once from a URL or texture, confirm it, and do not depend on a live player's account.
What NPCs cost#
A packet NPC costs almost nothing on the server. The plugin keeps a list of NPCs and, when a player comes into range, sends the packets that draw them; when the player clicks, it handles the click. Forty in a lobby are not worth thinking about. The client cost - drawing forty player models with skins - is real but modest.
A Citizens NPC is an entity, and its cost depends on what it does:
- Standing, `lookclose` on: small. It ticks, checks for nearby players to look at, and is tracked like any entity.
- Walking a path: pathfinding costs like a mob's, every time it recalculates.
- Fighting (Sentinel guards): targeting, pathing and combat, every tick, which is mob-level cost or more.
- Running Denizen scripts: depends entirely on the scripts. Badly written scripts that run every tick are a common source of lag on RPG servers.
If an RPG server is slow, spark will show Citizens and Denizen in the call tree when they are the cause. Reading a spark report covers finding them. Common fixes are fewer moving NPCs, longer path intervals, guards that only activate when players are near, and scripts triggered by events instead of polling.
Citizens player NPCs also briefly appear as players to the server. Some plugins that count online players or iterate over players can see them. Most well-written plugins check for the NPC metadata Citizens sets; a few do not, and you will see NPC names in odd places. Packet NPCs never have this problem.
A lobby selector, start to finish#
The most common NPC job on any network is the game-mode selector: a row of characters at spawn, each sending players to a different server. Here is the whole job with FancyNpcs, which is the right tool for it.
- Stand where the first NPC should be, facing the way it should face, and run
/npc create survival. - Give it a look:
/npc skin survival <url>with a skin you control, and/npc turn_to_player survival trueso it watches whoever approaches. - Name it:
/npc displayname survival <green>Survival. Keep names short; long names overlap when NPCs stand close together. - Wire the click:
/npc action survival any_click add send_to_server survival. The value is the server name as defined in your proxy configuration, not the address. - Repeat for each mode, spacing NPCs at least two blocks apart so name tags stay readable.
- Add a hologram above or beside each NPC with the player count for that server, if you want live numbers - see holograms, scoreboards and TAB.
- Test as a non-operator. Operators often bypass permission checks that real players hit, and a selector that only works for staff is a common launch-day surprise.
For a single-server setup without a proxy, replace step 4 with a player_command action that runs a warp, or a console_command that teleports {player}. The structure stays the same.
Two design notes. Keep the selector away from the exact spawn point: players arriving are still loading chunks and textures, and NPCs rendered at the spawn block get clicked by accident. And keep the count small; five clearly labelled choices are better than twelve, and every extra player model is something a low-end client has to draw.
Common problems and fixes#
NPC does not appear after a restart. For Citizens, check the console for errors on load - a Citizens build that does not match the server version fails here. Check saves.yml exists. For FancyNpcs, check the plugin loaded and the NPC's world name has not changed.
Click command runs but does nothing. Run the same command by hand in the console, with the player's name substituted. Most failures are a typo or a command that needs the player online in a specific world. The console line says why.
Clicking an NPC also attacks it or opens a shop twice. Restrict the trigger: -r in Citizens or right_click in FancyNpcs. Left and right click both fire on some interactions.
NPC names show in the tab list. Citizens hides its NPCs from the tab list by default; a tab plugin that rebuilds the list may show them. Check the tab plugin's options for hiding NPCs.
Two NPC plugins fight over `/npc`. Remove one, or use namespaced commands. Do not run two NPC plugins for the same job.
NPCs lag a lobby. If it is a Citizens lobby with many lookclose NPCs, switch the static ones to a packet plugin. If it is client frame rate, reduce the number of NPCs in view.
On RE:NODE you upload the plugin jar through the file manager or SFTP, and the console has command history and tab completion, which helps when building NPCs with long command strings. NPC data files are part of the server's files, so they are included in panel backups; take one before a big lobby rebuild.
FAQ#
Which is better, Citizens or FancyNpcs?
For static NPCs that run a command or send players to another server, FancyNpcs: free, simple and almost free in tick time. For NPCs that move, fight, guard or run scripted quests, Citizens, because packet NPCs cannot do those things.
Do NPCs count towards the player limit?
Packet NPCs never do. Citizens player NPCs do not take a slot, but some plugins that list or count players may see them. Most well-maintained plugins ignore them.
How do I give an NPC a custom skin?
Use a skin image URL: /npc skin --url <url> in Citizens, or /npc skin <npc> <url> in FancyNpcs. The plugin has the skin signed through a service such as MineSkin. For a permanent look, use a URL rather than a player name.
Can an NPC send players to another server on my network?
Yes. FancyNpcs has a send_to_server action for proxy networks. With Citizens, run the proxy's server command as the player, or a plugin command that moves players between backends.
Why is my Citizens NPC running commands as op dangerous?
Because temporarily opping a player to run a command can leave them opped or let a chained command run with operator rights if something fails. Run rewards as console commands with the player's name instead, and grant specific permissions for player commands.




Comments
Completely anonymous: no account, no email, no cookie. We store the name you type, the text and the time - nothing else. Links are limited and markup is not rendered.