Skip to content

ak811/game-of-life

Repository files navigation

Game of Life (Discord Bot)

A collaborative “crafting” mini‑game for Discord: players combine items like fire+water to discover new ones, working together until someone (or the server) discovers life.

This repo is built around discord.py + a lightweight storage layer + an LLM-powered crafting engine (OpenAI). It’s intentionally simple: one channel, one shared inventory, and a lot of human creativity.


Features

  • Crafting via chat: type fire+water (spaces okay) to craft.
  • Shared server inventory persisted to disk per guild (data/).
  • LLM crafting engine that returns one real word + emoji, with guardrails.
  • Interactive, paginated inventory UI (Discord buttons).
  • Admin controls: start/stop rounds, ping contributors.
  • Quality of life:
    • Fuzzy item matching (so typos don’t kill the vibe).
    • Suggestions when an item isn’t found.
    • “Top crafters” leaderboard stats.
    • Auto-restore a running round after bot restart.

How the Game Works

  1. A round starts with seed items: fire, water, earth, air.
  2. Players craft by submitting itemA+itemB.
  3. The bot:
    • Finds both items in the inventory (exact match, then fuzzy match).
    • Calls the LLM to generate a single, real word result + emoji.
    • Adds new items to the shared inventory (duplicates are allowed as “already discovered”).
    • Tracks contributor stats.
  4. The round ends when life exists in the inventory.

Commands

All commands work in the configured game channel only.

Command What it does
!game_of_life / !gol Show help
!game_of_life inv Show inventory (paginated)
!game_of_life page <n> Jump to page n
!game_of_life find <word> Search inventory (whole-word match, then fuzzy suggestions)
!game_of_life top Show top crafters
!game_of_life start Admin/host only: start a new round
!game_of_life stop Admin/host only: stop the round
!game_of_life ping Admin/host only: mention contributors + stats

Crafting input format:

  • fire+water
  • fire + water
  • nature's gift + nature's gift (apostrophes supported)

Requirements

  • Python 3.10+ recommended
  • A Discord application + bot token
  • An OpenAI API key (used for crafting results)

Python dependencies

Install these (you can pin versions however you like):

pip install -U discord.py python-dotenv openai

If you prefer a requirements.txt, create one with:

discord.py>=2.3
python-dotenv>=1.0
openai>=1.0

Setup

1) Create your .env

Copy .env.example to .env:

cp .env.example .env

Fill in:

DISCORD_BOT_TOKEN="your_discord_bot_token"
OPENAI_API_KEY="your_openai_api_key"

2) Configure the game channel and host user

Edit:

cogs/game_of_life/config.py

AUTHORIZED_USER_ID = 123456789012345678
GAME_OF_LIFE_CHANNEL_ID = 123456789012345678
COMMAND_PREFIX = "!game_of_life"
GOL_ALIAS = "!gol"
  • AUTHORIZED_USER_ID is the single user allowed to start/stop/ping.
  • GAME_OF_LIFE_CHANNEL_ID is the only channel where the bot responds.

3) Invite the bot to your server

Give it permissions to:

  • Read messages
  • Send messages
  • Embed links
  • Use external emojis (optional)
  • Use message content intent (required for reading fire+water)

Important: You must enable the Message Content Intent in the Discord Developer Portal and in code (already enabled in bot.py via intents.message_content = True).


Run Locally

From the repo root:

python bot.py

You should see:

  • Logged in as <botname>
  • Then you can use !gol in the configured channel.

Data & Persistence

All server data is stored in data/:

  • inventory_<guild_id>.json – shared inventory items
  • contributors_<guild_id>.json – contributors for the current round
  • state_<guild_id>.json – whether a round is active
  • stats_<guild_id>.json – per-user craft counts and new item counts

This is deliberately simple JSON storage. If you deploy to an ephemeral filesystem (some PaaS), you’ll want a persistent volume or a real database.


LLM Crafting Rules (What the bot tries to enforce)

The crafting engine (llm.py) uses a strict system prompt plus post-validation to keep results sane:

  • Must return STRICT JSON: {"status":"ok","result_name":"<one word>","emoji":"<emoji>"}
  • result_name must be:
    • one lowercase word (letters and optional hyphens)
    • a real, recognizable word (not a made-up blend)
    • not equal to either input
  • When inputs are identical, the result must not regress (e.g., ocean+ocean should not become sea).
  • Built-in fallback pairs for common combos (e.g., fire+water -> steam), plus safe fallback words if parsing fails.

⚠️ Costs & rate limits: OpenAI calls cost money. If you expect high usage, consider adding:

  • cooldowns / per-user limits
  • caching crafted pairs
  • cheaper models or a local ruleset for early-game combos

Deploying (Basic guidance)

This bot runs anywhere Python runs. The only “special” requirement is persistent storage if you want inventories to survive restarts.

Common options:

  • A VPS with systemd
  • Docker with a mounted volume for data/
  • A hobby server like Raspberry Pi (humans love reinventing space heaters)

Example systemd service idea (sketch):

[Unit]
Description=Game of Life Discord Bot
After=network.target

[Service]
Type=simple
WorkingDirectory=/path/to/game-of-life
EnvironmentFile=/path/to/game-of-life/.env
ExecStart=/path/to/venv/bin/python bot.py
Restart=always

[Install]
WantedBy=multi-user.target

License

MIT. See LICENSE.

About

Game of Life (Discord Bot)

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages