Running Inspiration Pad Pro 3 from the Command-Line (macOS/Windows/Linux)

Inspiration Pad Pro 3 is an excellent tool for creating random tables and rolling them. It’s probably the #1 utility in my entire toolbox. That said, it’s a Windows-only application and my laptop is a Macbook.

In order to get around this obstacle I developed a way to run Inspiration Pad Pro 3 from my Mac’s command-line interface. Below is an example of me running it:

With a few tweaks to my script I was able to port it to work on Windows 10 via Windows Subsystem for Linux. That same script will also run on Linux natively for those of you that run that.

It does have a few limitations:

  1. You can’t nest generator files more than 1 subdirectory deep.
  2. Prompts don’t work. A workaround is hard-coding the result you want in the script.

If you’re interested in getting this set up for yourself I wrote out some instructions below to help you:

macOS Instructions
  1. Ensure you have Homebrew installed.
  2. Install noah with the command

brew install noah

  1. Download the IPPmacOS.zip file from my itch.io page.
    Inside will be two folders, common and generators, along with two files, ipad3cgi and ipp.sh.
Notes

ipad3cgi is the same file that is available for download direct from NBOS here. The common and generators folders are the folders automatically created and populated when installing the full version of IPP3 on a Windows machine, I’ve included them and standardized the naming conventions within for your convenience.
The ipp.sh file is the script I wrote to assist with the generation.

  1. Move the IPPmacOS folder you downloaded somewhere logical, e.g. your Documents folder.
  2. Next, you’ll need to open ipp.sh with your favorite text editor and populate the gendir variable with the full path to the location of the generators folder. If you put the IPPmacOS folder in your Documents folder, this should be:

gendir=/Users/[your_username]/Documents/IPPmacOS/generators

  1. Next, you need to create an alias so you can call the generator from anywhere. This can be done by adding a line to your ~/.bash_profile file via the below command. Simply change the path to wherever you moved the IPPmacOS folder. If you put the folder in your Documents folder you will only have to change [your_username] in the below.

echo “alias randomgen=‘cd /Users/[your_username]/Documents/IPPmacOS && ./ipp.sh && cd - >/dev/null’” >> ~/.bash_profile

Now that that’s done we commit the changes with the below command:

source ~/.bash_profile

Now, no matter what directory you’re in, running randomgen will activate the script!

  1. If you are on Catalina the security settings may prevent ipad3cgi from running the first time to call it. To remediate this, follow the below steps to adjust your security settings:

When the error pops up, click the ? icon

Then, in the help guide, click Open the General panel for me

Then, hit the cancel button

This will populate the ipad3cgi allow anyway option in the general panel - click it

Run the randomgen alias again, this time you’ll get a slightly different error box - click open

And you’re all set!

Windows Instructions
  1. Ensure you have Windows Subsystem for Linux installed.
    Details to install WSL can be found here, a more detailed in-depth guide can be found here. This guide assumes you’re using Ubuntu.
  2. Download the IPPWin.zip file from my itch.io page.
    Inside will be two folders, common and generators, along with two files, ipad3cgi and ipp.sh.
Notes

ipad3cgi is the same file that is available for download direct from NBOS here. The common and generators folders are the folders automatically created and populated when installing the full version of IPP3 on a Windows machine, I’ve included them and standardized the naming conventions within for your convenience.
The ipp.sh file is the script I wrote to assist with the generation.

  1. Unzip the IPPWin.zip folder you downloaded and move the resulting IPPWin folder somewhere logical, e.g. your Documents folder.
  2. Next, you’ll need to open ipp.sh with your favorite text editor and populate the gendir variable with the full path to the location of the generators folder. If you put the IPPWin folder in your Documents folder, this should be:

gendir=/mnt/c/Users/[your_username]/Documents/IPPWin/generators

  1. Finally, you need to create an alias so you can call the generator from anywhere. This can be done by adding a line to your ~/.bashrc file via the below command (assuming you’re using Ubuntu). Simply change the path to wherever you moved the IPPWin folder. If you put the folder in your Documents folder you will only have to change [your_username] in the below.

echo “alias randomgen=‘cd /mnt/c/Users/[your_username]/Documents/IPPWin && ./ipp.sh && cd - >/dev/null’” >> ~/.bashrc

Now that that’s done we commit the changes with the below command:

source ~/.bashrc

Now, no matter what directory you’re in, running randomgen will activate the script!

Linux Instructions
  1. This guide assumes you’re using Ubuntu.
  2. Download the IPPLinux.tar.gz file from my itch.io page.
    Inside will be two folders, common and generators, along with two files, ipad3cgi and ipp.sh.
Notes

