Deploying a Project Zomboid server and developing Discord bots in TypeScript and Lua to drive community engagement and provide real-time server insights.
For many multiplayer games, community engagement is key to a vibrant, long-lasting player base. While hosting a dedicated server for a game like Project Zomboid provides a persistent world, it lacks integration with the community's primary communication platform—in our case, Discord.
The challenge was twofold:
The foundation of this project was a dedicated Project Zomboid server. I used LinuxGSM to streamline the installation and management process on a Linux VM. This provided a robust command-line interface for handling updates, backups, and server startups/shutdowns.
# Example LinuxGSM commands for server administration
./pzserver start # Start the server process
./pzserver update # Check for and apply SteamCMD updates
./pzserver backup # Create a compressed backup of the server state
Server configuration and mod management were handled by modifying the .ini
and .lua
files, allowing for a highly customized gameplay experience tailored to our group.
To enhance community engagement, I developed a suite of TypeScript-based services that parse game logs and interact with the Discord API.
Problem: Player deaths are significant events in Project Zomboid. We wanted a way to share these moments with the community in real-time.
Solution: I developed a service that actively monitors the server's PerkLog
file. When a new line is added, the script uses a regular expression to check if it's a death event.
// Regex to capture player name and hours survived from a log line
const deadLinePattern = /\[[\d\- :\.]+\] \[\d+\]\[(.+)\]\[\d+,\d+,\d+\]\[Died\]\[Hours Survived: (\d+)\]\./;
If a match is found, the script performs two actions:
sequenceDiagram participant Game Server participant Log File participant TypeScript Service participant SQLite DB participant Discord Webhook Game Server->>Log File: Appends player death event TypeScript Service->>Log File: Watches for file changes and reads new line TypeScript Service->>TypeScript Service: Matches line with Regex TypeScript Service->>SQLite DB: Stores death event data TypeScript Service->>Discord Webhook: Sends formatted notification
Problem: We wanted a fun, competitive way to track player stats and celebrate (or commiserate) our collective efforts.
Solution: A second TypeScript script was created to query the SQLite database. It calculates the total number of deaths and hours survived for each player, ranking them in a "Zombie-Darwin Awards" leaderboard. This script is scheduled to run weekly as a cron
job, automatically posting the updated leaderboard to Discord.
/online
Player Status CommandProblem: Players wanted an easy way to check who was currently online without having to launch the game.
Solution: This required a more integrated approach.
players.json
file./online
). When a user executes the command, the bot reads the players.json
file and presents the data in a clean, embedded format in the Discord channel.This three-part system effectively provides a near real-time view of the server's status directly within Discord.
This project successfully transformed a standard game server into a deeply integrated community hub.
cron
for scheduling and SQLite for data persistence.This case study demonstrates the ability to identify a need within a community and build a full-stack, automated solution to meet that need, creating a more engaging and connected user experience.