A multiplayer game platform for Discord that runs turn-based matches inside message threads, featuring plugin game engines, PostgreSQL persistence, and crash recovery.
I developed Strife as a complete rewrite of my earlier Discord bot PlayCord, creating an extensible platform where multiplayer turn-based games run in dedicated message threads. The architecture uses a modular plugin system so that the exact same game logic runs interactively on Discord, replays historical matches, and runs in local command line sessions.
Building a reliable online gaming bot requires treating state persistence as the central priority, using deterministic game rules and an append-only move log so that crashes never corrupt active games.
My earlier Discord gaming bots like Piranha and PlayCord were fun experiments, but each bot was tightly coupled to a single game and handled user interaction through hardcoded commands and temporary memory dictionaries. Whenever the bot restarted or encountered an unexpected network disconnect, ongoing games vanished and player progress was lost. Strife was designed from scratch to solve these limitations by providing a durable hosting environment that can run many different games through a unified plugin interface.
The system creates dedicated Discord message threads for every new match, keeping game discussions and interactive button controls neatly contained without cluttering server channels. It includes built-in implementations of seven games, ranging from classic board games like Chess and Connect Four to social deduction games like Coup and Mafia, while allowing new games to be added as modular plugins.
The primary design goal for Strife was ensuring that a server restart or network glitch would never ruin an active match. To achieve this, the host records every game move into a PostgreSQL database as an append-only log of player actions and state transitions. If the bot restarts while games are in progress, it scans the database for active matches and replays each recorded move sequentially through the game engine, restoring the exact state of the board before re-enabling player controls.
Because the core game loop is completely separated from Discord's network APIs, the same game logic function can run in multiple contexts. During a live match it listens to Discord button clicks, in replay mode it reads past database records to generate an interactive playback, and in local development it runs directly in a terminal console, which makes testing new game rules much faster.
Running interactive games on Discord introduces numerous edge cases around timeouts, concurrent button presses, and user navigation. Strife packs interaction metadata into signed payloads attached to Discord interface components, allowing the bot to route button clicks directly to the appropriate match without keeping large state trees in transient memory.
To keep slow game logic or unexpected loops from freezing Discord's asynchronous event loop, player moves are executed in a managed thread pool with strict timeout bounds. If a game plugin hangs or takes too long to respond, the host can safely terminate the turn and notify the players without impacting any other matches running on the server.