Adventure documentation sorely lacking


There are a lot of things to like about PhantomBot but I think one of the most compelling features is the adventure system. There are features I’d like added to it but to be honest basic documentation of the existing feature set is pretty inadequate. Just to rattle off the issues:

  1. There is no pointer in the core documentation that tells you what file(s) you should be editing.

  2. Once you find advenureSystem.js there is some basic documentation within it, but it doesn’t explain anything more than how to do a basic-template adventure, and none of the provided adventures are more complex than the basic template, leaving you with no idea what does and doesn’t work beyond [body text] [body text] [people die maybe] [end of adventure]

  3. There’s no explanation of how (caught) works. Does it roll a fixed percentage every time you use (caught), meaning adventures with more instances of (caught) lead to that many more deaths? What is the roll that it’s making? Where can you edit the roll?

As I understand it, a lot of this stuff was well covered in the old forums, but all those posts appear to be gone. Like I said, I have feature ideas I’d love to see, but fixing the above should be a matter of minutes for a developer who knows the system, and other stuff might take hours of re-writing.

Please update the documentation for this really cool feature so more people can write better adventures. Thanks :slight_smile:


Just to help you out a little, you can find older posts from the other forum here

As for more info on the adventure system, did you only check the adventureSystem.js file or did you check it’s lang file as well?


I’m no PhantomBot dev but I am currently playing around with customizing several “adventures” for a streamer friend of mine. Some of them will be specific to certain games that he plays regular while the rest will be the general stories. I would be happy to help with any questions you have as I feel I have a pretty good understanding of the adventure system at this point.

  1. For the code: [Path to PhantomBot] > scripts > games > adventureSystem.js
    For the stories: [Path to PhantomBot] > scripts > lang > [language - mine is english] > games > games-adventureSystem.js

  2. In order to get more complex adventures you need to know about about programming in general and further about how to write in javascript.

  3. (caught) is just a variable used to store the people that “lost the roll”. Using (caught) more than once will only result in those same users being used over and over in the different plot points. As far as getting into more detail I would be more than happy to help further if you’re wanting to add to the adventures.


OK, I thought it triggered a roll each time but looks like I’m going to have to do some work to make a multi-stage adventure work. Thanks for the info!


function calculateResult()

