grifferz / pah-irc

Perpetually Against Humanity, IRC Edition
Artistic License 2.0
11 stars 10 forks source link

Perpetually Against Humanity, IRC Edition (pah-irc)

What?

It's another IRC bot for playing Cards Against Humanity™. Cards Against Humanity is a trademark of Cards Against Humanity LLC.

Wikipedia describes it as:

a party game using cards. It is available as a free download that players can print to create their own cards, and also available to purchase in published hardcopy.

Here's some logs from a real game of Perpetually Against Humanity.

Why?

There's quite a few IRC bots for this already, but it struck me that none of them particularly played to IRC's strengths, those being:

Usage

Quite a few interactions with the bot will be fairly natural language and depend on context, for example:

<AgainstHumanity> We need 3 more players to get this game started. Who else wants to play? Say "AgainstHumanity: me" if you'd like to join in.

<grifferz> AgainstHumanity, me

<AgainstHumanity> Great, you're in! 2 more players needed…

Which hopefully doesn't need to be documented.

Public channel commands

Public channel commands should be addressed to the bot by just sending a message to the channel with the bot's nickname as the first word. In the documentation we'll assume that the bot's nickname is AgainstHumanity, so for example:

AgainstHumanity status

AgainstHumanity: status

AgainstHumanity, status

are all fine.

Private commands

These commands can be given in private message to the bot. Again there are some interactions that are more natural, in response to the state of the game.

Many commands optionally take a channel parameter. This is only needed if the player is in more than one active game. That's fairly unlikely so most of the time that can be left off and the bot will work it out.

Installation

You can find the dependencies in the cpanfile, but you may find it simpler to install them all into a local directory with cpanminus:

$ cpanm --local-lib=./pah-libs --installdeps .

Or if you'd rather use CPAN modules for everything that's not core Perl:

$ cpanm --local-lib-contained=./pah-libs --installdeps .

IRC nickname

Now is a good time to register an IRC nickname for the bot to use. It can help with flooding to also make sure the bot is voiced in channels it's likely to be used in, but it will still work if not.

Configuration file

The example configuration file at etc/pah-irc.conf.example should contain enough comments and the default values for you to be able to work this out. Just copy it to etc/pah-irc.conf and then edit it to suit.

Database

The bot currently uses an SQLite database file. I've tried to use unexciting SQL though so it should be simple to make it work with other DB engines. Please submit an issue if you need that.

Before your first run of the bot you'll need to create the database like so:

$ bin/upgrade_db
DBIx::Class::Schema::Versioned::_on_connect(): Your DB is currently unversioned. Please call upgrade on your schema to sync the DB. at bin/upgrade_db line 41

An empty SQLite 3 database file will then exist at var/pah-irc.sqlite, which you can examine with:

$ sqlite3 var/pah-irc.sqlite '.tables'
bcards                      users_games               
channels                    users_games_discards      
dbix_class_schema_versions  users_games_hands         
games                       wcards                    
users

…and so on.

Database upgrades

If you've pulled new code or downloaded a newer release then the bot may refuse to start, telling you that your database schema is outdated. Running bin/upgrade_db again should upgrade you to the new schema without losing any data. Take backups, though!

Start / stop / restart

bin/pah-irc-init [start | stop | restart ]

Logging will end up at var/pah-irc.out. The logging tries not to give spoilers so it's safe to look at even if you're one of the players.

/invite it to a channel

Once the bot is on IRC and identified to a nickname it can be /invited to channels and issued a start command to get things going.

Flooding

The game can be rather verbose, both in the channel and in private message to players. If you aren't careful then the IRC server will probably flood-limit the bot by dropping its messages or even disconnect it from the network.

The default bot configuration allows for a burst of 10 messages and thereafter will send only one message per second until there has been a pause of 10 seconds again. This appears to be enough to avoid flood-limiting on networks that use Charybdis or ircd-seven (e.g. Freenode).

Freenode IRC operators have told us that voicing the bot in a channel will exempt it from some flood checks both to the channel and to users who share the channel with the bot.

If you are in a position to further exempt the bot from flood limits (i.e. you have access to the IRC server configuration, or know someone who will modify it for you) then you can adjust the bot's own flood limiting by altering the msg_per_sec and msg_burst configuration options.

Security

This bot is relying on the IRC network having IRC services and an IRCd that exposes the identified status of the user in the WHOIS reply. Charybdis IRCd is known to do this, so this should work on IRC networks like Freenode.

You will not be able to start a game nor participate in one unless you have a registered nickname and are identified to it.

Should you drop or abandon your registered nickname and it is later registered by someone else then they will be able to play games of Perpetually Against Humanity as "you".

On a technical note this means that for every privileged command, the bot is doing a WHOIS command and waiting for the response to see if the user is actually identified to a nickname before it does anything with the command. That may seem slow, but I took this approach in a previous bot (Enoch quote bot) and it seemed to be unnoticeable. I'm prepared to add caching later if it becomes a problem.

Restarting the bot

Pretty much all game state is kept in the database so it should be safe to kill and restart the bot at any time.

Speed of play, or lack thereof

If you haven't got the hint yet, the idea here is not to stress about games being very slow-moving. They can just kind of happen in their own time. There isn't any end.

What happens when someone ignores their responsibility though? At the moment we're trying forced resignations after a timeout (the turnclock in the config file).

There's only two responsibilities in Perpetually Against Humanity:

If that doesn't happen in a reasonable amount of time—and for now we'll go with 2472 hours being a reasonable amount of time—then the player responsible has timed out of the game. For now we'll treat that like resigning.

For a Card Tsar that means:

  1. The current round is abandoned
  2. No one gets any Awesome Points
  3. Any played White Cards will be discarded.
  4. The Card Tsar's own hand is discarded.
  5. If there's still at least 4 players, the next player becomes Card Tsar and play continues. Otherwise the game is paused until more players join.

For anyone else that means:

  1. The White Cards in their hand, including any White Cards played in the current round, are discarded.
  2. If there's still at least 4 players then play continues, otherwise play is paused until more players join.

So, a person who goes unresponsive can hold up a game for a while, but games aren't necessarily meant to be quick-fire anyway because they are never going to end. Players who know they need to stop playing (e.g. because they aren't going to be on IRC for a while) can be helpful by explicitly resigning.

We tried for a while with 24 hours as the turnclock, but we found that some regular weekday players who don't IRC at weekends ended up getting kicked out. So, now we're trying 72 hours (3 days).

Card packs

Current releases have:

(Emphasis on the UK because most of the IRC channels using this are UK-biased)

If you are willing to type up more card content then please do so and send a pull request.

The bot can use any combination of packs via the packs configuration directive. At the moment this is a global setting, so all games will need to use the same combination of packs. A per-game deck selection will follow in a later release.

License

This IRC bot is made available under the Artistic License, the same as Perl itself.

Cards Against Humanity card content is used under a Creative Commons BY-NC-SA license.

Bugs

Undoubtedly many.

I don't really know what I am doing, programming-wise, but I know at least that having a single module file with 5,000 lines in it is not sane.

So, I'd appreciate any bug reports, assistance or advice. Please be gentle!

Issues can be reported on github.