# Click Arena (Zig)





A native multiplayer clicking game built with **Zig**, **raylib**, and **SpacetimeDB**. This is the native desktop client for [Click Arena](https://github.com/phiat/click-arena) — same game, same shared backend, rendered with raylib instead of a browser.
Also serves as a test bed for the [SpacetimeDB Zig SDK](https://github.com/phiat/spacetimedb-zig).
## Stack
- **Client**: Zig 0.15+ with raylib — native GPU-rendered window, no browser needed
- **Backend DB**: SpacetimeDB (Rust WASM module) — server-authoritative game state
- **Bridge**: [spacetimedb-zig](https://github.com/phiat/spacetimedb-zig) — Zig client SDK for SpacetimeDB over WebSocket
- **Styling**: Dark theme, green/pink accent palette
## Running locally
### Prerequisites
- Zig 0.15+
- SpacetimeDB CLI (`spacetime`) with a local instance running on port 3000
- [spacetimedb-zig](https://github.com/phiat/spacetimedb-zig) cloned as a sibling directory (`../spacetimedb-zig`)
### SpacetimeDB module
If you haven't already published the game module (shared with the [Phoenix client](https://github.com/phiat/click-arena)):
```bash
cd click_arena_module
cargo build --target wasm32-unknown-unknown --release
spacetime publish clickarena
```
### Build and run
```bash
zig build run
```
The game window opens at 800×600. Connect, type a name, and start clicking.
| Setting | Default | Location |
|---|---|---|
| SpacetimeDB host | `localhost:3000` | `src/main.zig` |
| Database name | `clickarena5` | `src/main.zig` |
## How it works
1. Players join by entering a name — calls the `join_game` reducer in SpacetimeDB
2. Clicking the central button calls the `click` reducer, incrementing score by 1
3. Bonus buttons (+10 points) spawn around the click button — all players see them simultaneously
4. Up to 6 bonuses can be active at once, each in a different position
5. First player to click a bonus claims it — it disappears with a genie animation (fizzle then fly into the main button)
6. Bonuses spawn via click milestones (10% chance every 20 clicks) and a random timer (30–90 seconds)
7. The leaderboard updates in real-time via SpacetimeDB subscriptions
8. Re-joining with the same name reclaims your score
## Architecture
```
raylib window ←→ Zig game loop ←WebSocket→ SpacetimeDB
↕
spacetimedb-zig SDK
(schema fetch, subscriptions, reducer calls)
```
**SpacetimeDB tables**: `Player` (session_id, name, score) and `Bonus` (id, position, points)
**Reducers**: `join_game`, `click`, `spawn_bonus`, `claim_bonus`, `leave_game`
### Source layout
```
src/
├── main.zig # Entry point — SpacetimeDB + raylib init, game loop
├── game.zig # Game state, SpacetimeDB callbacks, reducer calls
├── draw.zig # All rendering — screens, buttons, animations
└── constants.zig # Layout, colors, types
```
## Related
- [click-arena](https://github.com/phiat/click-arena) — Phoenix LiveView client (same backend)
- [spacetimedb-zig](https://github.com/phiat/spacetimedb-zig) — The Zig SDK this project tests
## License
MIT