Spaces:
Running on Zero
Running on Zero
| title: HuggingWizards | |
| emoji: π§ | |
| colorFrom: purple | |
| colorTo: indigo | |
| sdk: gradio | |
| sdk_version: 5.9.1 | |
| app_file: app.py | |
| pinned: false | |
| short_description: Nemotron-4B is the Game Master | |
| tags: | |
| - track:wood | |
| - sponsor:nvidia | |
| - achievement:offgrid | |
| - achievement:sharing | |
| Social Media Post and Demo Video: https://www.linkedin.com/posts/dean-byrne-02a28b191_huggingwizards-for-hugging-face-hackathon-activity-7472041413648502785-K2rP?utm_source=share&utm_medium=member_desktop&rcm=ACoAAC0RumIBxlIKTkKv5tF-hb2OU7TdZ19kxcQ | |
| # π§ HuggingWizards | |
| A small 2D pixel-wizard **co-op arena** that runs as a Gradio Space on **ZeroGPU**. | |
| Up to **8 players** join one shared arena, fight a central **boss** and the | |
| **minions** it spawns, and upgrade their magic between rounds. Everyone else can | |
| **spectate** live. Controls: **WASD** to move, **Space** to attack. | |
| The hackathon twist: **NVIDIA Nemotron-Mini-4B-Instruct** is the **Game Master**. | |
| At the end of every round it decides: | |
| - **Rewards** β how much gold each wizard earns (based on damage / survival). | |
| - **Blessings** β individual boons for wizards who earned them: any timed aura, | |
| a `full_heal`, or even an `extra_life` for a struggling player. | |
| - **Boss attack pattern** β `balanced`, `sniper` (fast aimed bolts), `artillery` | |
| (slow heavy orbs + dense shockwaves), `swarm` (minion floods), or `berserker` | |
| (relentless charges). The active pattern shows next to the boss's name. | |
| - **Boss attack speed (with decaying mercy)** β the GM reads every wizard's | |
| HP% and lives and tunes `boss_attack_speed` (0.5β2.0): slower for a wounded | |
| party, faster for a healthy one. Guardrail: the allowed floor rises each | |
| wave (no mercy left by ~wave 13), out-of-range or malformed values are | |
| clamped, and every trace records `requested` vs `applied` plus the floor. | |
| - **Boss & minion reset** β next-round boss HP, minion count/HP, spawn rate, | |
| boss damage, aggression, and the enemy archetype mix. | |
| - **Card pool** β which level-up cards may be offered next wave. | |
| Every round produces a structured **agent trace** (prompt β raw model output β | |
| parsed decision β applied effect), saved under `traces/` and shown live in the | |
| Gradio dashboard. | |
| ## Architecture | |
| - **Client** (`static/`): HTML5 canvas game loop in the browser (rendering + input). | |
| - **Server** (`app.py`, `game/`): FastAPI WebSocket + a ~20 Hz authoritative game | |
| tick on CPU. Gradio is mounted for the trace/leaderboard dashboard. | |
| - **Game Master** (`game/gamemaster.py`): `@spaces.GPU` burst inference at round | |
| boundaries only β the pattern ZeroGPU is built for. Falls back to deterministic | |
| logic if the model/GPU is unavailable (so it runs locally too). | |
| ## Run locally | |
| ```bash | |
| pip install -r requirements.txt | |
| python app.py | |
| # open http://localhost:7860 | |
| ``` | |
| The Game Master uses Nemotron only when a GPU + the `spaces`/`transformers` stack | |
| is present; otherwise it transparently uses the deterministic fallback so local | |
| dev and CI still work. | |
| ## Game Master model | |
| On a Space the model is loaded **at startup** (the ZeroGPU pattern: weights are | |
| downloaded and staged before any `@spaces.GPU` call, so the 60 s GPU window is | |
| spent purely on inference). Locally it is lazy-loaded on the first round. | |
| Environment variables: | |
| | Variable | Values | Effect | | |
| |---|---|---| | |
| | `HUGGINGWIZARDS_NO_LLM` | `1` | Skip the model entirely; deterministic Game Master (CI / quick dev). | | |
| | `HUGGINGWIZARDS_QUANT` | `auto` (default), `none`, `4bit`, `8bit` | Quantization via bitsandbytes. `auto` = bf16 on Spaces/big GPUs, NF4 4-bit on local GPUs with <12 GB VRAM. | | |
| Quantization notes: 4-bit NF4 shrinks the 4B model from ~8.5 GB to ~3 GB of | |
| VRAM and speeds up cold loads β ideal for small local GPUs. On ZeroGPU's H200 | |
| plain bf16 is both comfortable and faster per token, so `auto` keeps bf16 there. | |
| ## Assets | |
| Pixel art / audio from free packs (Tiny RPG Character Pack, Tiny Swords, | |
| Free Pixel Effects, Retro Impact Effect Pack, Pixel UI pack 3, Pixel RPG Music | |
| Pack). See each pack's license. | |
| - **Maps**: each boss faction has its own territory β the Tiny Swords grass | |
| tileset plus a per-theme ground tint, landmark buildings | |
| (`static/assets/buildings/`: orc camp huts, the Iron Legion's blue castle, | |
| the Lancer Host's red keep, the Archer Coven's monastery & ranges) and a | |
| seeded scenery mix (bushland / rockfields / forest). Scenery is purely | |
| cosmetic β the server simulation is unchanged. | |
| - **Effects**: spell-cast muzzle flashes, impact bursts (on boss/minion/player | |
| hits) and death poofs are drawn client-side from the Free Pixel Effects | |
| spritesheets, triggered by snapshot flags (`hurt`, attack, minion id removal). | |
| Skill activations and GM blessings are server-driven events rendered with | |
| more of the pack: freezing novas, felspell blasts, protection circles, | |
| vortex summons, sunburn blessings, magic-bubble heals. | |
| - **Characters**: pick a champion (Warrior / Archer / Lancer / Pawn) on the | |
| name screen β Tiny Swords blue units (`static/assets/chars/`), all size-normalized | |
| and growing with level. | |
| - **Special bosses**: **Aegis** (red wave, holy-spell attacks) on waves 3/9/15β¦ and | |
| **Toaster Bot** (green wave, glitch-portal attacks) on waves 5/11/17β¦ Beat one and | |
| every survivor gains its signature attack as a permanent power. | |
| - **Timed auras**: rare floor-only power-ups (30β60 s) visualized with the Retro | |
| Impact Effect Pack (`static/assets/retro/`) wreathing the wizard. | |
| - **Music**: a looping track from the Pixel RPG Music Pack starts on the first | |
| join/spectate click (browser autoplay policy); a π button toggles it. | |