Skip to content

Latest commit

 

History

16 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

English فارسی

Lion and Sun flag

ROULETTE

Stars Forks License

Roulette

> Six chambers. One truth. No undo.
██████╗  ██████╗ ██╗   ██╗██╗     ███████╗████████╗████████╗███████╗
██╔══██╗██╔═══██╗██║   ██║██║     ██╔════╝╚══██╔══╝╚══██╔══╝██╔════╝
██████╔╝██║   ██║██║   ██║██║     █████╗     ██║      ██║   █████╗
██╔══██╗██║   ██║██║   ██║██║     ██╔══╝     ██║      ██║   ██╔══╝
██║  ██║╚██████╔╝╚██████╔╝███████╗███████╗   ██║      ██║   ███████╗
╚═╝  ╚═╝ ╚═════╝  ╚═════╝ ╚══════╝╚══════╝   ╚═╝      ╚═╝   ╚══════╝

Six chambers. Six chances. Don't be a coward — this game is winner-takes-all. Life or death. If you think you're brave enough, come play.

If you like it, star the repo. If you want to build on it, fork it — the buttons are right there at the top of this page.


Overview

ROULETTE is a multiplayer-only terminal game. Two players share one revolver, one live TCP connection, and a single question repeated every turn: will the next pull be the one? Written in Python, with a dedicated Ruby narrative layer giving the game its voice — flavor text, typing effects, ASCII art.

There is no folding, no walking away once a match begins. Every survived pull raises your score. Score is the only thing that can ever buy you a Last Chance — one single emergency survival, earned, not given, and usable exactly once per match.

⚠ Game Rules

By launching and entering the game, you accept these rules:

  1. Entering the game means you accept the rules. No warning screen comes twice — the rules screen is shown once, before you can host or join, and that is your only notice.
  2. You are not permitted to run this game on virtual machines. This is a played-straight, single-environment experience — it is not built or intended to be run inside a VM.
  3. Any form of cheating guarantees your loss. There is no benefit to tampering with the client or the odds — the server is authoritative and treats detected tampering as an automatic loss for the offending player.

اگه به خدا اعتقاد داری موقعی که خشاب رو سرته بگو نجاتت بده

"If you believe in God, when the cylinder is against your head — ask Him to save you."

What Makes This Different

  • Multiplayer only, room-based matchmaking. Host a room under a name, share that name, and the server pairs the two of you together for an authoritative, real-time match. No bots. No practice mode.
  • The Last Chance system. Each player can earn exactly one emergency survival for the entire match. Score is checked before any death is ever finalized — if you've earned enough, it's spent instead of you.
  • Deliberately scarce, streak-based scoring. A small, flat amount of score per survived pull, scaled by your own consecutive-survival streak. Earning a Last Chance takes real, sustained risk — it cannot be farmed.
  • A rules screen before every session. Plain-language rules are shown before anyone can host or join, so nobody sits down blind.
  • A dedicated narrative engine. All atmosphere — flavor text, typing effects, ASCII banners — is generated by a separate Ruby layer, cleanly decoupled from the Python game logic.
  • Persistent statistics. Wins, losses, best score, streaks, and full match history — including room and opponent names — are stored between sessions.
  • A death record for every loss. A personal, readable report is generated the moment a match ends in death, alongside a compact audit trail of every death across every match.
  • Cryptographically strong randomness. The bullet's chamber is chosen with a cryptographically secure random source, not a seedable or predictable generator. The outcome cannot be predicted or reverse-engineered.
  • Fail soft, not hard. A missing narrative layer, a dropped connection, or a corrupted save file all degrade the experience gracefully, with a clear message, instead of crashing the match.

Installation

Requirements

  • Python 3.10+
  • Ruby (optional, but strongly recommended for the full narrative experience — the game falls back gracefully without it)

Linux / macOS

git clone https://github.com/your-username/roulette.git
cd roulette
chmod +x install.sh
./install.sh

source .venv/bin/activate
python3 client/main.py

If Ruby isn't already installed:

# Debian/Ubuntu
sudo apt install ruby

# macOS (Homebrew)
brew install ruby

Windows

git clone https://github.com/your-username/roulette.git
cd roulette
install.bat

.venv\Scripts\activate
python client\main.py

If Ruby isn't already installed, get it from rubyinstaller.org.

Running a match

  1. One player starts the game and chooses Host a room, picking a room name and, optionally, starting a local server automatically.
  2. The other player starts the game, chooses Join a room, and enters the same room name plus the host's address and port.
  3. Once both players are in the room, the match begins — the server is authoritative from that point on.

To run a standalone server for more than one room, or for players connecting from different machines:

python3 server/main.py

Architecture

roulette/
├── client/
│   └── main.py        # Entry point: startup checks, rules, menu, dispatch
├── server/
│   └── main.py         # Persistent, multi-room authoritative match server
├── game/
│   ├── revolver.py      # Pure revolver mechanics (spin / fire / odds)
│   ├── online.py         # Client-side networking + UI for matches
│   ├── score.py            # Stats, Last Chance rules, death record artifacts
│   └── narrator.py          # Bridge to the Ruby narrative/effects layer
├── scripts/
│   ├── texts.rb            # Atmospheric text generation
│   └── effects.rb           # Typewriter effects + ASCII art rendering
├── assets/
│   └── texts.txt              # Categorized pool of narrative lines
├── data/
│   ├── scores.json             # Persistent player statistics
│   └── deaths.log               # Append-only death audit trail
├── install.sh / install.bat       # Platform installers
└── requirements.txt

Design principles:

  • Rooms, not raw pairing. A room name is the only thing two players need to agree on ahead of time — no connection-order choreography.
  • Authoritative server. All randomness and rule enforcement — including the one-time Last Chance check — happen server-side, before a death is ever finalized. Clients only render state and send intent (pull). They don't get a vote.
  • Separation of voice and logic. Python never hard-codes flavor text. Every line, every typing effect, every ASCII banner is requested from the Ruby layer through game/narrator.py, which shells out to scripts/texts.rb and scripts/effects.rb.
  • Small, testable core. game/revolver.py has zero UI or I/O dependencies, so the core mechanic can be tested in total isolation from the drama around it.
  • Fail soft, not hard. Missing Ruby, a dropped connection, a corrupted save file, a permissions problem — all of it degrades gracefully with a clear message instead of a crash and a shrug.

License

MIT — see LICENSE.

About

Multiplayer terminal Russian roulette — Python game logic + Ruby narrative layer, over a live TCP connection.

Topics

Resources

Stars

9 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages