Code Monkey home page Code Monkey logo

bot-on-the-clocktower's Introduction

Bot on the Clocktower

A Discord bot to assist with running a game of Blood on the Clocktower on Discord

This bot handles setting up all the channels, roles, and permissions you need to play Blood on the Clocktower, as well as moving the players back and forth during the various phases of the game without needing to type in complex movement commands!

Invite the Bot

First, you need to >> invite the bot <<

For more information on the permissions it requests, see Permission Details.

Quick Start: /createtown

To quickly set up your town, simply send a command to the bot with the name of your town. You can also specify whether you'd like to use the "Night Category" with Cottages via the usenight param - some players don't use it.

/createtown townname:"Ravenswood Bluff"

This will create all the categories, channels, and roles needed by Ravenswood Bluff.

The bot supports more than 1 town per Discord server. With 2 differently-named towns, you can run 2 games at once on the same server.

Explanation of the Setup

For more information on precisely what this command does (what categories, roles, and permissions are created), see the Setup Details and Command Details documentation.

Gameplay

All players can gather in the Town Square channel while the Storyteller sets up the game on http://clocktower.online (or whatever mechanism your group uses).

When it's time for Night 1 to begin, the Storyteller should use the /game command to start a new game.

image

From here, they can hit the Night button to move into the Night phase of the game.

Initial Evil Info

If desired, to distribute the Minion and Demon info (but not the Demon bluffs), the Storyteller can use the /evil command (see Command Details) to quickly send messages to all the Evil players informing them of their teammates.

Night Phase

During the Night, the Storyteller can visit Cottages as dictated by the night order (the players are alphabetized into the Cottages to make finding players easier). The permissions are set up to allow the Storyteller to screen-share with users in the Cottages (for instance, to show the Grimoire to the Spy or Widow).

Once the night phase is complete, the Storyteller presses the Day button (or uses the /day command) to bring the players back to the Town Square and begin the day.

Day Phase

Players can switch to other Daytime channels to have semi-private conversations until the Storyteller is ready to open nominations. The Storyteller may use the Vote button (or /vote command) or set a Vote Timer using the dropdown (or /voteTimer command) to drag all the players back to the Town Square.

This cycle of night & day continues until there's a winner!

If you'd like to start a new game with a new Storyteller, the new Storyteller can run /game, /night or any other command when ready to take over Storytelling duties.

Once you're all done playing, a Storyteller can optionally push the End Game button (or run /endgame) to remove roles and nicknames, generally cleaning up the town (though the bot will run this automatically after a few hours).

If you have more than one Storyteller, check out the /storytellers command in the Command Details.

A Word About Rate Limits

Discord sometimes limits how many commands a bot can execute in a given timeframe (for good reason).

This is most noticeable when you run /night, /day, or /vote in larger groups - frequently only some (usually about 10) of the players will initially be moved, and there will be a delay of several seconds before the rest are moved.

This is normal behavior and not something to worry about! Just be patient and everyone will move eventually. Make sure you wait for everyone to wake up from their cottages in the morning!

The bot randomizes the order people are moved in, so it won't end up leaving the whole evil team with 10 extra seconds to plot by coincidence.

If you run into much longer delays, failures to move, or other errors, do let us know, however.

Command Details

For full details of all the supported commands, see the Command Details documentation.

Permission Details

The bot requests the following permissions:

Permission Why?
Manage Channels To create/destroy channels and categories with /createtown and /destroytown commands
Manage Roles To grant/remove Storyteller and Villager roles
To create/destroy roles with /createtown and /destroytown commands
Manage Nicknames To add/remove (ST) for the Storyteller's nickname
Move Members To move players to nighttime rooms or back to the Town Square
Manage Messages To delete /evil command messages so players can't see who's evil
View Channels Required for many operations
Send Messages Required for many operations

Support

I can be contacted on Discord at lilserf#8712 with any issues or questions. In general, please file a Github issue with lots of details if you run into problems. Of course, we're just doing this in our spare time and the bot features have primarily been driven by what our local play group needs, so please be patient.

bot-on-the-clocktower's People

Contributors

coreyschulz avatar lilserf avatar magroader avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

bot-on-the-clocktower's Issues

Add Spectators

Similar to Storytellers, Spectators could have their names prefixed/suffixed and can be thrown into the same cottage together at night.

quick town setup command?

When run from the control channel, it would infer as much as possible via naming/regexes:

  • assume the control channel is in the Day category
  • assume the night category is "{day} - Night"
  • assume the roles are "{day} Storyteller" and "{day} Villager"
  • assume the first voice channel in the Day category is Town Square

!destroytown Not destroying some number of cottages as well as the Graveyard

Doing:

!createtown TestTown

Followed pretty immediately by:

!destroytown TestTown

Appears to fail to destroy some stuff. Message:

I destroyed what I knew about for Town TestTown2.

I did not destroy some things I was unfamiliar with:

  • TestTown2 - Night / Cottage (channel)
  • TestTown2 / Graveyard (channel)

You can destroy them and run this command again.

I did not destroy these things yet, just in case you still need them:

  • TestTown2 - Night (category)
  • TestTown2 / botc_mover (channel)
  • TestTown2 (category)
  • TestTown2 Villager (role)
  • TestTown2 Storyteller (role)

However, as far as I can tell, the Cottage and the Graveyard DID get destroyed. So there appears to be a bug where it thinks it didn't destroy the Graveyard, or something. Might be a lag issue of some kind, may need to tweak how we determine whether a channel was destroyed.

Running it again works fine.

!legion command

!legion is like !evil, but:

  • Everyone is "the demon"
  • There CAN be minions, but usually not. Not sure how to handle that!
  • Should also tell the Legion members who is NOT Legion, as that would be a lot easier information to digest
  • They all get the same not-in-play roles

I think this would be easier to handle as 1 command rather than visiting each person individually. But I dunno what the syntax should be.

Auto cleanup no longer working

For the last 2 weeks, the automatic cleanup of the game has not worked. I'm guessing it's hitting an exception somewhere and aborting

!help text is cut off

Lots of ...s hide text:

​Commands:
  currgame Set the current users in all standard BotC voice channels as playe...
  day      Move users from Cottages back to Town Square
  evil     Send evil info to evil team. Format is `!evil <demon> <minion> <mi...
  help     Shows this message
  lunatic  Send fake evil info to the Lunatic. Format is `!lunatic <Lunatic> ...
  night    Move users to Cottages in the BotC - Nighttime category
  vote     Move users from other channels back to Town Square

!destroyTown could be smarter/safer

It could use the DB to pull data on what channels/categories etc to remove instead of assuming they have certain names

It could also be used within the control channel with no parameters if we want

Add optional timer to !day -> !vote

  • Add a way that you can specify a number of minutes when you start the !day phase
  • After N-1 minutes the bot will post a 1-minute warning to the players (or to the text chat if we add knowledge of the text chat)
  • After N minutes the bot will auto-run the !vote command

Allow N Storytellers

Suggestion:

!setStorytellers Colin Mark

If one of the mover commands is used by someone who is NOT in the current Storyteller list, it should clear the previous Storytellers and set the 1 who used the command.

!endgame should also clear the STs

Ability to have 2 separate games on the same server

Depends on #5

We're getting to the point where we are almost full up for a single game of BotC, with around 12-13 players. If we eventually hit 16 players, that's sort of 1 too many (although travelers can alleviate that) and there's a LOT of crosstalk. It may very well be better, in such a case, to split up into 2 groups (8 players and 7 players, or more).

In order to facilitate this, the mover bot would need some extra sauce:

Assuming there will be 2 separate #botc_mover channels, and that each of those represents its own game. For each #botc_mover channel:

  • It needs to be able to set what the nighttime category is (e.g. !set nightcategory <id or string>)
  • It should be able to figure out what the daytime category is, as the #botc_mover channel is already in that category, so no extra command likely required there.
  • It needs to be able to set what the Current Storyteller Role is (e.g. !set strole <id or string>)
  • It needs to be able to set what the Current Player Role is (e.g. !set playerrole <id or string>)

More sanity checking in addTown

  • Check that there are "enough" channels in the day category and recommend more
  • Check that there are "enough" Cottages in the night category and recommend more
  • Check that the night category has the right perms for the category as a whole (only visible to current players?) and on the cottages (only visible to storyteller)

No need of else statement

class botcBot -> function getTownInfo. There's no need to else statement there.

Explanation:
If the IF statement returns True it will return TownInfo(ctx.guild, doc) and jumps out of the function else the interpreter will go to the next line and then it will return None and jump out of the function.

!currgame fails for unknown reasons

TypeError('sequence item 0: expected str instance, Member found',) (from message !currgame)

I thought this was because nobody was in a voice channel but it happened even when I was in a voice channel

!endgame command to reset everything

  • Remove person-specific permissions from all the cottages
  • Remove "(ST) " from storyteller name
  • Remove current game and current storyteller roles

Change support to use built-in Discord slash commands

As of May 4, 2021, Discord added some first-class support for slash commands, including autocomplete. Bot on the Clocktower should make use of this (perhaps only if it has Slash Command permission for the server?)

New slash commands for bots! Performing actions with bots is easier than ever. Bot developers—when they’re ready, please don’t scare them—can have a list of commands available for their bots accessible by the forwardslash key (/). You won’t have to remember bot commands anymore and get laughed at when you get the command wrong :( !help…..!help….please

Added use Slash Commands permission. If you run a server, make sure to configure this permission for your bot channels. Bots that upgrade to Slash Commands require this permission.

Have the bot announce new versions somehow

  • Possibly respond when you start a new game
  • Possibly just post into the control channel when it starts up
  • But only once per version
  • And only if there is a big enough feature to announce

Not removing cottage permissions from previous storyteller

  • I was ST
  • Tommy did !currgame and !night
  • Our roles were updated correctly
  • Our (ST) nickname was updated correctly
  • However, I still have permission to see Tommy's cottage (along with Tommy)

image

So something about when we swap storyteller in this way is not properly updating the Cottage view permissions

Interactive town setup / creation

This would talk to a user (via DMs?) and interactively add a town by asking questions

Alternately, this flow could even create the channels for a town with the correct permissions etc (though that would require new permissions on the bot)

bug: !endgame command misses some features, has error

I used !endgame with nobody in the Town Square, and nothing happened.
Then I remembered that someone usually has to be connected, and I used it again. Here's what happened:

  • It appears everyone lost the BotC Current Player role
  • I lost the BotC Current Storyteller role
  • I still had permissions to view ONE of the Cottages
  • I still had (ST) in front of my name

I then though maybe doing it first when not in Town Square was a problem, so I did !curgame (typo!) followed by !endgame. Same visible results after !endgame, but I was also sent this error:

Traceback (most recent call last):
  File "bot.py", line 114, in onEndGame
    await prevSt.remove_roles(stRole)
AttributeError: 'NoneType' object has no attribute 'remove_roles'

I then realized the command was actually !currgame, so I tried again to do !currgame !endgame. This time, the Cottages went away, but I still had (ST) on my name, and I got the whisper with the same error above again.

Web-based Control Panel

I don't know how easy this is, but some bots have a web-based control panel that can be used to poke at a bot, rather than needing to send messages to a channel. This would be a super cool API, and something you could pop out to another window and use buttons to (for example) switch to night and day.

Option to clean up chat channel periodically

We play weekly, and many weeks when the first night starts I notice we have a chat channel full of messages I haven't read from the previous week. This is usually because I storytell the last game, and don't have time for the chat channel anyway.

There should be an option to, probably during periodic cleanup, clear out the chat channel. It's intended to be a temporary thing just for the current game anyway, so I think we would set this option on our Town.

Periodic cleanup of unreachable guilds / day categories

Presumably people will not always tell our bot when they don't want it anymore (kick from guild) or have removed their day categories, but we'll still have data about them sitting around in the DB.

This task is to have a (weekly?) maintenance task to check on towns and see if we can still access the guild/day category. If we can't, then we might as well eject them from the db.

If not None (inverse logic)

You can use inverse logic in the code below

Actual code:

if info is not None:
            await self.sendEmbed(ctx, info)
        else:
            await ctx.send("Sorry, I couldn't find a town registered to this channel.")

Suggested code:

if info:
          await self.sendEmbed(ctx, info)
else:
            await ctx.send("Sorry, I couldn't find a town registered to this channel.")

There are many lines of code very you can apply this improvement.

issue with town "Murdertown" in @magroader's server

Moved the storyteller to their cottage but then failed to set the permissions on that cottage

  File "bot.py", line 941, in onNight
    await cottage.set_permissions(user, view_channel=True)
  File "/app/.heroku/python/lib/python3.6/site-packages/discord/abc.py", line 658, in set_permissions
    await http.edit_channel_permissions(self.id, target.id, allow.value, deny.value, perm_type, reason=reason)
  File "/app/.heroku/python/lib/python3.6/site-packages/discord/http.py", line 241, in request
    raise Forbidden(r, data)
discord.errors.Forbidden: 403 Forbidden (error code: 50013): Missing Permissions

Better error message when not allowed to change nickname

If the person whose nickname needs to be changed has a role higher in the role list than the bot - including being the owner of the server - then the error message is messy. We should catch this error message and send an explanation about what can be done to fix it, e.g.:

Attempted to change nickname "Colin" to "(ST) Colin" but was unable. This is likely for one of these reasons:

  • Colin has a role that is higher in the role list than the Bot on the Clocktower role
  • Colin is the owner of the server
  • Bot on the Clocktower needs to be re-invited to the server to grant it nickname-changing permissions

This could be sent to the mover channel rather than being a private message

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.