{"id":22270306,"url":"https://github.com/jifish/storyteller","last_synced_at":"2026-03-09T14:33:36.052Z","repository":{"id":96150214,"uuid":"121452318","full_name":"JiFish/Storyteller","owner":"JiFish","description":"A Slack / Discord Bot for playing Gamebooks","archived":false,"fork":false,"pushed_at":"2020-05-17T15:06:29.000Z","size":949,"stargazers_count":4,"open_issues_count":2,"forks_count":4,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-28T13:37:47.438Z","etag":null,"topics":["alice-in-wonderland","alices-nightmare-in-wonderland","bot","chatbots","crystal-maze","discord","discord-bot","discordbot","fighting-fantasy","firetop-mountain","game","lone-wolf","narnia","php","slack","slack-bot","slack-webhook","slackbot","sonic-the-hedgehog","storyteller"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JiFish.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-02-14T00:13:42.000Z","updated_at":"2024-01-25T05:26:55.000Z","dependencies_parsed_at":"2023-03-16T04:00:21.796Z","dependency_job_id":null,"html_url":"https://github.com/JiFish/Storyteller","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/JiFish/Storyteller","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JiFish%2FStoryteller","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JiFish%2FStoryteller/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JiFish%2FStoryteller/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JiFish%2FStoryteller/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JiFish","download_url":"https://codeload.github.com/JiFish/Storyteller/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JiFish%2FStoryteller/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30299108,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-09T13:46:43.843Z","status":"ssl_error","status_checked_at":"2026-03-09T13:46:42.821Z","response_time":61,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["alice-in-wonderland","alices-nightmare-in-wonderland","bot","chatbots","crystal-maze","discord","discord-bot","discordbot","fighting-fantasy","firetop-mountain","game","lone-wolf","narnia","php","slack","slack-bot","slack-webhook","slackbot","sonic-the-hedgehog","storyteller"],"created_at":"2024-12-03T12:08:00.934Z","updated_at":"2026-03-09T14:33:36.043Z","avatar_url":"https://github.com/JiFish.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Storyteller\n## A Slack / Discord* Bot for playing Gamebooks (v2.0)\n\n## Introduction\nStoryteller is a bot for use with Slack which helps a group of people play\nthrough a gamebook co-operatively. It was designed for _Fighting Fantasy_, but\ncan now play a number of different gamebook types, including _Lone Wolf_.\n\nIt should work with almost any gamebook.\n\nStoryteller adds commands to read the story, manage your character and roll\ndice for fights and other challenges. It will assist you in playing the game\nbut does not strictly enforce rules - replicating the experience of playing\nwith a real book and dice.\n\nStoryteller is programmed in PHP, requires no database and is state-based. This\nmeans it can be installed on an ordinary web-server.\n\n* Discord is also supported, with some caveats, see *Using Discord* below.\n\n## Book Support\n\nAnything without a character sheet is supported, this includes the\n_Choose Your Own Adventure_ books.\n\nThe following _Fighting Fantasy_ books currently work very well: Battleblade\nWarrior, Black Vein Prophecy, Bloodbones, Caverns of the Snow Witch, The\nCitadel of Chaos, City of Thieves, Creature of Havoc, Crypt of the Sorcerer,\nDeathmoor, Deathtrap Dungeon, Demons of the Deep, Eye of the Dragon, The Forest\nof Doom, House of Hell, Island of the Lizard King, Legend of Zagor, Masks of\nMayhem, Portal of Evil, Rebel Planet, Return to Firetop Mountain, Scorpion\nSwamp, Seas of Blood, Starship Traveller, Stealer of Souls, Talisman of Death,\nTemple of Terror, Trial of Champions, The Warlock of Firetop Mountain. Most\nother can still be played.\n\nThe first 20 _Lone Wolf_ books have good support, as do the 8\n_Lone Wolf: New Order_ books.\n\nThe following other books / series are supported: Alice's Nightmare in Wonderland,\nThe Crystal Maze Adventure, The Sonic The Hedgehog Gamebooks, The Narnia Solo\nGames books.\n\nThe full list of supported books is here:\nhttp://htmlpreview.github.io/?https://github.com/JiFish/Storyteller/master/extras/book_support.html\n\n## Set-Up\nDownload and unzip. Place on a webserver running PHP. PHP7 is recommended.\n\n### 1. Set-Up Slack\nFirst you must create an incoming and outgoing webhook. In Slack, go to\n**Administration \u003e Manage Apps \u003e Custom Integrations**.\n\n#### Incoming Webhook\n![Incoming hook example](../master/extras/slack_incoming_hook_example.jpg)\n\n- Set the channel to where you want the story to be told. You will probably\nwant to dedicate a channel to the story.\n- Give the bot a good name. I suggest Storyteller or StorytellerBot.\n- **Make a note of the Webhook URL.** Open `config.ini` and set `slack_hook` to\nthis URL.\n\n#### Outgoing Webhook\n![Outgoing hook example](../master/extras/slack_outgoing_hook_example.jpg)\n\n- Set the channel to the same channel as the incoming hook.\n- Set the trigger word. I suggest using `!` to keep things simple. The trigger\nword must be prefixed to every command.\n- Set the URL to where your installation will be located.\n- **Make a note of the Webhook Token.** Open `config.ini` and set `slack_token`\nto this value.\n\n### 2. Get the story\nBy default Storyteller ships with a very short and simple sample book. It isn't\nvery fun, so you'll likely want to replace it. You have 3 options.\n\n#### Option 1: Install Lone Wolf books\nJoe Dever has generously allowed Project Aon to host copies of the Lone Wolf\ngamebooks. I've provided a tool that downloads the books ready for use. If\nyou go with this option, the config.ini file will be updated for you, and you\ncan skip section 3. Run the script and follow the on-screen prompts:\n```\nphp tools/install_lonewolf.php\n```\n\nIt is your responsibility to comply with with the Project Aon Licence. Also,\nconsider making a donation: https://www.projectaon.org/\n\n#### Option 2: Import a book you own\nStoryteller comes with two tools for importing existing texts: one for plain\ntext and one for htmlz. Use htmlz if your book has images. If you own the\nbook in a eBook format, you can use the tool calibre (https://calibre-ebook.com/)\nto convert it to one of these two formats.\n\nMany books, notably Fighting Fantasy, are not currently available in eBook\nformats. Your only option here is to scan and OCR the text yourself!\n\nThe text is converted to a php array. See `jofm.php` in *books* for an example\nbook. The converters aren't perfect and you may need to clean up the output\nmanually.\n\n##### Import from plain text .txt file\nUse the bookconvert.php script in the *tools* directory e.g.\n```\nphp tools/bookconvert.php mybook.txt mybook\n```\n\n##### Import from .htmlz file\nhtmlzconvert.php will attempt to extract images from the book to Storyteller's\nimages directory at the same time as converting the text.\n```\nphp tools/htmlzconvert.php mybook.htmlz mypicturebook\n```\n\n#### Option 3: Write your own adventure\nPerhaps one of the best ways to get a story in to the bot is to write your own.\nChoose a set of supported rules you like and come up with your own adventure.\nIf anyone does do this, please consider submitting your story back here. I'd\nlove to include longer stories with this distribution.\n\n### 3. Add your book to config.ini\nOnce you have your book php file, put it in the `books` directory. Next add a\nnew section to `config.ini` for your book.\n\n- The section name will be used as the book id.\n- `name` is the full title of the book.\n- `file` is the php file from step 2.\n- `rules` is the ruleset to use for the book. This controls which stats are\navailable, the character sheet and ensures character generation matches the\nbook. You can look up the correct book type in `book_support.html` found in\nthe *extras* directory. Use `none` for books with no character sheet.\n\nHere is an example section:\n```\n[wofm]\nname = \"Warlock of Firetop Mountain\"\nfile = books/wofm.php\nrules = ff_wofm\n```\n\nSet `default_book` under `[general]` to your book id.\n\n### 3a. Add book images (optional)\n\nCreate a directory in `images` with the name of your book id and copy in\nillustrations. The images should be named after the page number e.g.\n`42.jpg` or `1.png`\n\n### 4. Adjust other config.ini settings (optional)\n\nYou may wish to adjust other settings in config.php at this point. You might\nlike to remove `save` and `load` from the disabled commands list. This will\nallow players to use save-points. Alternatively, you could add the `undo`\ncommand to this list if you want to prevent players from undoing their\nmistakes.\n\n### 5. Get the code online\n- Upload the installation to your PHP enabled web-server. No database is\nneeded. The uploaded directory must be writeable.\n- Make sure it's location matches what you step up for the outgoing hook in\nstep 1. If it's different go back and alter the hook.\n- If you are _not_ using apache, you must replicate the rules in `.htaccess` to\nensure the installation is secure.\n\n### 6. Ready to play!\nType `!library` in the channel you chose for the webhook to see a list of available\nbooks and open one with the `!book` commands shown.\n\nType `!0` to read the background page and `!1` to start the story. When the\nstory tells you to turn to a page or section, you can read it in the same way,\ne.g. `!42`.\n\nFor games with character sheets, like Lone Wolf or Fighting Fantasy, the use\n`!newgame` to roll a character.\n\n`!help` will list other commands available for the open gamebook.\n\n## Using Discord\n\n### 1. Outgoing hook replacement\nThe bot can also be used for Discord. The biggest limitation is Discord does\nnot support outgoing hooks. You can work around this one of two ways:\n1. Run a discord bot to emulate outgoing hooks. There's a working python\nexample `discord_oghook_bot.py` in the *extras* directory. Setting up a discord\napp account and getting tokens ready etc. is left as an exercise for the\nreader.\n2. Expose `input.php` by editing `.htaccess`. This will allow entering commands\nby submitting a URL like\n`http:\\\\yourdomain.com\\storyteller\\input.php?c=!echo%20Hello%20World!` You\ncould submit this with a form (see `example-form.html` in the *extras*\ndirectory.) Or use your imagination!\nIf you come up with a creative input method, please consider submitting it back\nhere!\n\n### 2. Other complications\n- Don't forget to add `/slack` to the end of your discord incoming hook to make\nit slack compatible. It will look like\n`https://discordapp.com/api/webhooks/0123456789/YOURCODEHERE/slack`\n- Set `discord_mode` to true in `config.ini`. This will ensure messages are\nformatted correctly for Discord.\n- Ensure `images/emoji_cache` is writeable. Discord does not support emoji\navatars, so emoji PNGs are cached and sent instead. This will cause a short\ndelay when using an emoji for the first time.\n\n## Usage Tips and Hints\n- Remember, you have to enforce the rules!\n- `!help` to see some basic commands. Help will be customised depending on the\nruleset.\n- If a book adds complications to the normal `!fight` rules. Check `!help`\nto see if there is parameter or alternate command that can help you. The\nFighting Fantasy rulesets has several alternate fight rules programmed. Most\nothers allow you to stop fights after a given number of rounds.\n- If the book asks you to do something there isn't a command for, you can\nalways roll dice with `!roll` and apply any effects manually.\n\n## Legal\nIt is YOUR responsibility to comply with copyright laws and determine what is\nfair-use.\n\n## Technical Information\n**Do you accept bug reports?**\n\nYes. Particularly security issues should be reported. Please provide a test\ncase and post it on the github project's issue page.\n\n**What about support requests and feature ideas?**\n\nSure. You can also post them on the issues page. No promises though.\n\n**Will you support other books?**\n\nI'd like to. Please make requests on the issues page.\n\n**What about pull requests / patches etc.?**\n\nGladly.\n\n**What about a proper bot that isn't state-based / support for other chat\nsoftware?**\n\nI'd like to do this, but I'm not sure how to best achieve this with PHP. This\nis why the discord outgoing hook bot is written in python.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjifish%2Fstoryteller","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjifish%2Fstoryteller","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjifish%2Fstoryteller/lists"}