ipad3cgi is the same file that is available for download direct from NBOS here.
The common and generators folders are the folders automatically created and populated when installing the full version of IPP3 on a Windows machine, I’ve included them and standardized the naming conventions within for your convenience.
The ipp.sh file is the script I wrote to assist with the generation.

  1. Untar the IPPLinux.tar.gz folder you downloaded with the tar -xvf IPPLinux.tar.gz command and move the resulting IPPLinux folder somewhere logical, e.g. your home folder.
  2. Next, you’ll need to open ipp.sh with your favorite text editor and populate the gendir variable with the full path to the location of the generators folder. If you put the IPPLinux folder in your home folder, this should be:

gendir=/home/[your_username]/IPPLinux/generators

  1. Finally, you need to create an alias so you can call the generator from anywhere. This can be done by adding a line to your ~/.bashrc file via the below command (assuming you’re using Ubuntu). Simply change the path to wherever you moved the IPPLinux folder. If you put the folder in your home folder you will only have to change [your_username] in the below.

echo “alias randomgen=‘cd /home/[your_username]/IPPLinux && ./ipp.sh && cd - >/dev/null’” >> ~/.bashrc

Now that that’s done we commit the changes with the below command:

source ~/.bashrc

Now, no matter what directory you’re in, running randomgen will activate the script!

Once you’ve followed the instructions above you should be all set!

If you’re interested in diving into the details of how the script works feel free to read on:

Script Details

The text of the ipp.sh script for the IPPmacOS .zip is below:

IPPmacOS Script Text
#!/bin/bash

shopt -s extglob nullglob

# set gendir to the path of your IPP Generators folder
# example -  gendir=/Users/username/Documents/IPPmacOS/generators

gendir=

# Omit the following subdirectories with omitdir="directories_to_remove"
# the syntax is that of extended globs, e.g.
# omitdir="cmmdm|not_this_+([[:digit:]])|keep_away*"
# If you don't want to omit any subdirectories leave empty with omitdir=

omitdir=

# Create an array and omit directories

