Admin instruments: Custom NPCs —Improved by admins for admins

A patched build of Custom NPCs for Minecraft 1.16.5 (Forge). The same mod you know, with the bugs fixed, a rebuilt editor, a dark theme, a much stronger quest system

Custom NPCs — BRP

🇺🇦 Українська версія: README.md · Changelog: CHANGES_EN.md / CHANGES.md

A patched build of Custom NPCs for Minecraft 1.16.5 (Forge). The same mod you know, with the bugs fixed, a rebuilt editor, a dark theme, a much stronger quest system and a complete Ukrainian translation.

Built and maintained for the gummercraft.fun server.

   
Version 1.16.5-BRP-0.0.27
Minecraft 1.16.5
Forge 36.2+
Languages Ukrainian, English (complete) + 15 partial

About the mod

Custom NPCs lets you create your own characters and build a whole world out of them: branching dialogs, quests, factions with standings, shops, banks, companions, transporters, mailmen. Every NPC is configurable down to the details — model, animations, combat tactics, scripts.

The original mod was created by Noppes — kodevelopment.nl. All credit for the mod itself belongs to him. This build is only a patch on top of 1.16.5.


What this build fixes and adds

Data stops disappearing

  • Carpentry recipes persist and craft. In the original 1.16.5 build the whole subsystem was dead: the recipe file was never read on startup, saving did nothing, deleting removed nothing, the manager always received an empty list, and the bench could not match a single recipe. Fully restored and pinned by tests.
  • Quest and dialog ids are never handed out twice. A new quest made after deleting the newest one and restarting used to get its id - and everyone who had finished the old quest had the new one finished too. The highest id ever issued is now kept on disk.
  • Quest progress survives saving, and a renamed location block no longer reverts after a restart - both made location quests unreliable.
  • A corrupted save no longer blocks writing — file streams used to stay open on truncated files.
  • The bank no longer charges for nothing — the slot fee was taken before the limit check.
  • Finishing a quest from a script no longer crashes the server.
  • Three infinite recursions (server-start crashes) found and fixed.