for (i in currentAdventure.users) {
if ($.randRange(0, 20) > 0) {

  		if ($.randRange(0, 20) > 20) {
  		} else {
        } else {

function replaceTags(line) {

    if (line.indexOf('(caught)') > -1) {
        if (currentAdventure.caught.length > 0) {
            return line.replace('(caught)', adventureUsersListJoin(currentAdventure.caught));
        } else {
            return '';
  if (line.indexOf('(caught1)') > -1) {
        if (currentAdventure.caught1.length > 0) {
            return line.replace('(caught1)', adventureUsersListJoin(currentAdventure.caught1));
        } else {
            return '';
    if (line.indexOf('(survivors)') > -1) {
        if (currentAdventure.survivors.length > 0) {
            return line.replace('(survivors)', adventureUsersListJoin(currentAdventure.survivors));
        } else {
            return '';
    return line

function endHeist()

$.say($.lang.get(‘’, currentAdventure.survivors.length, currentAdventure.caught.length, currentAdventure.caught1.length)); //in case too many people enter.

function clearCurrentAdventure()

currentAdventure = {
gameState: 0,
users: [],
tgOwners: [],
survivors: [],
caught: [],
caught1: [],

That’s really all I did to add an additional instance with the possibility of additional deaths, gonna be adding more complexity possibly even including a roll to revive some of the users that were lost but that will require a bit more work to break each user down individually. The adventure game currently lumps every user that is lost into a single group.

EDIT: Actually once you add additional variables you also have to make changes inside the games-adventureSystem.js as well in order to include the additional user group(s) such as:

$.lang.register(‘adventuresystem.stories.2.title’, ‘Beartraps’);
$.lang.register(‘adventuresystem.stories.2.chapter.1’, ‘Friends! I’ve got coordinates for a secret stash of bolts, hidden away within the bowels of the elven forest. We should shoe up and give this a go!’);
$.lang.register(‘adventuresystem.stories.2.chapter.2’, ‘Look out, bear traps! (caught) got their legs ripped off!’);
$.lang.register(‘adventuresystem.stories.2.chapter.3’, ‘Look out, bear-pig traps! (caught1) got their legs shredded!’);
$.lang.register(‘adventuresystem.stories.2.chapter.4’, ‘Dayum, that was a close call for loosing a leg. But you’ve deserved this (survivors)!’);

Also if you want to make the stories specific to certain games you have to restart the counter “stories.[counter].title” in order to separate the group so it will only show up for those games and other stories won’t show up at all.

$.lang.register(‘adventuresystem.stories.1.title’, ‘Enemy Rear’);
$.lang.register(‘’, ‘xcom: enemy within’);
$.lang.register(‘adventuresystem.stories.1.chapter.1’, ‘Load up! We have a fight on our hands and you don’t want to get caught with your pants down!’);
$.lang.register(‘adventuresystem.stories.1.chapter.2’, ‘/me The squad lands in Suburbia and scans the area but are unprepared for what they see…’);
$.lang.register(‘adventuresystem.stories.1.chapter.3’, ‘The aliens showed their rear with deadly results, (caught) was caught in the backblast and is no longer with us!’);
$.lang.register(‘adventuresystem.stories.1.chapter.4’, ‘(caught1) took fire in their rear and was dragged away before we could get to them!’);
$.lang.register(‘adventuresystem.stories.1.chapter.5’, ‘It was a tough fight but we won (survivors)! Tend to your wounds and get ready for another bout!’);


Thanks, I used this as a basis to start editing the script, it looks like it’ll take some work to have adventures with a varying number of death events but this will work for me to get them up to multiple events per adventure at least.


Actually you don’t have to use the extra variables for every adventure. If you want to make 10 variables to store the deaths but want to vary the amount of events in each adventure then you can. It will just treat it as if there were no death rolls for those variables. With 10 (caught) variables(well I guess the proper term would be arrays) then you could have adventures that only have 1 death event and others with any other number up to 10 death events.

This is still very limited though, but if you give me an idea of what you’re trying to do I might be able to help out some.

EDIT: Nvm, I was mistaken in my assumption, it will still continue through every roll, you just won’t have anything shown if the survivors are lost.


Yeah I guess what I mean is that you can’t have a different amount but the same odds of overall survival. Right now I think I’m good although now that I’ve started tinkering with the adventure engine there’s definitely more complex stuff coming down the line. Thanks for the help!


I guess a fairly simple way to be able to make the events vary in the stories rather than be stuck to a specific number for all of them would be to replace “.chapter” with “.caught1”, “.caught2”, etc. So that you can check for the event number before rolling for the event. Some modification of the code would of course be necessary.


I hope this doesn’t sound rude, that is not my intent. So, please consider that before reading this.

I have been performing professional software development for two decades, I worked on open source projects before that (Linux, AberMUD, and various others) for close to another decade. What I learned was what my teachers, professors, and co-workers have told me - read the code :slight_smile: I have been thrust into multiple projects and had to learn new languages and determine how code worked to be able to make bug fixes and enhancements. I didn’t work on PhantomBot for the first version, or even the first few releases of the second version. My first adventure was adding in an API for StreamLabs and integrating it fully into PhantomBot. It took a lot of time and loss of hair as I ripped it out wondering how the thing worked. The best thing to do, really, is roll up your sleeves, read the code, and start hacking about - you will learn about a system very quickly that way.

I will add a page describing the language file, and how to modify that, and include the instructions from there, that is definitely missing.

Again, I hope this isn’t taken as rude, not my intent. We are here to answer questions when people have them and even help out with coding questions - and if we don’t answer, as you can see from this post - other folks in the community are happy to help out!



Let me know if this does a good job in describing how to edit the language file:



It’s a wonderful explanation on editing the language file for general stories but doesn’t even touch on the game specific aspect that you have included. I think that feature is really incredible and think others will too if you include information on how to use it properly. I actually discovered it by “reading the code” as you say, because it didn’t really click immediately when reading the very short example in the language file.

I actually created a thread where I was asking for help on the game specific adventures here and ended up explaining how I figured out how to get them working properly. Adding information about this neat little feature will most likely help anyone curious about adding more variety to the adventure system.


Quick question, the guide you provided includes information on where to put the custom stories, [lang > custom], but what about if you change the scripts for the adventure? Does PhantomBot have a similar custom system where we should place the modified adventure or do we just need to make sure to back up our changes and re-modify the add-on after updating?


Similar item, you can move the scripts into custom but do have to make a modification for the module enable/disable/command feature. I think at one point something was written up but may have been lost to the digital wind. I will try to write something up at some point today.

What I used to do (I haven’t customized scripts lately for myself) is make a copy, put into custom, disable the old module, and enable the new one. The old one can sit there, happy and doing nothing, and the new one does all the work.

Also, thank you for understanding my post about ‘reading the code’ and understanding that I wasn’t attempting to be rude. I definitely do not want to come across as a rude egomaniacal jerk in posts like that.



Also, thank you for understanding my post about ‘reading the code’ and understanding that I wasn’t attempting to be rude. I definitely do not want to come across as a rude egomaniacal jerk in posts like that.

I normally just end up being rude and disregarding hurt feelings personally, but I’m kinda a jerk so whatever lol. Thanks for all the help and I look forward to the guide, I’m not very strong with Javascript but am learning fairly quickly.


Please let me know if this guide helps with the understanding of the suggested way to make custom copies of stock PhantomBot modules (scripts):


Awesome, thanks so much…not sure why I didn’t see this before lol. So essentially I just find inside the script where this:


is used and then make sure the path is changed from the default (i.e. games/adventureSystem.js) to the new path (i.e. custom/adventureSystem.js). So I just create a custom folder inside the same directory in order for this to work as written in the example. This method should also allow other folder names correct? Like if I wanted to make specific folders for specific streamers (i.e. [streamer name]/adventureSystem.js)…???


That and the $.bot.isModuleEnabled(), yes. You can even do like the following if you really want:


And just enable the script depending upon which streamer this instance is tied to.

The language files, not quite as simple, if a streamer has a particular need of different text, then, there can be only one copy in custom that will override the settings from the non-custom language directory. Then I suppose you could keep different copies named after each streamer, but, you would have to include only that file with that particular instance of PhantomBot.

Hope that helps!


I would really love to talk with you more indepth about how to write complex stories and actually make them an adventure as well as maybe saving that data like some sort of rpg like adventure wherein it saves end data to use on the next adventure


It’s definitely possible but goes beyond anything I’ve done so far with the adventures. Feel free to DM me on here and we can go from there.