if [[ -z $omitdir ]]; then
   genarray=( "$gendir"/*/ )
else
   genarray=( "$gendir"/!($omitdir)/ )
fi

# remove the leading $gendir path to clean up array output

genarray=( "${genarray[@]#"$gendir/"}" )

# remove trailing backslash and insert an Exit choice into array

genarray=( Exit "${genarray[@]%/}" )

# At this point we have an array genarray indexed from 0
# containing Exit and all the subdirectories of $gendir
# (except the omitted ones if used in the above variable)

# Check that you have at least one directory in $gendir

if ((${#genarray[@]}<=1)); then
    printf 'No generators found. Exiting.\n'
    exit 0
fi

# Display the array

printf '\n'
printf 'Please choose the generator type. Enter 0 to exit.\n'
for i in "${!genarray[@]}"; do
    printf '   %d %s\n' "$i" "${genarray[i]}"
done
printf '\n'

# Ask for user input

while true; do
    read -e -r -p 'Generator Type: ' choice

    # Check that user's choice is a valid number

    if [[ $choice = +([[:digit:]]) ]]; then

        # Force the number to be interpreted in radix 10

        ((choice=10#$choice))

        # Check that choice is a valid choice

        ((choice<${#genarray[@]})) && break
    fi
    printf 'Invalid choice, please try again.\n'
done

# At this point, you're sure the variable choice contains
# a valid choice.

if ((choice==0)); then
    printf 'Canceled.\n'
    exit 0
fi

# Now you can work with subdirectory:

printf "\`%s'\n" "${genarray[choice]}"

# create new pwd variable

gendir2="$gendir"/"${genarray[choice]}"

# as $gendir2 will be edited below and you need the full path, duplicate it into $gendir3

gendir3="$gendir2"

# create a new array

genarray2=( "$gendir2"/* )

# remove leading $gendir2:

genarray2=( "${genarray2[@]#"$gendir2/"}" )

# remove trailing .ipt and insert Exit choice

genarray2=( Exit "${genarray2[@]%.ipt}" )

# At this point you have an array genarray2, indexed from 0 
# that contains Exit and all the files of $gendir2
# Check that you have at least one file in there:

if ((${#genarray2[@]}<=1)); then
    printf 'No generators found. Exiting.\n'
    exit 0
fi

# Display the array:

printf '\n'
printf 'Please choose the generator. Enter 0 to exit.\n'
for i in "${!genarray2[@]}"; do
    printf '   %d %s\n' "$i" "${genarray2[i]}"
done
printf '\n'

# Now wait for user input

while true; do
    read -e -r -p 'Your choice: ' choice

    # Check that user's choice is a valid number

    if [[ $choice = +([[:digit:]]) ]]; then

        # Force the number to be interpreted in radix 10

        ((choice=10#$choice))

        # Check that choice is a valid choice

        ((choice<${#genarray2[@]})) && break
    fi
    printf 'Invalid choice, please try again.\n'
done

# At this point, you're sure the variable choice contains
# a valid choice.

if ((choice==0)); then
    printf 'Canceled.\n'
    exit 0
fi

# Now you can work with the variable:

printf "\`%s'\n" "${genarray2[choice]}"
printf "\n"

# pull user input into # of randoms to generate

while true; do
	read -e -r -p 'How many would you like to generate? ' choice2
	if [[ $choice2 = +([[:digit:]]) ]]; then
		((choice2=10#$choice2))
		((choice2<=1000 && choice2>0)) && break
	fi
	printf 'Invalid quantity, please enter a different number.\n'
done

# call noah to run the linux binary, pass the bloated $gendir3
# into it so it can call the paths that the user selected, call
# $choice2 which is the # of randoms to generate, use iconv to
# convert any non-ISO-8859-1 to something the shell can display,
# then clean up output with sed

noah ipad3cgi "$gendir3"/"${genarray2[choice]}".ipt $choice2 | iconv -f ISO-8859-1 | sed -e 's/<[^>]*>//g' | sed '/content-type/d'

# something in the above code only makes it work when run in the directory so
# I built a dirty hack in the alias call to make it work, the dev/null hides
# the output so it's as if it works anywhere but actually isn't.  I'll probably
# never fix this so whatever

# cd [full path to IPP directory]  && ./ipp.sh && cd - >/dev/null

It is well commented so you should be able to pick it apart if you need to. The Linux and Windows scripts are identical to the macOS script above except they don’t call noah to run the ipad3cgi binary as it will run natively on Linux.

Essentially what is happening is the variable gendir is manually set to wherever the IPP generators folder is, then all the subfolders contained within are pulled into an array. If there are any directories you wish to exclude for whatever reason, you can manually omit them with the omitdir variable.

After the array is populated and cleaned up, the script asks for user input and validates that the input is a valid choice. The script then looks at the selected directory and creates another array which it cleans up and presents to the user again, just like above. This is why you can’t have more than one subdirectory for the script to work as this is the “bottom level” of the script. You could copy and paste the arrays in the script to get it to go deeper than one subdirectory; however, even IPP3 doesn’t work this way, so I suggest simply using the script as-is rather than making a complex directory tree.

After the .ipt generator file is selected by the user the script asks how many times the user would like it to generate a result. After confirming the input is valid, ipad3cgi is called (via noah if you’re on macOS) and generates the results. The results are then cleaned and converted to a displayable character encoding via iconv.

For whatever reason the script doesn’t work unless your pwd is the folder you’re running the script in. For that reason I designed the alias to cd you to the directory, then cd you back to wherever you were once it’s done running, sending any indication of that happening to /dev/null so it’s transparent to the user.

Now that you know how to use IPP3 from the CLI you’ll need some generator files to throw at it. Simply populate them inside the directories in the generators folder or create your own directories to house them!

If you’d like to contribute your own .ipt generator files to this project, please keep to the following conventions:

  • If you use any shared tables, place them in the common directory
  • When calling shared tables, please use the full path, e.g. use: common/nbos/names/Human.ipt - if you don’t it breaks the Linux release
  • When calling shared tables, please ensure you use strict capitalization (see example above) - if you don’t it breaks the Linux release

Please review the examples included in the release to assist in creating your own tables, they also adhere to the three guidelines above. If you need additional help on how to create the tables, the pdf how-to guide can be found here directly from NBOS.

Below is a running collection of .ipt tables:

  • Stay tuned!

Feel free to share your own .ipt files or ask questions below!

12 Likes

Woah, this is awesome! I don’t use a Mac but I was not aware of Inspiration Pad Pro 3 - thanks for writing this up and sharing!

You’re welcome! I’ve developed tables for both Castle Gargantua and Trilemma Adventures that I intend on releasing here soon, so keep an eye out.

1 Like

Neat, but I just use Parallels with Windows 10 in Coherence mode to run in on my iMac.

Definitely an option, albeit Parallels does have a cost.

There are several other command-line utilities I use to run my games so this fits my workflow very nicely. Usually my thought process is if I can do it in the terminal I do. Examples would be rolldice and gibberify.

With regards to the first of those limitations you mention, is that mainly an impact on how tables are saved? As in you are still able to nest a table within a table within a table for the generator? Because if so, that’s still a step up from the mobile app, which unfortunately doesn’t allow for any subdirectories - I’ve had to up my game on alphabetical file naming conventions!

Inspiration Pad Pro is a great tool. I’ve got it set up to generate all relevant Stygian Library tables with modifiable room depths, and am playing around with a more generic solo dungeon generator. Mixed with d4 Caltrops’ encounter activities, it powers pretty much my entire Barrowmaze campaign rolls at the moment.

Very handy for carrying around on a USB stick.

1 Like

Yes, this is correct. A picture speaks 1000 words:

If you added another folder under Conditions and populated .ipt files there the script wouldn’t be able to access them.

That said, the .ipt files can have nested tables and even reference each other without issue. For example, in the compiled files, the Dwarf Name.ipt file is really just

use: nbos\names\dwarf.ipt

Table: Dwarf Name
[@MasterDwarfName]

which is calling the dwarf.ipt file from the nbos\names folder.

An example of a more complex .ipt with many tables would be Orc Horde.ipt under Treasures which looks like this:

Orc Horde.ipt
Header: Stuff an orc might have on him/her/it

Table: OrcHoard
2:nothing.  poor orc is broke.
[@weapon]
2:[@stuff]
2:[@weapon], [@stuff]
2:[@weapon], [@2 stuff >> implode]
[@weapon], [@3 stuff >> implode]


Table: stuff
[@coins]
[@things]

Table: coins
{1d6} cp [@container]
{2d6} cp [@container]
{3d6} cp [@container]
{1d4} sp [@container]
{2d4} sp [@container]
{1d4} small [@gem](s)

Table: gem
topaz
garnet
polished stone
sea shell

Table: container
loose
wrapped in a piece of leather
wrapped in a piece of hide
wrapped in a leaf
in a small hide pouch
in a small leather pouch
tucked into a crude belt

Table: things
{1d6} small humanoid fingers
a bundle of {2d6} twigs
a small wooden figurine of [@carvings]
a feather headdress
a bone necklace
a stone carving of [@carvings]
a rabbit carcass
a squirrel carcass
a rotting fish
a bit of cooked meat
a small bird carcass
a horn
{1d4} torch(s)
a vial of some liquid ([@liquid])
a flask of some liquid ([@liquid])
a nice silver knife

Table: weapon
a rusty short sword
a rustly long sword
a club
a fire sharpened spear
a spiked club
a crude stone knife
a dull iron knife

Table: liquid
some ick he found by a stream
poison
an oitment for ticks
a healing salve
awful moonshine
poisonous moonshine
5:water

Table: carvings
an idol or god
a fish
a bird
a deer or horse
a bear
a orc
a human or humanoid
a design

Ah, that is wonderful. Now I am glad I never got into the habit of learning how to reference tables in other files. I always knew being lazy and inefficient would work in my favour one day! At last a use for all those long files with every possible table needed have a use.

You can reference tables in other files, sorry if I was unclear. Take a look at the post above again, I added another picture, maybe that will clear things up.

Oh no, the fault is purely from my end. Humanities graduate!

This is terrific! I have the script working on my Linux machine, though some of the generators return a “(missing)” result. For instance, Names > Hungarian > 3 spits out three names, no problem.

But Encounters > Adventure Hooks > 1 > returns “(missing)” instead.

You can see the relevant strace results here. Let me know how I can help!

PS I had to mark both the script and the binary as executable (I think linux strips these when you unzip; tarballs do not).

1 Like

One more thing:
Running

:zap: ./ipad3cgi Generators/Encounters/AdventureHooks.ipt 1

results in:

content-type: text/html

(missing)
1 Like

I think this might be because of the other .ipt scripts being not set to executable. Try running chmod -R 755 on the IPPWinLinux folder rather than just the script and binary.

My hunch is because AdventureHooks.ipt is actually just calling a different file under Common\nbos called AdventureHooks.ipt and I’m assuming something is getting messed up in the permissions there.

Let me know if that fixes it.

It did not! To be clear, I made all contents executable with:

chmod -R 755 IPPWinLinux
1 Like

Hm.

I uploaded a tarball of the files - try downloading it here. Extract with tar -xvf IPPWinLinux.tar.gz and populate the gendir variable inside the ipp.sh script, update the alias to the new location (or remove the old extraced files) then see if it works.

What version of Linux are you running?

Same issue, I’m afraid. I am running Xubuntu 19.10 (64bit, obviously).
Rather than filling up the thread, I’ll PM you from here on out!

1 Like

I’ve made the first post a wiki, as discussed here so now everybody with TL1+ can add their ipt files.

1 Like

What do we do if someone with TL1 links to a script with malicious intent?

TL1 is pretty easy to obtain and I’m not sure I’m comfortable with people able to change the script links to somewhere else.

Is there any way to lock a portion of the wiki post to only be edited by me? Will I be notified if the wiki is edited and I just need to watch it like a hawk?

Now it requires TL2+.

1 Like

Thanks @thekernelinyellow, this should secure everything.

@yochaigal - based on your feedback I’ve fixed the Linux release. The permissions issues were resolved by using a tar rather than a zip, and I’ve fixed the pathing issues by slightly changing the file structure. Thank you again for your troubleshooting assistance!

I’ve gone through and updated the guide to accommodate these changes and also taken new screenshots.

If you have any other feedback to make the tool better please let me know, thanks!

1 Like