Server safety

  • Editor permissions are OP-only. 29 of the 30 permission nodes used to register as available to every player.
  • Reading the NBT of any block in the world by any player is closed off.
  • Purchases are validated by the server: index, price, stock, reputation — the price used to be whatever the client's slot happened to hold.
  • Per-element network packets. A big shop or a long quest line is no longer packed into a single packet — that used to threaten a disconnect at the ~1 MB packet limit.
  • World rules come from the server, not the client: name tags no longer show through blocks (NameTagsThroughBlocks), and the map's hitbox switch makes every client turn F3+B straight back off (BlockHitboxes). Both live in the server config and reach clients at login.
  • Editor limits are config options (LimitConditions, LimitQuestBranches, LimitTradeOffers, up to 9999 each) and are synced too, so an admin's editor gates on the server's limit rather than its own.
  • A backup when the mod version changes — the customnpcs folder is copied aside before anything is converted; the formats are a one way door, so this is the last line of defence.
  • A server-safety auditor (tools/dist_audit.py) finds client-only API called from server code — the bug class that kills a dedicated server instantly and that the compiler cannot see.
  • Admin actions need permissions, not just an item in hand: npc containers need customnpcs.npc.gui, block and schematic saves customnpcs.edit.blocks (and reach only this mod's blocks, not any chest at client-supplied coordinates).
  • Player actions only on the spot: a dialog reply, a transporter ride and handing a quest in to an npc are not accepted from anywhere.
  • Races between players closed: a follower cannot be bought out from under its owner along with their paid days, a bank cannot be opened through another bank's banker, and mail attachments no longer vanish when a letter is closed unsent.
  • Code in items only from trusted players. A scripted item, a soulstone, a scripted block or an npc from a spawn egg made in creative by a player not trusted with scripts (an operator, or customnpcs.tool.scripter) arrives without its code or its entity - as vanilla does with command blocks.
  • File names from players stay in their folder: a clone named ../../../../ops no longer overwrites ops.json, and a category named .. no longer empties the customnpcs folder.
  • Chunk loaders no longer keep chunks loaded for good - the mod's tickets are not saved and all of them are released; invisible npcs no longer send a packet every tick.

Quests

  • On-screen tracker: active quests with objectives in a corner, completed ones green. Kill progress flashes "Zombie 3/5" on the actionbar. Everything can be turned off: globally in the config and per quest in the editor. Any of the four corners, an offset from that corner, the line width and the objective cap are config options; it draws last and keeps clear of the potion icons and the sidebar scoreboard.
  • Mixed quest type — items + dialogs + kills + locations + manual counters in one quest.
  • Branching chains — a list of next-quest candidates with conditions; the first one the player qualifies for starts. The old single "next quest" remains the unconditional fallback.
  • Quest scheme — the whole chain as a graph: types, repeats, branches labelled IF/OR, END, GOTO. Nodes drag, clicking one opens the quest editor.
  • Location zones — X/Y/Z/radius straight from the editor, no waypoint blocks in the world.
  • Reward choice — a per-quest "player picks one" reward mode.
  • No objective limits — kills, dialogs, counters are unlimited; kill targets are picked from the entity registry with search instead of being typed by hand.
  • The quest log is rebuilt: quest list + scrollable story + every objective coloured by state.
  • Per-quest sounds — separate accept and completion sounds, picked the same way as the dialog sound; an empty field means silent.

Dialogs

  • A conversation screen in journal style: the exchange history with speaker names (NPC in accent, player in green), numbered replies, digits 1–9 as hotkeys, trade as its own button.
  • A dialog scheme per NPC: nodes are dialogs, edges are replies, labelled IF/OR/END/GOTO.
  • Availability conditions are an unlimited list (used to be 4+4+2+2 fixed slots) with an "all conditions / any condition" combiner, and they can now gate individual reply options too.
  • NPC dialogs and reply options are unlimited, shown as a list or tiles.

Shops

  • Offers are data, not slots. No 18-offer limit; stock, faction-reputation prices, up to four item prices, categories, search, tile/list view modes.
  • Setting up a shop costs no items — the editor slots copy what you hold instead of taking it.
  • Purchases are visible instantly: the inventory syncs the moment the trade happens, with a pickup sound and a "Bought ×N" confirmation; Shift/Ctrl buys in bulk.
  • Shop from a dialog — a dialog option can open a saved market with no trader role needed.
  • Restocking — per offer: refill to N copies every M minutes of real time. Zero in either field disables it, so existing shops behave exactly as before.
  • Offers are fully editable after creation: category, the goods and every price amount (mouse wheel over the slot, Shift for 8), reputation and its faction, stock, restocking, enabled. The "Settings..." button holds the shop-wide ignore damage / ignore nbt toggles.
  • Any amount: goods and prices up to 9999 regardless of stack size - click a slot and type the number (Ctrl+wheel steps 64). Payment accepts an item with tags a mod added as long as every tag of the price is there; saved markets no longer distort nbt.
  • A two-panel trade window, in the style of STALKER: the trader's shelf with category tabs on the left, your own pack on the right. An item the trader buys is lit and says what it pays, and clicking your own item sells it; a line underneath describes whatever is under the cursor.

Combat and behaviour

  • The shooting range finally means engagement range. An npc holding a projectile and set to fight back engages as far as it can shoot when that is further than its aggro range (NpcRangedAggro turns it off), notices targets above and below it rather than only inside a flat eight-block slab, and closes the distance itself whether or not direct line of sight is required.
  • Editing the aggro range takes effect at once - saving the stats tab used to refresh nothing, so the number only started working after a chunk reload.
  • Modded enemies are recognised. Hostile means the IMob marker or the MONSTER spawn category, not only descendants of MonsterEntity - which is how mods declare it. The guard's buttons add "all hostile mobs / animals / creepers" categories that cover mobs from mods installed later; old guard lists migrate on their own. The healer no longer poisons villagers, pets and golems.
  • Npc jobs: the farmer picks pumpkins and melons, the builder no longer throws after its builder block is broken, and linked npcs each keep their own home.
  • Weapons used like a player: with no projectile set an npc fires the bow, crossbow, trident, throwable or modded gun that shoots on use in its hand (ranged properties, "Fire held weapon").
  • Projectile size from 1% of a block (it could not go under half a block) - small bullets and pellets.
  • Natural spawns out of sight: never within 24 blocks of a player nor where one is looking (NpcNaturalSpawnMinDistance, NpcNaturalSpawnHiddenRange).
  • A "has item" availability condition - from a hand (with nbt) or by id, up to 9999, has / has not, and "take when used": payment for a reply or a dialog.

The npc map

  • A top-down window over every npc in the dimension: a dot in its faction's colour, names from ×1.5, drag to pan, wheel to zoom (×0.25–×8).
  • It shows all of them, not just the loaded ones — the server keeps a persistent npc registry (mapregistry.dat), so npcs in unloaded chunks appear too; clicking one teleports you there, clicking a loaded one opens its editor straight away.
  • Quest links — arrows from the npc handing a quest out to the npc it is handed in to.
  • Quest zones — location objectives drawn as labelled circles.
  • Real terrain instead of a grid: the surface is sampled from loaded chunks into a persistent client-side cache (256×256 tiles per server and dimension), so ground seen once stays mapped forever, at zero server and network cost.
  • Search that highlights matches and centres on the first one.

Editor

  • A dark grey theme drawn from a palette instead of textures. Config switch: dark / light / legacy.
  • Rebuilt screens: measured layout (no language overlaps its controls), sections with headers, dropdowns instead of cycle-buttons, scrolling instead of page-flipping, hover hints on icon buttons, an unsaved-changes indicator with Ctrl+S. The classic layout of the main editor remains available as an option. editor remains available as a choice.
  • The text editor (quest texts, dialogs, scripts): line breaks show immediately, the view follows the cursor, Home/End, Shift+click, Ctrl+Backspace, Ctrl+Z/Y.
  • Every screen fits the window. Automatic gui scale leaves 426x240 on 1440p, 4K and 720p and 480x270 on 1080p. A screen that lacks room lowers the gui scale by a whole step while it is open (the pixel font stays sharp) and restores yours when it closes.
  • Labels no longer run into their controls: where a translation is longer than the room, the label is cut with "..." and shows in full on hover. Dropdowns and hints always draw on top.

Localisation

A complete Ukrainian translation — 793 lines, 100% coverage. The mod had no Ukrainian file at all before this build.


Installation

Like any Forge mod: drop the .jar into your mods folder.

Important when upgrading from the original build

Back up your world before the first launch. Shops and availability conditions convert from the old format automatically, but are saved only in the new one — a world saved by this build will not open with the original mod.

Permissions. If non-operators edited NPCs on your server, they now need either operator rights or explicitly granted customnpcs.* nodes. This change is intentional.

Recipes. If the world ran on the original 1.16.5, the recipe file may have stayed empty — those recipes have to be recreated once. They persist from then on.

Looks. The theme defaults to dark. To get the original textures back, set GuiThemeName=legacy in config/CustomNpcs.cfg.

Client and server must be the same build. The network protocol is now CNPCS-BRP19; a player on a different version cannot join. Update the server and the players together.

A wand without permissions. Npc containers now need customnpcs.npc.gui, and block and schematic saves customnpcs.edit.blocks. Anyone who had a wand without these loses access to those screens - this is intentional.

The first start on 0.0.24+ reads the player files once, so new quests and dialogs never get the id of a deleted one (the log says so if any were found). Guards with an old "monsters" or "animals" list get the matching category automatically.

Chunks from old chunk loaders (before 0.0.26). Older builds loaded chunks with vanilla forceChunk, and those could stay loaded for good. List them with /forceload query and clear them with /forceload remove all (this also clears chunks forced by hand; the new loaders load theirs again as soon as players are near).

Renaming an npc by command is now /noppes npc <name> rename <new name> - the old delete <new name> form no longer renames.

Creative without permissions. Scripted items and filled soulstones moved in the creative inventory by a player without customnpcs.tool.scripter (and not an operator) lose their code and their entity. Hand such items out in survival, or give builders that permission.


Building from source

JDK 8 is required — ForgeGradle 5 for 1.16.5 will not work otherwise.

gradlew.bat build

The first run takes a while: ForgeGradle decompiles and maps Minecraft itself.

Two checks before a release

Both read the compiler's class output (build/classes/java/main after gradlew build) and exit non-zero when something is wrong:

python tools/dist_audit.py build/classes/java/main
python tools/run_tests.py  build/classes/java/main

dist_audit.py finds client-only API called from server code. That is not a style issue but a crash: Forge strips @OnlyIn(Dist.CLIENT) members on a dedicated server, and such a call kills the tick loop. The compiler cannot see it, because the build compiles against the merged jar. Success is CRITICAL - (none).

run_tests.py saves quests, shops and availability conditions, loads them back, compares every field, feeds them rubbish, and checks carpentry recipe matching. This build's formats are a one way door, so a serialisation bug costs data - and that is the bug class behind every worst failure here.


Still on the list

  • The Inventory tab keeps the classic layout: its geometry is defined by slot positions in a container shared with the server.
  • Picking shop goods from the item registry (so items would not need to be in your inventory).
  • The player-facing mail, faction and transport screens are still on the old textures.
  • 15 of the 17 languages are partial (Ukrainian and English are complete).
  • Global recipes show in the recipe book but are not registered with the vanilla recipe manager, so an ordinary crafting table does not make them. The npc carpentry bench (4x4 recipes) works.

License and credit

The original Custom NPCs mod © Noppes, licensed CC BY-NC — non-commercial use with attribution. This build is distributed under the same terms.

The patch was prepared for the gummercraft.fun community.

Admin instruments: Custom NPCs —Improved by admins for admins Team

profile avatar
  • 5
    Projects
  • 2.1K
    Downloads

Gummercraft server complex programmer and soldier of the 81st Airmobile Brigade of Ukraine

More from Rayman_GCView all