A browser-based AI arena game where LLM-powered NPCs compete in team-based challenges. Watch AI agents explore, strategize, and solve puzzles in real-time!
- 4 AI NPCs in 2 competing teams (Red vs Blue)
- Real-time LLM decisions using Groq/Gemini APIs
- Team-based challenges requiring coordination
- Zone exploration with locked gates and puzzles
- Live commentary generated by AI
- WebSocket real-time updates
# Clone the repo
git clone https://github.com/07AMIT10/npc.git
cd npc
# Set up API keys
export GROQ_API_KEY=your_groq_key # Fast action decisions
export GEMINI_API_KEY=your_gemini_key # Strategic brain
# Run the server
go run ./cmd/server/main.go
# Open http://localhost:8080┌──────────────┐ ┌─────────────┐ ┌──────────────┐
│ Browser UI │ ←→ │ Go Server │ ←→ │ LLM APIs │
│ (Canvas) │ WS │ (Fiber) │ │ (Groq/Gemini)│
└──────────────┘ └─────────────┘ └──────────────┘
npc/
├── cmd/server/main.go # Entry point
├── internal/
│ ├── api/ # LLM integration & orchestration
│ ├── llm/ # Provider adapters & load balancing
│ ├── game/ # World, teams, zones
│ ├── challenge/ # Puzzle system
│ └── observability/ # Tracing & audit logs
├── web/
│ ├── index.html # Game page
│ ├── game.js # Canvas rendering
│ └── style.css # Dark theme UI
└── config.yaml # Configuration
- Cost Optimization - Reduce LLM API costs
- Visual Polish - Modern UI with animations
- Scalability - Prepare for deployment
Currently: 4 NPCs × 15 decisions/min = 60 API calls/minute
Instead of 4 separate API calls, combine all NPCs into ONE prompt:
// Before: 4 calls
for _, npc := range npcs {
decision := callLLM(npc.observation)
}
// After: 1 call
combinedPrompt := `
NPCs:
1. Explorer (red) at [100,100], sees gate at dist 350
2. Scout (red) at [200,150], sees Wanderer at dist 400
3. Wanderer (blue) at [800,600], sees gate at dist 250
4. Seeker (blue) at [750,550], idle
Respond with decisions for ALL NPCs as JSON array.
`
decisions := callLLM(combinedPrompt) // 1 call instead of 4!Expected savings: ~75%
| Optimization | Savings |
|---|---|
| Multi-NPC prompts | 75% fewer calls |
| Decision caching | 30% cache hits |
| Token compression | 73% smaller prompts |
| Total | ~85% reduction |
- Vanilla JS (1274 lines in single file)
- Basic canvas rendering
- No animations or effects
src/
├── components/
│ ├── GameCanvas/ # Canvas + particle system
│ ├── Sidebar/ # React components
│ ├── Header/ # Animated scoreboard
│ └── Overlay/ # Tooltips, modals
├── store/
│ └── gameStore.ts # Zustand state
└── hooks/
└── useWebSocket.ts # WS connection
| Feature | Description |
|---|---|
| Particle System | Movement trails, gate unlock effects |
| Animated Scores | Count-up animation with glow |
| Tooltips | Hover over NPCs/gates for info |
| Minimap | Overview in corner |
| Smooth Transitions | Framer Motion animations |
class ParticleSystem {
// NPC movement - subtle dust trail
emitMovementTrail(x, y, color) {...}
// Gate unlock - celebration burst
emitGateUnlock(x, y) {...}
// Challenge - thinking sparkles
emitThinkingSparkles(npc) {...}
}| Platform | Cost | Cold Start | Best For |
|---|---|---|---|
| Render | Free | 30s after 15min | Getting started |
| Fly.io | ~$0-5/mo | <1s | Production |
| Railway | Free tier | Similar to Render | Quick deploys |
- Fork this repo on GitHub
- Create new Web Service on Render
- Connect your GitHub repo
- Set environment variables:
GROQ_API_KEY- Your Groq API keyGEMINI_API_KEY- Your Gemini API key
- Deploy!
- Sign up at UptimeRobot (free)
- Create HTTP(s) monitor
- URL:
https://your-app.onrender.com/health - Interval: 14 minutes
- Server stays awake during monitored hours!
docker build -t npc-arena .
docker run -p 8080:8080 \
-e GROQ_API_KEY=your_key \
-e GEMINI_API_KEY=your_key \
npc-arenaEnable cancelling in-flight LLM calls when users reset:
ctx, cancel := context.WithCancel(context.Background())
// User clicks Reset → cancel() → saves API tokenstransport := &http.Transport{
MaxIdleConns: 100,
MaxIdleConnsPerHost: 10,
}import "golang.org/x/time/rate"
limiter := rate.NewLimiter(rate.Limit(5), 5)
limiter.Wait(ctx) // Context-aware!# Fast SLM (pick one)
GROQ_API_KEY=xxx # Recommended
SAMBANOVA_API_KEY=xxx
HF_API_KEY=xxx
# Brain LLM
GEMINI_API_KEY=xxx # Recommended
# Optional: Per-NPC overrides
NPC_EXPLORER_PROVIDER=groq
NPC_EXPLORER_MODEL=llama-3.1-70bgame:
tick_rate: 60
decision_rate: 2
model_roles:
movement:
provider: groq
model: llama-3.1-8b-instant
challenge:
provider: gemini
model: gemini-2.0-flash| Button | Action |
|---|---|
| ▶ Start | Begin simulation |
| ⏸ Pause | Freeze NPCs |
| 🔄 Reset | Restart world |
| Endpoint | Description |
|---|---|
GET / |
Game UI |
GET /health |
Server status |
GET /stats |
LLM statistics |
GET /test |
Test all providers |
WS /ws |
Real-time game updates |
# Run with hot reload
go run ./cmd/server/main.go
# Run tests
go test ./...
# Build binary
go build -o npc-server ./cmd/serverMIT
- Groq - Ultra-fast LLM inference
- Google Gemini - Strategic AI
- Fiber - Go web framework
