Roll20 uses cookies to improve your experience on our site. Cookies enable you to enjoy certain features, social sharing functionality, and tailor message and display ads to your interests on our site and others. They also help us understand how our site is being used. By continuing to use our site, you consent to our use of cookies. Update your cookie preferences .
×
Create a free account

[Script] 5e NPC Importer via JSON (Evolution of Text-Based Importers)

May 31 (2 months ago)

Edited May 31 (2 months ago)

Hey everyone,

Like many of you, I've spent way too much time manually creating NPC sheets in Roll20. I love using custom monsters from PDFs and other sources, but getting them into the game can be a real grind.

I'd seen some older scripts that tried to tackle this, like Zanthox's awesome ImportStats script (which was a big inspiration for this, by the way!), but I wanted to try a slightly different approach using a structured JSON format. My hope was this would make it easier to handle more complex statblocks and be more friendly for generating NPC data with tools like ChatGPT or other LLMs.

So, I put together a new API script: the 5e NPC JSON Importer.

You can grab the script and all the details over on GitHub:

https://github.com/ByteBard97/roll20-5e-npc-json-importer

What it does (or tries to do!):

My main goal was to make importing NPCs into the official 'D&D 5e by Roll20' sheet as painless as possible.

Saves Time: Seriously, this is the biggest thing. Define your NPC in JSON, run the command, and boom – sheet created.

Handles a Lot of Stuff:

Basic stats, skills, saves, AC, HP, speed, senses, languages, CR, XP.

Populates repeating sections for Actions, Bonus Actions, Reactions, Legendary Actions, and Traits.

Sets up spellcasting (ability, caster level, slots – you still gotta add the actual spells, though).

Can do Mythic Actions (or use it for Lair Actions).

Fills in the Bio.

Even does the initiative tiebreaker.

Token Automation: If you put the JSON in a token's GM Notes, it'll link the token, set its name, bars (HP/AC), and make it the default token for the new character.

JSON Input:

Best way for bigger NPCs: Put the JSON in a Handout (GM notes field) and use !5enpcimport handout|YourHandoutName.

For quick stuff: !5enpcimport { ...your JSON... } or !5enpcimport with a selected token.

The Nitty-Gritty (Documentation):

Installation & Usage: All in the README.md

The JSON Format: This is key. I've documented all the fields in JSON_STRUCTURE.md. There are also some examples in the test_npcs/ folder on GitHub.

Big Thanks!

Again, a huge shout-out to Zanthox and their Roll205eSheetImport script / forum post. It was a massive help and showed what was possible.

I'm still learning a lot about Roll20 scripting, so any feedback, bug reports, or suggestions are super welcome! You can open an issue on GitHub or just reply here.

Hope this helps some of you spend less time prepping and more time playing!


May 31 (2 months ago)
timmaugh
Forum Champion
API Scripter

That's an impressive amount of work, ByteBard! I'll have to spend some time looking this over!

For now, two quick suggestions:

1) all scripts get concatenated into one long file before being read into the game, so they all share the same namespace. To save yourself from any potential collisions of objects/functions being named the same as yours, I would suggest putting your script in its own closure/scope. The Aaron has a revealing module pattern template he uses, and here is my template for the same pattern.

2) Put your chat event listener registration inside an on('ready') event (you have an on-ready listener already, but you could always add another and put the chat handler in that one). The reason has to do with metascripts and the extra functionality they bring to scripts like yours (like conditional blocks for the command line, or data retrieval from different places in the game, or roll management, etc.). It's OK if you've never heard of metascripts... but they are powerful, and it's a small change to make to bring your script into alignment. That way, when you *are* ready, the metascripts will be there!

May 31 (2 months ago)

Hi @timmaugh,

Thank you so much for taking the time to look at my script and for your incredibly helpful suggestions! I really appreciate you sharing your expertise.

Based on your advice, I've made the following changes:

Script Scoping (IIFE): I've refactored the entire script. The build process now wraps all the concatenated modules within a single Immediately Invoked Function Expression (IIFE). Additionally, all internal modules are now defined using const to ensure they are properly scoped within this IIFE. This should prevent any namespace collisions and keep the global scope clean.

on('ready') for Chat Listener: The chat event listener (on('chat:message', ...)) has been moved into the main on('ready', ...) handler. This ensures the script is fully initialized before it starts processing any chat commands.

I've also taken the opportunity to implement a more structured approach within the core module, similar to the Revealing Module Pattern, using scriptName and version constants and a dedicated registerEventHandlers function for better organization.

All these changes are on a new feature branch here:

https://github.com/ByteBard97/roll20-5e-npc-json-importer/tree/feature/script-scoping-initialization-

I'd be very grateful if you could take a look when you have a moment to see if this aligns well with your suggestions or if there are any further improvements you'd recommend regarding these points.

Thanks again for your guidance – it's been a massive help in improving the script's structure and robustness!

Best regards,

ByteBard