Spaces:
Running
title: NoExit
emoji: πͺ
colorFrom: gray
colorTo: red
sdk: static
pinned: false
license: mit
NoExit
A real-time, text-driven 2D game built in Unity where the player is locked in a room with two AI-generated characters who remember everything you tell them.
Inspired by Sartre's Huis Clos β there is no exit.
Gameplay
Type freely to converse with two characters whose names, backstories, and personalities are generated at runtime. Every piece of personal information the player reveals is silently extracted and stored β and the characters will bring it up again.
- Type text to talk; press Enter to submit
- Press Enter again to dismiss a dialogue box
- Arrow keys move the player character
- Point and click movement
Technical Architecture
Engine & Rendering
- Unity 2D (Universal Render Pipeline)
- TextMeshPro for all UI text
- Light2D for atmosphere and reactive flicker effects
- WebGL build served via Hugging Face Spaces
AI Pipeline
All AI calls route through Hugging Face Spaces β no API keys are exposed to the client.
Dialogue Model
Endpoint: jejunepixels-noexit-proxy.hf.space/chat
A proxy Space that forwards chat completion requests. Includes automatic retry logic (up to 2 retries, 10s delay) to handle cold starts.
Personal Information Extractor
Scans every line of dialogue β from both the player and the characters β for personally identifying information using a small LLM. Two switchable backends:
| Backend | Endpoint | Model |
|---|---|---|
| Custom FastAPI | jejunepixels-qwen3-4B-info-extractor-fastapi.hf.space/extract |
Qwen3 4B |
| HF Gradio Space | jejunepixels-qwen3-0-6b-info-extractor-api.hf.space/extract |
Qwen3 0.6B |
Returns extracted information as a string, or "none" if nothing personal was found.
Character Generation
At game start, two characters are generated procedurally via sequential LLM calls: first a name, then a full backstory and personality description using that name. The resulting description becomes each character's permanent system prompt for all future dialogue.
Addressing System
Once a character has accumulated personal information about the player, an LLM routing call (capped at 10 tokens) decides which character should respond to the next player message β Character 1, Character 2, or both. Falls back to both responding after 3 failed attempts.
Reactive Events
A timer-based event system fires unprompted questions at the player during pauses in conversation. If the player has revealed personal information, the question targets a specific piece of what was shared. Otherwise it asks a generic get-to-know-you question. Each fired event schedules the next one randomly.
Dialogue Display
- Words reveal one by one with a typewriter effect
- Up to 3 dialogue boxes can be active simultaneously
- AABB overlap detection repositions boxes to prevent collisions
- Player input is locked while any dialogue is displaying
- When personal information is detected, the scene lighting flickers
Data Logging
Every AI interaction is logged locally in JSONL format using system / user / assistant triplet structure, across four separate files for dialogue, info extraction, addressing decisions, and character generation. Intended for fine-tuning and analysis.
Configurable Parameters
| Parameter | Description |
|---|---|
| Dialogue model | Model ID used for character dialogue and addressing |
| Info model | Model ID used for information extraction |
| Temperature | Separate values for dialogue and character generation |
| Max dialogue tokens | Token cap per character response (default: 150) |
| Max addressing tokens | Token cap for routing decisions (default: 10) |
| Info extractor backend | Toggle between Qwen3 4B (FastAPI) and 0.6B (Gradio) |