A Discord bot for tabletop RPG character generation with built-in support for MÖRK BORG and an extensible plugin architecture for other game systems. Handles complex character creation workflows, party generation, PDF export, and guild-specific settings.
- Slash command framework —
/generatecommand with automatic game system routing - DM delivery — Generated characters sent via DM with in-channel confirmation
- Guild settings — Per-guild configuration and customization
- Ephemeral responses — Clean Discord UI with private confirmations
- MÖRK BORG system — Full implementation of the MÖRK BORG character generation rules
- Ability score rolling and character class assignment
- Equipment and inventory generation
- Vignette (backstory) generation
- Omens and scroll mechanics
- HP and alignment determination
- Comprehensive game rules — 100+ reference data entries (armor, weapons, spells, items, names, etc.)
- PDF support — Export characters to fillable PDF character sheets
- Party generation — Create multiple characters in one command, bundled in a downloadable ZIP file
- Pluggable architecture — Implement
IGameSystemto add new TTRPG systems
- .NET 10.0 — Modern C# with nullable reference types
- Comprehensive test suite — 30+ test classes covering character generation logic, party building, PDF generation, and option parsing
- Structured logging — Microsoft.Extensions.Logging integration
- Docker ready — Dockerfile and docker-compose.yml for containerized deployment
- .NET 10.0 SDK
- Discord bot token (see Discord Developer Portal)
- (Optional) Configured PDF template for character sheets
-
Clone the repository
git clone https://github.com/ChrisMartin86/ScvmBot.git cd ScvmBot -
Configure Discord bot settings
cp bot/appsettings.example.json bot/appsettings.json
Edit
bot/appsettings.jsonwith your Discord bot token:{ "Discord": { "Token": "<YOUR_DISCORD_BOT_TOKEN>", "GuildIds": [] }, "Bot": { "SyncCommands": false } }Configuration guide:
Token: Your bot's Discord token (required)GuildIds: Optional array of Discord server IDs. Omit or leave empty for global command registration, or provide one or more server IDs for guild-specific registration- Empty
[]: Commands register globally across Discord (takes ~1 hour to propagate) - One or more IDs: Commands register only in those guilds (takes ~15 seconds)
- Empty
-
Run the bot
dotnet run --project bot
docker-compose up --buildScvmBot/
├── bot/
│ ├── Data/
│ │ └── MorkBorg/
│ │ ├── armor.json # Armor reference data
│ │ ├── classes.json # Character classes
│ │ ├── weapons.json # Weapons and gear
│ │ ├── spells.json # Scroll/spell mechanics
│ │ ├── items.json # Miscellaneous items
│ │ ├── names.json # Character name generation
│ │ ├── descriptions.json # Vignette descriptions
│ │ ├── vignettes.json # Backstory templates
│ │ ├── character_sheet.pdf # PDF template
│ │ └── DATA_REFERENCE.md # Data documentation
│ ├── Games/
│ │ ├── IGameSystem.cs # Game system plugin interface
│ │ ├── CharacterGenerationResult.cs
│ │ └── MorkBorg/ # MÖRK BORG implementation
│ │ ├── CharacterGenerator.cs
│ │ ├── CharacterCardBuilder.cs
│ │ ├── ReferenceDataService.cs
│ │ ├── VignetteGenerator.cs
│ │ ├── MorkBorgCommandDefinition.cs
│ │ └── ...
│ ├── Models/
│ │ ├── ICharacter.cs # Character interface
│ │ ├── GuildSettings.cs
│ │ └── MorkBorg/
│ │ └── MorkBorgCharacter.cs
│ ├── Services/
│ │ ├── BotService.cs # Discord lifecycle management
│ │ ├── GenerateCommandHandler.cs # Command routing
│ │ ├── ResponseCardBuilder.cs # Discord embed formatting
│ │ ├── PartyZipBuilder.cs # ZIP archive creation
│ │ └── Commands/
│ │ ├── ISlashCommand.cs # Command plugin interface
│ │ └── HelloCommand.cs # Example command
│ ├── Program.cs # DI configuration & entry point
│ ├── Dockerfile
│ └── appsettings.example.json
├── tests/
│ ├── ScvmBot.Bot.Tests/ # Framework and integration tests
│ └── ScvmBot.Games.MorkBorg.Tests/ # Game logic unit tests
├── docker-compose.yml
├── ScvmBot.sln
└── LICENSE
/generate morkborg character— Generate a single MÖRK BORG character/generate morkborg party [count]— Generate a party of characters (1-10)/hello— Test bot connectivity
Characters are sent via DM. In-channel responses confirm delivery and provide download links for generated files.
- Create a new directory under
bot/Games/YourSystem/ - Implement
IGameSysteminterface:public class YourGameSystem : IGameSystem { public string Name => "Your Game"; public string CommandKey => "yourgame"; public bool SupportsPdf => true; public SlashCommandOptionBuilder BuildCommandGroupOptions() { ... } public Task<GenerateResult> HandleGenerateCommandAsync(...) { ... } }
- Register in
Program.cs:services.AddSingleton<IGameSystem, YourGameSystem>();
- The system will automatically appear under
/generate yourgame
dotnet testdotnet build ScvmBot.sln- Discord.Net (3.19.1) — Discord API integration
- iText7 (9.5.0) — PDF generation
- Microsoft.Extensions.* (10.0.5) — Dependency injection, configuration, logging, hosting
ScvmBot is an independent production by Christopher Martin and is not affiliated with Ockult Örtmästare Games or Stockholm Kartell. It is published under the MÖRK BORG Third Party License.
MÖRK BORG is © 2019 Ockult Örtmästare Games and Stockholm Kartell.
See THIRD_PARTY_LICENSES.md for full details.
MIT © 2025 Christopher Martin
Third-party content is licensed separately — see THIRD_PARTY_LICENSES.md.