Skip to content

Scayar/BinaryLoop

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

⟁ BINARY LOOP

XOR Puzzle Game on ESP32 with Cryptographic Token Verification

Version License ESP32 PHP PlatformIO


Binary Loop is an educational hardware + software puzzle game that teaches binary logic and XOR cryptography through a gamified, cyberpunk-themed experience. Players solve XOR decryption puzzles on a physical ESP32 device, then verify their scores on a web leaderboard using cryptographic tokens.


 ╔══════════════════════════════════════════════╗
 ║   KEY:    0 0 1 1                            ║
 ║   CIPHER: 1 0 1 0                            ║
 ║   ─────────────────                          ║
 ║   PLAIN:  [█] _ _ _    ← You solve this!    ║
 ╚══════════════════════════════════════════════╝

🎮 Gameplay Demo

Gameplay Demo


Table of Contents


How It Works

Binary Loop bridges the physical and digital worlds. A standalone ESP32 device runs the puzzle game offline, and a PHP web dashboard handles score verification and leaderboard display.

flowchart LR
    subgraph HARDWARE["🔌 ESP32 Device (Offline)"]
        A["🟦 Press BLUE\nto Start"] --> B["🧩 Solve XOR\nPuzzles"]
        B --> C{"All 30 Levels\nCompleted?"}
        C -->|Yes| D["🔑 Generate\n4-Digit Token"]
        C -->|"🟥 Press RED\n(Give Up)"| D
    end

    subgraph WEB["🌐 Web Dashboard (PHP)"]
        E["📱 Scan QR Code"] --> F["📝 Enter Name\n& Token"]
        F --> G["🔐 Server Verifies\nToken"]
        G -->|Valid| H["✅ Score Added\nto Leaderboard"]
        G -->|Invalid| I["❌ Score = 0\n(Anti-Cheat)"]
    end

    D -.->|"Student reads\ntoken from screen"| E

    style HARDWARE fill:#0a0a0a,stroke:#00ff41,stroke-width:2px,color:#00ff41
    style WEB fill:#0a0a0a,stroke:#00d9ff,stroke-width:2px,color:#00d9ff
Loading

System Architecture

graph TB
    subgraph ESP32["ESP32 Microcontroller"]
        FW["Firmware (C++/Arduino)"]
        OLED["OLED SSD1306\n128×64 I2C"]
        BTN_B["🟦 Blue Button\nGPIO 26"]
        BTN_R["🟥 Red Button\nGPIO 25"]
        TOK["Token Generator\n(Score × 7919 + Level × 123) % 10000"]

        BTN_B --> FW
        BTN_R --> FW
        FW --> OLED
        FW --> TOK
    end

    subgraph Server["PHP Web Server"]
        API["api.php\nREST API"]
        VER["Token Verifier\nBrute-Force Reverse Lookup"]
        DB["leaderboard.json\nScore Storage"]

        API --> VER
        VER --> DB
    end

    subgraph Client["Web Frontend"]
        UI["Cyberpunk UI\nHTML/CSS/JS"]
        FORM["Score Submission\nForm"]
        LB["Live Leaderboard\nTable"]

        UI --> FORM
        UI --> LB
    end

    TOK -.->|"4-digit token\n(air-gapped)"| FORM
    FORM -->|"POST /api.php?action=submit"| API
    LB -->|"GET /api.php?action=leaderboard"| API

    style ESP32 fill:#1a0a0a,stroke:#ff6b35,stroke-width:2px,color:#ff6b35
    style Server fill:#0a0a1a,stroke:#777BB4,stroke-width:2px,color:#777BB4
    style Client fill:#0a1a0a,stroke:#00ff41,stroke-width:2px,color:#00ff41
Loading

Hardware Setup

Required Components

Component Specification Quantity
ESP32 Dev Module Dual-Core 240MHz, WiFi/BLE 1
OLED Display SSD1306, 0.96", 128×64, I2C 1
Push Button (Blue) Momentary, normally open 1
Push Button (Red) Momentary, normally open 1
Jumper Wires Male-to-Male ~8
Breadboard Standard size 1

Wiring Diagram

                    ┌──────────────────────┐
                    │       ESP32          │
                    │                      │
   OLED SSD1306    │                      │    Buttons
   ┌──────────┐    │                      │    ┌──────────┐
   │ SDA ─────┼────┤ GPIO 2  (D2)        │    │          │
   │ SCL ─────┼────┤ GPIO 15 (D15)       │    │ BLUE ────┼──── GPIO 26 (D26)
   │ VCC ─────┼────┤ 3.3V               │    │   GND ───┼──── GND
   │ GND ─────┼────┤ GND                │    │          │
   └──────────┘    │                      │    │ RED ─────┼──── GPIO 25 (D25)
                    │                      │    │   GND ───┼──── GND
                    │                      │    └──────────┘
                    └──────────────────────┘

   Note: Buttons use internal pull-up resistors (INPUT_PULLUP).
         Wire one pin to GPIO, the other to GND. No external resistors needed.

Pin Reference

Component ESP32 Pin Type Notes
OLED SDA GPIO 2 I2C Data Custom I2C pins
OLED SCL GPIO 15 I2C Clock Custom I2C pins
OLED VCC 3.3V Power Do NOT use 5V
OLED GND GND Ground
Blue Button GPIO 26 Digital Input Internal pull-up, active LOW
Red Button GPIO 25 Digital Input Internal pull-up, active LOW

Software Installation

Prerequisites

Tool Purpose Download
VS Code Code editor code.visualstudio.com
PlatformIO Firmware build & upload VS Code Extension
PHP 7.4+ Web server backend php.net

Step 1: Flash the ESP32 Firmware

# Clone the repository
git clone https://github.com/Scayar/BinaryLoop.git
cd BinaryLoop

# Open Unified_ESP32 folder in VS Code with PlatformIO
# Connect ESP32 via USB
# Click the Upload button (→) in PlatformIO toolbar

PlatformIO will automatically download the required libraries:

  • Adafruit GFX Library @ ^1.11.9
  • Adafruit SSD1306 @ ^2.5.9

Step 2: Start the Web Dashboard

Option A — PHP Built-in Server (Recommended for testing)

cd WebApp
php -S localhost:8000

Then open http://localhost:8000 in your browser.

Option B — XAMPP / WAMP (Windows)

# Copy the WebApp folder into your htdocs directory
# Example: C:\xampp\htdocs\binaryloop\
# Start Apache from the XAMPP Control Panel
# Open: http://localhost/binaryloop

Option C — Any PHP Web Host

Upload the WebApp folder to your web hosting. Ensure PHP 7.4+ is available and leaderboard.json has write permissions (chmod 666).

Step 3: Verify Setup

  1. The ESP32 OLED should display "BINARY LOOP" with "PRESS BLUE" blinking
  2. The web dashboard should load with the cyberpunk UI at your chosen URL
  3. Try submitting a test score to verify the API connection

How to Play

stateDiagram-v2
    [*] --> Idle: Power On
    Idle --> Playing: 🟦 Press BLUE
    Playing --> LevelIntro: Start Level
    LevelIntro --> Solving: Show KEY & CIPHER

    state Solving {
        [*] --> WaitInput
        WaitInput --> FlipBit: 🟦 Press BLUE
        FlipBit --> CheckAnswer
        CheckAnswer --> WaitInput: Wrong
        CheckAnswer --> Correct: Match!
    }

    Solving --> NextLevel: ✅ Correct
    Solving --> GameOver: 🟥 Press RED (Give Up)
    NextLevel --> LevelIntro: Level ≤ 30
    NextLevel --> GameOver: Level > 30

    GameOver --> ShowToken: Display Score & Token
    ShowToken --> Idle: 🟦 Press BLUE (New Game)
Loading

Controls

Button Idle Screen During Puzzle Game Over
🟦 BLUE Start game Flip bit at cursor Start new game
🟥 RED Give up, end game

Game Mechanics

  1. Start — Press the blue button on the idle screen
  2. Solve — Each level shows a KEY and CIPHER in binary. You must produce PLAIN = CIPHER XOR KEY
  3. Cursor — Moves automatically every second across the bit positions
  4. Flip — Press blue when the cursor is on the bit you want to toggle (0→1 or 1→0)
  5. Win — When your input matches the XOR result, the screen flashes and you advance
  6. Give Up — Press red at any time to end the game early
  7. Token — After the game ends, a 4-digit verification token is displayed
  8. Submit — Scan the QR code, enter your name and token on the web dashboard

Level Progression

Levels Key (Binary) Key (Decimal) Bit Width
1–5 0011 3 4 bits
6–10 0101 5 5 bits
11–15 0111 7 5 bits
16–20 1001 9 6 bits
21–25 1011 11 7 bits
26–30 1101 13 8 bits

Scoring

Score per level = Level Number × 100
Maximum possible score = Σ(n × 100) for n=1..30 = 46,500 points

Token Verification System

The token system creates a secure, air-gapped bridge between the offline hardware game and the online leaderboard, without requiring WiFi on the ESP32.

How It Works

sequenceDiagram
    participant P as Player
    participant E as ESP32
    participant W as Web Browser
    participant S as PHP Server

    P->>E: Plays game (Levels 1-30)
    E->>E: Calculate Token = (Score × 7919 + Level × 123) % 10000
    E->>P: Display 4-digit token on OLED

    P->>W: Scans QR → Opens web dashboard
    P->>W: Enters name + token
    W->>S: POST /api.php?action=submit

    S->>S: Brute-force reverse lookup
    Note over S: Scan Score 0→150,000 (step 50)<br>Scan Level 1→31<br>Check: (Score × 7919 + Level × 123) % 10000 == Token?

    alt Token Valid
        S->>W: ✅ Verified! Score: X, Rank: #Y
        W->>P: Show success + redirect to leaderboard
    else Token Invalid
        S->>W: ❌ Invalid token, Score = 0
        W->>P: Show error message
    end
Loading

Formula

SALT = 7919  (prime number)

Token = (Score × SALT + Level × 123) % 10000

Example:

Score = 3000, Level = 10
Token = (3000 × 7919 + 10 × 123) % 10000
     = (23,757,000 + 1,230) % 10000
     = 23,758,230 % 10000
     = 8230

Anti-Cheat Measures

Protection Description
Token Uniqueness Each game session produces a different token based on score and level
Duplicate Detection A token can only be submitted once; reuse is blocked
Score Validation Invalid tokens result in a score of 0 (unverified)
Brute-Force Verification Server scans all possible score/level combinations — no shortcut
Input Sanitization All user inputs are validated and sanitized server-side

API Reference

Base URL: api.php

GET ?action=leaderboard

Returns the full leaderboard sorted by score (descending).

Response:

[
  {
    "name": "Player1",
    "class": "10-A [L30]",
    "score": 46500,
    "token": "1234",
    "verified": true,
    "date": "2026-01-15T10:30:00+00:00"
  }
]

POST ?action=submit

Submit a score with token verification.

Request Body:

{
  "name": "Player1",
  "classUnit": "10-A",
  "token": "1234"
}

Success Response:

{
  "success": true,
  "rank": 1,
  "score": 46500,
  "level": 30,
  "verified": true,
  "message": "Verification successful!"
}

Error Response:

{
  "success": false,
  "message": "Token already used!"
}

GET ?action=stats

Returns aggregate statistics.

Response:

{
  "totalPlayers": 42,
  "verifiedPlayers": 38,
  "topScore": 46500
}

Project Structure

BinaryLoop/
├── assets/                     # Media (e.g. gameplay.mp4 for README demo)
├── Unified_ESP32/              # ESP32 Firmware
│   ├── platformio.ini          # PlatformIO configuration & dependencies
│   ├── .gitignore
│   └── src/
│       └── main.cpp            # Game engine, OLED graphics, token generation
│
├── WebApp/                     # Web Dashboard
│   ├── api.php                 # REST API (leaderboard, submit, stats, token verification)
│   ├── index.php               # Entry point (redirects to public/)
│   ├── leaderboard.json        # Score database (auto-created, gitignored)
│   └── public/
│       ├── index.html          # Single-page app with cyberpunk UI
│       ├── script.js           # Frontend logic (API calls, form handling, navigation)
│       └── style.css           # Cyberpunk theme (neon green, CRT scanlines, glitch effects)
│
├── .gitignore
├── CONTRIBUTING.md             # Contribution guidelines
├── LICENSE                     # MIT License
└── readme.md                   # This file

Troubleshooting

OLED display not working
  • Verify wiring: SDA → GPIO 2, SCL → GPIO 15
  • Confirm I2C address is 0x3C (most SSD1306 modules use this)
  • Ensure 3.3V power (not 5V)
  • Check Serial Monitor at 115200 baud for "OLED FAIL!" message
Buttons not responding
  • Buttons must connect between the GPIO pin and GND
  • No external pull-up resistors needed (firmware uses INPUT_PULLUP)
  • Check Serial Monitor — button presses are logged
  • Ensure debounce time (120ms) isn't causing missed presses
Token verification fails
  • Each game session generates a unique token — restarting the game creates a new one
  • The token must be exactly 4 numeric digits
  • Each token can only be used once (anti-cheat)
  • If the student restarted the game, the old token is invalid
Web dashboard shows "CONNECTION FAILED"
  • Ensure the PHP server is running (php -S localhost:8000 in the WebApp folder)
  • Check that PHP 7.4+ is installed: php -v
  • Verify api.php is accessible at the correct URL
  • Check browser console (F12) for detailed error messages
Leaderboard not saving scores
  • leaderboard.json must exist and be writable by the PHP process
  • On Linux/Mac: chmod 666 WebApp/leaderboard.json
  • On shared hosting, check file ownership matches the web server user
  • Verify the file contains valid JSON (at minimum: [])
PlatformIO upload fails
  • Ensure ESP32 is connected via USB and the correct port is detected
  • Install USB-to-UART drivers (CP2102 or CH340 depending on your board)
  • Try holding the BOOT button on the ESP32 while uploading
  • Check that no other program (Serial Monitor, etc.) is using the COM port

Tech Stack

Layer Technology
Microcontroller ESP32 (Xtensa LX6, Dual-Core 240MHz)
Display SSD1306 OLED 128×64 via I2C
Firmware C++ / Arduino Framework / PlatformIO
Libraries Adafruit GFX, Adafruit SSD1306
Backend PHP 7.4+
Frontend HTML5, CSS3, Vanilla JavaScript
Data Storage JSON flat file
Fonts Orbitron, Share Tech Mono (Google Fonts)

Contributing

Contributions are welcome! Please read CONTRIBUTING.md before submitting a pull request.


License

This project is licensed under the MIT License — see the LICENSE file for details.


Built by Scayar for Advanced Tech Education

GitHub Website

About

XOR puzzle game on ESP32 with OLED. Solve binary logic challenges, earn a token, verify on the web leaderboard.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors