Code Monkey home page Code Monkey logo

matrix-dicebot's Introduction

Tenebrous Dicebot

Build Status Matrix Chat

This repository is hosted on Agnos.is Git and mirrored to GitHub.

This is a dice rolling bot for facilitating roleplaying games on the Matrix messaging platform. It currently has basic support for the Chronicles of Darkness 2E Storytelling System and Call of Cthulhu, with plans to extend the codebase further to support other systems and character sheet management.

Features

tenebrous-dicebot is a dice rolling bot for facilitating role-playing games over Matrix (and anything that Matrix can bridge to, like Discord). It currently has the following features:

  • Rolling arbitrary dice expressions (e.g. 1d4, 1d20+5, 1d8+1d6, etc).
  • Rolling dice pools for the Chronicles of Darkness 2E Storytelling System.
  • Rolling dice for the Call of Cthulhu system.
  • Works in encrypted or unencrypted Matrix rooms.
  • Storing variables created by the user.

Support and Community

The project has a Matrix room at #tenebrous:agnos.is. It is also possible to make a post in GitHub Discussions.

For reporting bugs, we prefer that you open an issue on git.agnos.is. However, you may also open an issue on GitHub.

Development and Contributions

All development occurs on git.agnos.is. If you wish to contribute, please open a pull request there. In some cases, pull requests from GitHub may be accepted. All contributions must be licensed under AGPL 3.0 or later to be accepted.

Building and Installation

Docker Image

The easiest way to run the dice bot is to use the official Docker image. It is distributed on GitHub Container Registry by a CI pipeline.

The latest tag always points to the most recent successfully built master commit and is considered unstable, while individual tags are considered stable.

  • Unstable: docker pull ghcr.io/projectmoon/chronicle-dicebot:latest
  • Stable: docker pull ghcr.io/projectmoon/chronicle-dicebot:X.Y.Z

This image is based on Void Linux. To build the image yourself, run docker build -t chronicle-dicebot . in the root of the repository.

After pulling or building the image, see instructions on how to use the Docker image.

Install from crates.io

The project can be from crates.io. To install it, execute cargo install tenebrous-dicebot. This will make the following executables available on your system:

  • dicebot: Main dicebot executable.
  • dicebot-cmd: Run dicebot commands from the command line.
  • dicebot_migrate: Standalone database migrator (not required).
  • tonic_client: Test client for the gRPC connection (not required).

Build from Source

Precompiled executables are not yet available. Clone this repository and run cargo install.

Building the project requires:

  • Basic build environment (build-essential on Ubuntu, base-devel on Void and Arch, etc).
  • Rust 1.45.0 or higher.
  • OpenSSL/LibreSSL development headers installed.
  • olm-sys crate dependencies: cmake, libstdc++.
  • glibc.

Why doesn't it build on musl libc?

As far as I can tell, the project doesn't build on musl libc. It certainly doesn't build a static binary out of the box using the rust-musl-builder. This appears to be due to a transitive dependency of the Rust Matrix SDK.

Any PRs to get the project or Matrix SDK to properly be built into a static binary using musl would be very useful.

Usage

To use it, you can invite the bot to any room you want, and it will automatically jump in. Then you can simply give a dice expressions for either the Storytelling System or more traditional RPG dice rolls.

The bot supports a !help command for basic help information about its capabilities.

Basic Dice Rolling

The commands !roll and !r can handle arbitrary dice roll expressions.

!roll 4d6
!r 4d7 + 3
!r 3d12 - 5d2 + 3 - 7d3 + 20d20

Keep/Drop Dice

The bot supports either keeping the highest dice in a roll, or dropping the highest dice in a roll. This allows the bot to handle things like D&D 5e advantage or disadvantage.

!roll 2d20k1
!r 2d20dh1 + 5
!r 10d10k5 + 10d10dh5 - 2

Storytelling System

The commands !pool (or !rp) and !chance are for the Storytelling System, and they use a specific syntax to support the dice system. The simplest version of the command is !pool <num> to roll a pool of the given size using the most common type of roll.

The type of roll can be controlled by adding n, e, or r before the number, for 9-again, 8-again, and rote quality rolls. The number of successes required for an exceptional success can be controlled by s<num>, e.g. s3 to only need 3 successes for an exceptional success. All modifiers should come before the number, with a : colon.

Examples:

!pool 8      //regular pool of 8 dice
!pool n:8    //roll 8 dice, 9-again
!pool ns3:8  //roll 8 dice, 9-again with only 3 successes for exceptional
!pool rs2:5  //5 dice, rote quality, 2 successes for exceptional

Call of Cthulhu System

The commands !cthRoll, !cthroll, !cthARoll and !cthadv are for the Call of Cthulhu system. !cthRoll and !cthroll are for rolling percentile dice against a target number. A b: or bb: can be prepended to get one or two bonus dice.

!cthARoll and !cthadv are for skill advancement.

Examples:

!cthRoll 50     //roll against a target of 50
!cthRoll bb:60  //roll against a target of 60 with 2 bonus dice
!cthARoll 30    //advancement roll against a target of 30

User Variables

Users can store variables for use with the Storytelling dice pool system. Variables are stored on a per-room, per-user basis in the database (currently located in the cache directory if using the Docker image).

Examples:

!set myvar 5 //stores 5 for this room under the name "myvar"
!get myvar //will print 5

Variables can be referenced in dice pool and Call of Cthulhu rolling expressions, for example !pool myvar or !pool myvar+3 or !cthroll myvar. The Call of Cthulhu advancement roll also accepts variables, and if a variable is used, and the roll is successful, it will update the variable with the new skill.

Running the Bot

The easiest way to run the bot is to use the official Docker image, although you can also run the binary directly.

A typical docker run command using the official Docker image should look something like this:

# Run unstable version of the bot
VERSION="latest"
docker run --rm -d --name dicebot \
-v /path/to/dicebot-config.toml:/config/dicebot-config.toml:ro \
-v /path/to/cache/:/cache \
ghcr.io/projectmoon/chronicle-dicebot:$VERSION

The Docker image requires two volume mounts: the location of the config file, which should be mounted at /config/dicebot-config.toml, and a cache directory to store the database and client state after initial sync. That should be mounted at /cache/in the container.

Configuration File

The configuration file is a TOML file with three sections.

[matrix]
home_server = 'https://example.com'
username = 'thisismyusername'
password = 'thisismypassword'

[database]
path = '/path/to/database/directory/'

[bot]
oldest_message_age = 300

The [matrix] section contains the information for logging in to the bot's matrix account.

  • home_server: The URL for the Matrix homeserver the bot should log in to. This should be the proper hostname of the homeserver that you would enter into the login box, which might be different than the server name that is displayed to other users.
  • username: Bot account username.
  • password: Bot account password.

The [database] section contains information for connecting to the embedded database. Note: you do not need this if you are using the Docker image.

  • path: Path on the filesystem to use as the database storage directory.

The [bot] section has settings for controlling how the bot operates. This section is optional and the settings will fall back to their default values if the section or setting is not present.

  • oldest_message_age: the oldest time (in seconds) in the past that a message can be before being ignored. This prevents the bot from processing out-of-context old commands received while offline. The default value is 900 seconds (15 minutes).

Running Binary Directly

If you have built the application from source, you can invoke the dice bot directly instead of using Docker by running dicebot /path/to/config.toml. By default, the user account cache is stored in a platform-dependent location. If you want to change the cache location on Linux, for example, you can run export XDG_CACHE_HOME=/path/to/cache before invoking the bot.

Installing the application directly also installs dicebot-cmd, which allows you to run arbitrary bot commands on the command line. This does not connect to a running instance of the bot; it just processes commands locally.

Future plans

The most basic plans are:

  • Resource counting: creation of custom counters that can go up and down.
  • Perhaps some sort of character sheet integration. But for that, we would need a sheet service.
  • Use environment variables instead of config file in Docker image.
  • Per-system game rules.

Credits

This was orignally a fork of the axfive-matrix-dicebot, with support added for Chronicles of Darkness and Call of Cthulhu.

matrix-dicebot's People

Contributors

kg333 avatar projectmoon avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

kg333

matrix-dicebot's Issues

Implement user-defined variables

Add the ability for users to define their own variables and reference them in rolls.

  • Simple definition of variables, of a specific type. Number to begin with.
  • Variables can be used in dice rolls, substituting their number for the name.

To do this, we have to implement a other things:

  • Implement proper state management (Riker/actors).
  • Add database connectivity and storage.

Then to implement this:

  • Command to define variable.
  • Rework of parsing code to read variable names.

Implement resync functionality

Implement a command or process into the bot to resync all its data. This is useful while the database schema is changing, and also maybe necessary to catch up while the bot is offline, although perhaps the syncing of all missed events would allow it to catch up instead.

Keep track of what rooms the bot is in, and what users are in them

This is necessary foundational work for managing the bot's services in a private chat (direct message) instead of spamming commands out in the open. As most commands are planned to be per-room, giving commands in a DM need to be contextually aware of a room, either by giving a room ID/number or setting the room and having all commands afterward operate on that room.

Checklist:

  • Handle an event (which hopefully exists in matrix SDK) for when a user joins a room, and record the user in the rooms namespace in the database.
  • Handle user leaving event and remove the user from the room list.
  • On startup, sync room member lists as an async task. Update member list for every room the bot is in.

The bot should always exclude itself from member lists. Because direct messages are rooms, we might also want to ignore direct message rooms. This can be done with Matrix SDK.

Pool roller interpets huge numbers as variable names

A minor issue with the dice pool roller. It resolves huge numbers (outside the bounds of i32) to variable names, because the resolver simply assumes the value is a variable if it cannot parse an i32. What it should do is check if all the characters in the element are digits, and if so try to parse an i32. If the i32 parse fails, return an error. If the element is not all digits, then we can assume it's a variable name.

Do not process very old messages

The dice bot should not run commands for old messages, in an attempt to cut down on duplicate spam if it's logged in from more than one place.

  • Add a config parameter to control the oldest messages it should process.
  • Default to 15 minutes (or maybe even less).
  • Any messages older than current time - configured amount should be ignored when processing messages on startup.

Split database code and implement database migrations

Database code is getting larger, and we are in need of a migration facility as we settle the schema.

  • Split code for each type of data into separate files (e.g. variables.rs)
  • Create migration code.

Migration Code

Store the current migration version in a specific migration tree as a single number. Hardcode the current database version into the binary (because embedded database and laziness). Produce a range of migration numbers to run on startup, which would be all versions between the old and current version, and including the current version. Migrations are functions that receive the Database object.

Add device ID setting to the configuration

Add a new device ID setting to the matrix configuration block, and use when connecting to the server with client.login. This should prevent the bot from creating endless secure sessions every time it logs in.

Better formatting of re-rolled dice

It can sometimes be be difficult to tell how the dicebot is re-rolling dice in the Chronicles of Darkness dicepool system It would be useful to see something like 2 => 10 => 10, 8, 4 to indicate a reroll. There are two parts to this: changing code to support the possibility, and then making the formatting nice.

  • Instead of having dice roll functions return a Vec<u32> and tacking that on to a full set of rolls, a dice pool roll should be represented by a Vec<SingleRoll>, where SingleRoll has one or more actual rolls in it.
  • The SingleRoll trait can implement Display to provide the better formatting.
  • Code for calculating successes etc needs to sum up the total successes of each single roll to be accurate.

Limit number of variables a user can define

Limit the maximum number of variables a user can define in order to prevent abuse of the bot.

  • Room limit: how many variables can be defined in a specific room.
  • Global limit: how many total variables can be defined.

Checklist:

  • Increment a room limit key in the variables namespace if a new variable is defined (not updated).
  • Increment a global limit key in the variables namespace if a new variable is defined (not updated).
  • Decrement room limit key when variable deleted.
  • Decrement global limit key when variable deleted.
  • Deny !set of new variables when limit(s) reached (probably compare and swap)

Settle database schema

Need to settle the schema so it doesn't change too much.

  • Use Trees for broad categories of data, e.g. rooms or variables.
  • Each Tree has its own key subspaces for smaller categories, like metadata, or data types.

Something like: Tree ("variables"), metadata:roomid:username:variable_count, or variables:roomid:username:variablename.

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.