solanapolis
v2.1.3
Published
ποΈ Solanapolis β A real-time 3D city built on Solana. AI NPCs, Dubai Marina, Convex chat, wallet connect, claim parcels. One command: npx solanapolis
Maintainers
Readme
SOLANApolis
powered by Heliopolis and Helius on Solana
A real-time 3D city built from Solana wallet activity β claim your building, earn your plane, drive your car, explore the globe, fly anywhere on Earth, and dive into Bikini Bottom. $MAWD token-gated via Helius DAS API.
Quick Start
npx solanapolisThat's it. One command opens an interactive terminal dashboard with live city stats, Solana network data, wallet lookup, and an ASCII city map. No setup, no config, no browser required.
Want the full 3D game running locally?
npx solanapolis --serveThis installs all dependencies, configures environment variables, starts the Next.js game server, and opens your browser β all automatically.
Or play live right now: solanpolis.netlify.app
What is this?
SOLANApolis visualizes the Solana blockchain as a living city. Every wallet that has ever swapped tokens on Solana becomes a building. The more you've traded, the taller and more elaborate your building. Sign in with Phantom, and your building appears on the skyline β along with your personal plane or car if you claimed a slot early enough. Then zoom out to an interactive 3D globe, pick any location on Earth, and explore it with real satellite terrain and OSM Buildings β all rendered in your browser or streamed from an Unreal Engine 5 backend.
City Slots
SOLANApolis has a limited economy. There are only 1,000 total wallet slots in the city, and the first to claim get the best perks:
| Slot Type | Capacity | Perk | |-----------|----------|------| | β Planes | 100 | First 100 wallets each get a personal plane that circles above their building | | π Cars | 250 | First 250 wallets each get a resident car that drives the city streets | | π’ Buildings | 1,000 | All wallets get a unique building sized by their on-chain activity |
- Planes orbit above their owner's building at unique altitudes, speeds, and colors
- Cars continuously cruise the streets near their owner's block, each with a distinct color from a 20-color palette
- Clicking any plane or car focuses the camera on the owner's building and shows their wallet info
- The UI badge in the top-left corner shows real-time slot fill progress for wallets, planes, and cars
Features
3D Solana City
- Every Solana wallet address with swap history generates a unique building
- Building height, width, and detail scale with trading volume and transaction count
- Buildings are deterministically colored from wallet address β no two look alike
- Five skyscraper types for downtown buildings: Setback (Art Deco), Twin Peaks, Cantilever, Spire, and standard Box β each with multi-tier geometry and procedural windows
- Procedural window shader with per-window color variation (warm yellow, cool white, amber, blue TV glow), per-window on/off state based on time of day, slow pulsing, and day/night transitions
- Day/night cycle with dynamic lighting, fog, atmospheric haze, and stars
- Instanced mesh rendering for thousands of buildings at 60fps
- Parks, trees, lamp posts, road dashes, and sidewalks β all instanced
- Beach scene with animated ocean, waves, seagulls, and boats along the southern shoreline
- π¦ Bikini Bottom district β underwater city east of the main map with lobster NPCs, pineapple house, coral reef, animated kelp, tiki buildings, and glass dome
- AI Town sprite integration β city NPC overlays now use imported AI Town pixel-art character sprites and shared spritesheet metadata in the main frontend
π Globe View (NEW)
- Interactive 3D Earth powered by CesiumJS with real satellite imagery and terrain
- OSM Buildings 3D Tiles (Cesium Ion asset #96188) β millions of real-world buildings with height-based color coding:
- π΄ Red: 200m+ (skyscrapers)
- π Orange: 100β200m (major towers)
- π‘ Yellow: 50β100m (tall buildings)
- π’ Teal: 20β50m (mid-rise)
- π΅ Blue: under 20m (low-rise)
- Per-building metadata popovers β hover over any building to see its name, address, type, floor count, and height (adapted from Cesium's dynamic metadata UI patterns)
- π Locations β instant fly-to for 9 world cities: New York, London, Tokyo, Dubai, Paris, San Francisco, Sydney, Giza, Solana Beach
- π Earth View β zoom out to see the full planet from space
- Double-click any location to transition directly to the Cesium flight simulator there
- Shift+click β Google Street View panel via Cesium Ion's experimental
/experimental/panoramas/googleendpoint - Live HUD showing real-time LAT / LON / ALT as you navigate
- B toggle buildings on/off, L toggle locations panel, Esc return to city
Cesium Flight Simulator
- Full-screen flight simulator powered by Cesium.js with real satellite imagery and 3D terrain
- Spawns at London (51.5074Β°N, 0.1278Β°W) at 500m altitude, or at coordinates selected from the Globe view
- Aircraft physics with realistic banking:
- Throttle controls (W/S) with realistic acceleration
- Roll-induced yaw for realistic banking turns (A/D keys)
- Climb rate tied to pitch (Space/E)
- Gravity and stall simulation
- Crash detection when altitude < 5m
- Follow camera positioned correctly behind the aircraft with banking tilt and dynamic FOV
- Camera toggle (C) between follow and orbit views
- HUD showing speed (km/h), altitude (m), and heading (Β°)
- Crash screen with instant restart
- Error handling with retry/exit UI when initialization fails
Resident Planes (100 slots)
- First 100 wallets each get a 3D plane (fuselage, wings, tail fin) rendered via instanced meshes
- Each plane circles above its owner's building with unique orbit radius (8β26 units), altitude, angular speed, and warm color tint
- Planes bank gently into turns and oscillate in altitude
- Hover to see wallet info tooltip; click to navigate to the building
Resident Cars (250 slots)
- First 250 wallets each get a detailed 3D car (body, glass cabin, 4 wheels, floating diamond marker)
- Cars continuously drive city streets following paths generated from their building's block
- Each car has a unique color from a curated 20-color palette
- Cars automatically regenerate new routes when they reach the end of a path
- Hover to see wallet info; click to zoom to the owner's building
Swap Cars (AI Traffic)
- Live swap events from the database spawn AI-driven cars that drive through the city
- Up to 60 concurrent swap cars with fade-in/drive/fade-out lifecycle
- Each car carries swap metadata (token in/out, SOL amount)
- Click any swap car to open the swap info panel and follow it with the camera
- Swap particles: GPU-accelerated particle bursts fire at buildings when their wallet's swap car spawns β frame-rate independent physics
New Building Spotlight
- When a new wallet connects, a gold pulsing spotlight beam appears on their building
- Animated ring + point light effect that fades out after 8 seconds
- Triggered by new Phantom wallet connections in real time
π¦ $MAWD Token Gate (Bikini Bottom)
- Token-gated access β users must hold
$MAWDtokens to enter Solanapolis - Token:
5Bphs5Q6nbq1FRQ7sk3MUYNE8JHzoSKVyeZWYM94pump - Helius DAS API integration:
getAssetβ fetches $MAWD token metadata (symbol, name, image, decimals, price)searchAssetsβ scans wallet holdings for fungible tokens matching the mint
- 4-state gate flow:
- Not connected β Bikini Bottom underwater themed gate with animated lobster guards, bubbles, swaying kelp, pineapple house landmark
- Verifying β Triple scanner ring animation while scanning wallet for $MAWD
- Access denied β Shows current balance (even if 0), "Buy $MAWD on Pump.fun" CTA, re-verify button, contract address
- Verified β Full access to Solanapolis
- Balance display β shows exact $MAWD balance with USD value from Helius price data
- Glassmorphic underwater card UI with deep ocean gradient, animated bubbles, and lobster NPCs
- Direct link to Pump.fun for purchasing $MAWD
π Bikini Bottom District (3D)
- Underwater city positioned east of the main map at coordinates (220, 0, -100)
- 12 lobster NPCs β animated walking, bobbing, and claw-snapping, each with unique color variation
- Pineapple house β central 3D landmark with leaves, door, and windows
- 30 coral formations β 3 types: branching, brain (sphere), and fan coral in random hues
- 20 animated kelp strands β swaying in simulated underwater currents
- 8 tiki buildings β cylindrical, box, and cone shapes with thatch roofs and glowing windows
- 200 underwater particles β floating plankton/bubbles rising through the scene
- Glass dome β semi-transparent physical material enclosure over the entire district
- Caustic lighting β blue point lights simulating underwater light refraction
- Entry sign β "Bikini Bottom" archway with glowing lobster ornaments
Phantom Connect
- Sign in with your Solana wallet via Phantom Connect SDK
- Supports Google, Apple, and injected wallet providers
- OAuth redirect flow works on Netlify, custom domains, and local development
- Your wallet address auto-generates your building the moment you connect
- If you're among the first 100/250, your plane or car appears automatically
Three.js Plane Mode
- In-city flight with a detailed plane model (capsule fuselage, swept wings, winglets, under-wing engines with intake rings, afterburner cones, and engine glow lights)
- YXZ Euler rotation order for proper heading/pitch/roll (standard aircraft convention)
- WASD + Q/E controls with pointer-lock mouse look
- Chase camera follows behind and above the plane
Mapbox Mini-Map
- Live 180Γ180px Mapbox GL mini-map in the flight simulator overlay
- Dark map style with an orange aircraft marker that rotates to match your heading
- Smooth
easeTo()camera following at ~10fps updates
Multiplayer Flying
- Two separate Supabase Realtime broadcast channels:
heliopolis-planesβ Three.js city fly-through mode (XYZ coordinates)heliopolis-cesium-planesβ Cesium flight simulator mode (lat/lon/alt/heading)
- See other connected wallets flying as 3D plane meshes in real time
- Remote planes use smooth lerp/slerp interpolation for fluid motion
- Plane color is deterministically derived from wallet address
Player Car Mode
- Drive a car through the city streets in third-person
- Bicycle-model physics with acceleration, braking, and steering
- AABB collision detection against all buildings and houses
- Chase camera follows behind and above the car
- WASD + Space controls
- Combat-ready β fire projectiles with F or left-click while driving
Combat System
- Available in both car and plane modes β enter Drive or Fly mode to start shooting
- Press F or left-click to fire projectiles
- Projectiles travel at 120 units/sec with slight gravity drop
- Fire rate: ~6.6 shots/sec (0.15s cooldown), up to 50 active projectiles
- Hit detection: sphere-based collision against all 100 resident planes and 250 resident cars
- Scoring: 50 points per plane hit, 25 points per car hit
- Visual effects:
- Glowing orange bullet heads (sphere geometry)
- Velocity-aligned stretch trails behind each projectile
- Expanding icosahedron explosions at hit locations (1 second lifetime)
- Muzzle flash point light when firing
- On-screen hit marker (β) flash on successful hits
Game HUD & Minimap
- Real-time tactical minimap (200Γ200px canvas, top-right corner)
- All buildings shown as gray dots
- Resident planes as amber dots
- Resident cars as indigo dots
- Active projectiles as red dots
- Hit locations as expanding red rings (2 second fadeout)
- Player position as an orange triangle with heading indicator
- FOV cone showing player's field of view
- Pulsing ring around the player position
- Grid overlay for spatial reference
- Legend showing dot color meanings
- Score bar (top-center) showing:
- Current mode (β AIR / π GROUND)
- Live score counter (smooth animation)
- Hit count
- Active projectile count
- Fire key hint
- Crosshair (center screen) β bracket-style with orange center dot
- All HUD elements auto-show when entering car/plane mode, auto-hide when exiting
Day/Night Cycle
- 8-keyframe system covering dawn, sunrise, day, golden hour, sunset, dusk, night, and late night
- Smooth interpolation of sky color, fog, ambient/directional/hemisphere/accent lights, sun position, and star opacity
- Procedural window illumination that responds to time β windows turn on at sunset, glow through the night, and switch off at dawn
- Lamp posts illuminate at night with emissive glow decals
Building Interaction
- Click any building to open the wallet info panel (transaction count, volume, age, fees, token list)
- Hover windows on selected buildings to see per-window token tooltips
- Selection beam highlight with animated glow
- Window hover detection uses the same UV math as the shader for pixel-perfect accuracy
Network Stats HUD
- Live Solana network stats: TPS (with color-coded delta), slot number, and epoch progress bar
- Polls every 10 seconds
- Gradient progress bar from indigo β orange
π₯οΈ CLI Terminal (npx solanapolis)
- One-command launch β
npx solanapolisopens a full interactive dashboard in any terminal - Live city stats β real-time citizen count, plane/car slot fill with progress bars
- Solana network β TPS, slot number, epoch progress pulled from the live game API
- Treasury balance β SOL balance and USD value
- Top buildings β ranked leaderboard of highest-activity wallets
- Wallet lookup β enter any Solana address to see transaction count, volume, age, and building status
- ASCII city map β terminal-rendered city visualization with building density (
ββββ) - Auto-detect β paste a wallet address at the prompt and it auto-looks it up
- Local server mode β
npx solanapolis --serveboots the full 3D game locally - Custom port β
npx solanapolis --serve --port 8080 - Cross-platform β works on macOS, Linux, and Windows
CLI Commands
| Command | Action |
|---------|--------|
| [1] or open | Open the live game in your browser |
| [2] or lookup | Look up any Solana wallet address |
| [3] or claim | Step-by-step guide to claim a parcel |
| [4] or refresh | Refresh live dashboard stats |
| [5] or serve | Start the full game server locally |
| [6] or map | Render ASCII city map in terminal |
| [7] or battle | Show the live combat leaderboard |
| [8] or reward | Check parcel reward eligibility |
| [9] or status | Show queue, treasury, and slot status |
| [10] or chat | Join realtime terminal city chat |
| q | Exit |
| wallet address | Auto-detects and looks up any pasted address |
Terminal Dashboard Preview
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ποΈ CITY STATUS β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ£
β Citizens: βββββββββββββββββββββββββββββββββββββ 480/1000 β
β Planes: ββββββββββββββββββββββββββββββββββββββ 100/100 FULL β
β Cars: ββββββββββββββββββββββββββββββββββββββ 240/250 10 open! β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β‘ SOLANA NETWORK β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ£
β TPS: 4,231 transactions/sec β
β Slot: 280,456,789 β
β Epoch: 642 (73.2% complete) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββTwitter Auth
- Sign in with Twitter/X via Supabase OAuth
- Auth state persists across sessions
- Citizen ID Card modal for authenticated wallets
π€ AI Agent Interactions (Grok Multi-Agent)
- 12 unique NPC personas β Nova, Cipher, Drift, Spark, Phantom, Echo, Blaze, Nexus, Vex, Flux, Prism, and Sable β each with distinct personalities and perspectives
- 3-turn conversations generated by
x-ai/grok-4.20-multi-agent-betavia OpenRouter with chain-of-thought reasoning enabled - Multi-turn reasoning continuity: agent
reasoning_detailsare passed back between turns for coherent dialogue - Conversations about city-specific topics: swap events, TPS records, sunset reflections, drone patrols, building expansions, aerial stunts
- Real-time conversation feed in the bottom-left β click to expand, see topic, and inspect the AI's chain-of-thought reasoning
- Cron-scheduled: new agent interactions auto-generate every 2 minutes via Convex scheduler
- Deterministic fallback when no API key is present β agents still converse with pre-written dialogue
π¬ Persistent Agent Conversations & Companion Agents
- Talk to any NPC β click any agent's name tag in the 3D world or the "Chat with [Agent]" buttons in the conversation feed to open a persistent 1-on-1 conversation
- 12 city NPC personas (Nova, Cipher, Drift, Spark, Phantom, Echo, Blaze, Nexus, Vex, Flux, Prism, Sable) each respond in-character with city-aware context
- Persistent chat threads β conversations are saved per wallet and persist across sessions via Convex
userConversationstable - Streamed agent replies β private NPC and companion chats now stream token-by-token via
@convex-dev/persistent-text-streaming, then persist the final response into the conversation history - LLM-powered replies β agent responses generated by your configured LLM (Grok/OpenAI/OpenRouter) with persona, conversation history, and city context in the system prompt
- Auto-summarization β long conversations are automatically summarized to maintain context without exceeding token limits
- Reply locking β the UI prevents overlapping sends while an agent reply is still streaming
- Fallback replies β if the LLM is unavailable, agents respond with deterministic in-character messages
π€ Custom Companion Agents
- Create your own AI companions β up to 5 per wallet, each with a custom name, personality, conversation goals, emoji, and character appearance
- Persona templates β quick-start templates for Trading Expert, City Guide, Security Analyst, and Creative Muse
- Companion panel β bottom-left "Companions" button shows all your companions with last message preview, including
Thinking...while a streamed reply is in flight - Full CRUD β create, chat with, and remove companions from the management panel
- Companion conversations use the same persistent thread system as NPC conversations, with the user-defined persona driving the LLM
π’ Live Visitor Counter
- Real-time count of online users powered by Convex reactive queries
- Heartbeat-based presence: frontend sends
heartbeat()every 30 seconds; stale sessions auto-expire - Mode breakdown: see how many visitors are π driving, β flying, or just browsing
- Pulsing green dot with animated count transitions β changes pulse when someone joins/leaves
- Integrated into the top-left branding panel next to the SOLANApolis logo
- Safe fallback behavior if the active Convex deployment is temporarily missing the
sitePresencetable or indexes
π Cinematic Loading Screen
- Replaces the basic "Loadingβ¦" text with a full cinematic experience
- Floating particle canvas with 50 animated particles
- Animated city silhouette with buildings rising from the horizon (
buildingRisekeyframes) - Gradient progress bar with shimmer effect that auto-advances to 90%
- Rotating tips about the city's features (planes, cars, combat, globe view)
- "Initializing city gridβ¦" status text + "Powered by Helius Γ Convex on Solana" branding
π¬ City Chat
- Real-time in-game chat powered by Convex with AI assistants
- Player messages, shared player-to-player city chat, NPC agent messages, and AI stream responses
- Supports streaming via
@convex-dev/persistent-text-streaming - Toggle open/close with unread message counter
- Read-only mode for visitors without a building; full chat for wallet holders
Using Chat
- City Chat β open the bottom-left
City Chatpanel to read the shared public conversation. Connected wallets with a claimed building can post into the live chat. - NPC chat β click an NPC name tag in the 3D city or use
Chat with [Agent]in the agent feed to open a private streamed conversation. - Companion chat β create a companion from the
Companionspanel, then open its thread to chat in the same persistent streamed UI. - Convex requirement β private streaming chat depends on both
NEXT_PUBLIC_CONVEX_URLandNEXT_PUBLIC_CONVEX_SITE_URL. The.convex.cloudURL powers queries/mutations, and the.convex.siteURL powers HTTP streaming. - Current scope β the app supports public player chat and private user-to-agent threads. Dedicated user-to-user DM threads are not implemented yet.
Tech Stack
| Layer | Technology |
|-------|-----------|
| Framework | Next.js 16 (App Router, Turbopack) |
| 3D City | React Three Fiber + drei + Three.js |
| Shaders | Custom GLSL (PBR building shader, house shader, headlight decals, GPU particles) |
| Globe & Flight | Cesium.js v1.139 + Cesium Ion (3D terrain + OSM Buildings) |
| Street View | Cesium Ion Experimental API (/experimental/panoramas/google) |
| Mini-Map | Mapbox GL v3 |
| Real-time Backend | Convex (reactive queries, mutations, actions, cron jobs, streaming) |
| AI Agent Engine | Grok 4.20 Multi-Agent Beta via OpenRouter (chain-of-thought reasoning) |
| Token Gate | Helius DAS API (getAsset + searchAssets) for $MAWD verification |
| Wallet Auth | @phantom/react-sdk |
| OAuth | Supabase Auth (Twitter) |
| Multiplayer | Supabase Realtime Broadcast |
| Blockchain Data | Helius API (Solana) |
| Token Prices | BirdEye API |
| Styling | Tailwind CSS |
| CLI | Node.js (interactive terminal dashboard) |
| Package | npm (solanapolis) |
| Deployment | Netlify + npm |
| UE5 Backend | Unreal Engine 5.7 + CesiumForUnreal + SolanaSDK + Pixel Streaming |
| Solana Runtime | .NET 9 + Solnet 5.x (SOLANApolisRuntime) |
Controls
π Globe View
| Input | Action | |-------|--------| | Left-click drag | Rotate globe | | Right-click drag | Pan | | Scroll | Zoom | | Middle-click | Tilt | | Double-click | Fly to location (opens Cesium flight) | | Shift+click | Open Street View panel | | B | Toggle OSM buildings | | L | Toggle locations panel | | π Locations | Quick-jump to 9 world cities | | π Earth | Zoom out to full Earth | | Esc | Return to city |
Cesium Flight Simulator
| Key | Action | |-----|--------| | W | Increase throttle | | S | Decrease throttle | | A | Bank left | | D | Bank right | | Space | Climb | | Q | Roll left | | E | Roll right / Descend | | C | Toggle camera mode | | Esc | Exit flight simulator |
Three.js Plane Mode
| Key | Action | |-----|--------| | W / β | Throttle up | | S / β | Throttle down | | A / β | Bank left | | D / β | Bank right | | Q / Space | Climb | | E | Descend | | F / Left-click | Fire projectile | | Esc | Exit plane mode |
Car Mode
| Key | Action | |-----|--------| | W / β | Accelerate | | S / β | Brake / Reverse | | A / β | Steer left | | D / β | Steer right | | Space | Brake | | F / Left-click | Fire projectile | | Esc | Exit car mode |
City View
| Input | Action | |-------|--------| | Left-click + drag | Pan / Orbit | | Right-click + drag | Rotate / Pan | | Scroll | Zoom | | Click building | Select wallet | | Click car | Follow car |
Setup
Option 1: One-Shot via npm (Recommended)
No cloning, no config files, no env setup:
npx solanapolisThis connects to the live Solanapolis backend and shows an interactive terminal dashboard.
The CLI's live API/browser target is the Netlify deployment at https://solanpolis.netlify.app/.
To run the full 3D game locally:
npx solanapolis --serveThe CLI automatically:
- Installs all dependencies
- Generates
.env.localwith preconfigured API tokens - Starts the Next.js dev server
- Opens your browser to
http://localhost:3000
Option 2: Clone & Run Manually
Prerequisites
- Node.js 18+
- A Netlify account (for deployment)
- .NET 9 (for SOLANApolisRuntime, optional)
- Unreal Engine 5.7 (for UE5 backend, optional)
Environment Variables
Create .env.local:
# Helius (Solana RPC)
HELIUS_API_KEY=your_helius_api_key
HELIUS_RPC_URL=https://mainnet.helius-rpc.com/?api-key=your_key
HELIUS_WSS_URL=wss://mainnet.helius-rpc.com/?api-key=your_key
HELIUS_WEBHOOK_SECRET=your_webhook_secret
HELIUS_WEBHOOK_ID=your_webhook_id
# Supabase
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key
SUPABASE_SERVICE_ROLE_KEY=your_service_role_key
# Convex
NEXT_PUBLIC_CONVEX_URL=https://your-deployment.convex.cloud
NEXT_PUBLIC_CONVEX_SITE_URL=https://your-deployment.convex.site
CONVEX_DEPLOYMENT=prod:your-deployment-name
# Example deployed values
# NEXT_PUBLIC_CONVEX_URL=https://shocking-hound-837.convex.cloud
# NEXT_PUBLIC_CONVEX_SITE_URL=https://shocking-hound-837.convex.site
# Phantom Connect
PHANTOM_APP_ID=your_phantom_app_id
# BirdEye
BIRDEYE_API_KEY=your_birdeye_api_key
BIRDEYE_WSS_URL=wss://public-api.birdeye.so/socket/solana?x-api-key=your_key
# Cesium Ion (required for Globe + Flight)
NEXT_PUBLIC_CESIUM_ION_TOKEN=your_cesium_ion_token
# Mapbox
NEXT_PUBLIC_MAPBOX_TOKEN=your_mapbox_token
# Pixel Streaming (optional, for UE5 backend)
NEXT_PUBLIC_PIXEL_STREAMING_URL=ws://localhost:8888Install & Run
npm install
npm run devOpen http://localhost:3000.
Build
npm run build
npm startUE5 Backend Setup (Optional)
The UE5 backend provides high-fidelity rendering streamed via Pixel Streaming:
# 1. Link plugins into the UE5 project
cd SOLANApolis-UE5
./setup-plugins.sh
# 2. Build the Solana runtime (.NET 9)
./build-solanakit.sh
# 3. Open in Unreal Engine 5.7.x
# SOLANApolis-UE5/SOLANApolis.uproject
# 4. Configure Cesium Ion token in Project Settings β Plugins β Cesium
# 5. Launch with Pixel Streaming
SOLANApolis -PixelStreamingIP=0.0.0.0 -PixelStreamingPort=8888
# 6. Set NEXT_PUBLIC_PIXEL_STREAMING_URL=ws://your-server:8888 in .env.localArchitecture
bin/
βββ solanapolis.js # CLI launcher β interactive dashboard + server mode
src/
βββ app/
β βββ layout.tsx # PhantomWrapper + AuthProvider + MawdTokenGate
β βββ page.tsx # Main entry β dynamic import of CityScene
β βββ globals.css # Tailwind + activity keyframes + Bikini Bottom CSS
β βββ auth/callback/page.tsx # Phantom OAuth redirect handler
β βββ api/
β βββ wallets/route.ts # GET all placed wallets with identity data
β βββ wallet/[address]/ # Wallet lookup, balances, identity, tokens
β βββ network-stats/route.ts # Solana TPS, slot, epoch progress
β βββ token-gate/route.ts # POST β $MAWD token verification via Helius DAS API
β βββ webhooks/helius/ # Helius webhook receiver
β βββ auth/ # Phantom auth, callback, link-wallet
βββ components/
β βββ CityScene.tsx # Root 3D scene β orchestrates all components
β βββ CityGrid.tsx # City layout: roads, sidewalks, blocks, parks
β βββ CesiumGlobe.tsx # π Interactive 3D Earth + OSM Buildings + metadata
β βββ CesiumFlight.tsx # β Full Cesium flight simulator
β βββ PixelStreamViewer.tsx # UE5 Pixel Streaming WebRTC viewer
β βββ InstancedBuildings.tsx # Plain box buildings (instanced mesh + PBR shader)
β βββ InstancedSkyscrapers.tsx # Multi-tier skyscrapers (setback, twin, cantilever, spire)
β βββ InstancedCityPlanes.tsx # 100 resident planes circling owner buildings
β βββ InstancedResidentCars.tsx # 250 resident cars driving city streets
β βββ InstancedCars.tsx # AI swap-event cars (up to 60)
β βββ InstancedHouses.tsx # Low-rise placeholder houses
β βββ InstancedTrees.tsx # Park + sidewalk trees
β βββ InstancedLampPosts.tsx # Street lamps with night glow
β βββ InstancedRoadDashes.tsx # Road center-line dashes
β βββ FlightMiniMap.tsx # Mapbox mini-map overlay
β βββ PlaneMode.tsx # Three.js in-city plane mode
β βββ PlayerPlane.tsx # Player-controlled plane (detailed 3D mesh)
β βββ PlayerCar.tsx # Player-controlled car with collision
β βββ MultiplayerPlanes.tsx # Supabase Realtime multiplayer
β βββ BeachScene.tsx # Animated ocean, waves, seagulls, boats
β βββ BikiniBottom.tsx # π¦ Underwater district: lobster NPCs, coral, pineapple house
β βββ MawdTokenGate.tsx # $MAWD token gate with Bikini Bottom underwater theme
β βββ SceneLighting.tsx # 5-light rig + stars + fog
β βββ SelectionBeam.tsx # Building selection glow beam
β βββ SwapParticles.tsx # GPU particle bursts on swap events
β βββ NewBuildingSpotlight.tsx # Gold spotlight on new buildings
β βββ ProjectileRenderer.tsx # Instanced projectile bullets + explosions
β βββ GameHUD.tsx # Real-time minimap + score bar + crosshair
β βββ CitySlotsBadge.tsx # UI: wallet/plane/car slot counters
β βββ WalletPanel.tsx # Wallet info side panel
β βββ SwapPanel.tsx # Swap car info panel
β βββ WindowTooltip.tsx # Building/token hover tooltip
β βββ WalletSearch.tsx # Top search bar with autocomplete
β βββ ActivityFeed.tsx # Left-side activity stream
β βββ NetworkStats.tsx # Bottom-right TPS/slot/epoch HUD
β βββ AuthPanel.tsx # Wallet + Twitter auth UI
β βββ HowItWorksModal.tsx # Info modal
β βββ CitizenCardModal.tsx # Citizen ID card (lazy loaded)
β βββ Ground.tsx # Ground plane mesh
β βββ Park.tsx # Park block with grass
β βββ LeaderboardPanel.tsx # Combat leaderboard
β βββ GameChat.tsx # In-game chat (Convex + AI streaming)
β βββ LoadingScreen.tsx # Cinematic loading with particles + city silhouette
β βββ LiveCounter.tsx # Real-time visitor counter (Convex presence)
β βββ AgentChatFeed.tsx # AI agent-to-agent conversation feed + "Chat with" buttons
β βββ AITownNPCs.tsx # AI Town agents as 3D humanoids + drones (clickable name tags)
β βββ ConversationFocus.tsx # Persistent 1-on-1 chat overlay with streamed NPC/companion replies
β βββ CompanionPanel.tsx # Companion agent management panel (list, chat, delete, live reply previews)
β βββ CompanionCreator.tsx # Modal for creating custom AI companion agents
β βββ AICityTrafficBridge.tsx # Syncs wallets β Convex NPC agents
β βββ AITownSpriteAvatar.tsx # Pixel-art avatar renderer for AI Town character sheets
β βββ DubaiDistrict.tsx # Dubai-style landmark buildings
β βββ ConvexWrapper.tsx # Shared Convex provider gate for optional/reactive features
β βββ PhantomWrapper.tsx # Client-side PhantomProvider wrapper
βββ context/
β βββ AuthContext.tsx # Auth state (Supabase + Phantom)
βββ lib/
β βββ ai-town-assets.ts # Shared AI Town spritesheet + ambient animation registry
β βββ city-slots.ts # Slot constants (1000 wallets, 100 planes, 250 cars)
β βββ city-constants.ts # Grid layout: block size, road positions, park blocks
β βββ city-zoning.ts # Zone classification: downtown, midrise, lowrise, park
β βββ building-math.ts # Building dimensions, colors, window attributes
β βββ building-shader.ts # Custom GLSL PBR shader with procedural windows
β βββ house-shader.ts # House PBR shader with day/night tinting
β βββ skyscraper-types.ts # Skyscraper tier definitions (setback, twin, etc.)
β βββ player-plane.ts # Plane physics engine (speed, heading, pitch, roll)
β βββ player-car.ts # Car physics engine (bicycle model + collision)
β βββ collision-map.ts # AABB spatial hash collision detection
β βββ car-system.ts # AI car lifecycle manager (spawn, update, despawn)
β βββ car-paths.ts # City path generation for AI cars
β βββ day-night.ts # 8-keyframe day/night interpolation system
β βββ convex-config.ts # Shared Convex deployment/config helpers
β βββ swap-events.ts # Swap event polling from Supabase
β βββ projectile-system.ts # Projectile physics, lifecycle, and hit detection
β βββ multiplayer-manager.ts # Supabase Realtime multiplayer sync
β βββ sound-engine.ts # Audio engine: plane engine, clicks
β βββ supabase.ts # Supabase client (browser)
β βββ supabase-admin.ts # Supabase admin client (server)
βββ types/
β βββ wallet.ts # WalletBuilding + PlacedWallet interfaces
convex/
βββ schema.ts # Full Convex schema (AI Town + agents + user profiles + companions)
βββ agentInteractions.ts # Grok multi-agent NPC-to-NPC conversations (3-turn reasoning)
βββ userAgentChat.ts # Persistent user-to-agent conversation state + streamed reply placeholders
βββ userAgentChatStream.ts # HTTP streaming endpoint for private NPC/companion replies
βββ userProfiles.ts # Wallet-based user profile CRUD
βββ companionAgents.ts # Custom companion agent CRUD (create, list, update, remove)
βββ npcCarAgents.ts # LLM-driven NPC car behavior decisions
βββ chat.ts # City chat with AI streaming responses
βββ httpOrigins.ts # Shared CORS allowlist for Convex HTTP streaming endpoints
βββ world.ts # AI Town world management (heartbeat, join, leave)
βββ messages.ts # AI Town conversation messages + speech bubbles
βββ sitePresence.ts # Live visitor counter (heartbeat + reactive count)
βββ flightPresence.ts # Multiplayer flight/car presence snapshots
βββ crons.ts # Scheduled jobs (world management, data vacuum)
βββ constants.ts # Game constants (timeouts, cooldowns, distances)
βββ agent/
β βββ conversation.ts # Agent conversation generation (start, continue, leave)
β βββ memory.ts # Agent memory system (store, search, reflect)
β βββ embeddingsCache.ts # Embedding cache for memory search
β βββ schema.ts # Memory + embedding table schemas
βββ aiTown/
β βββ agent.ts # Agent tick logic, conversation initiation
β βββ agentOperations.ts # Agent actions (remember, generate message, do something)
β βββ conversation.ts # Conversation lifecycle (invite, walk, participate)
β βββ game.ts # Game state management
β βββ movement.ts # Pathfinding and movement
β βββ player.ts # Player class
β βββ schema.ts # AI Town table schemas
β βββ ... # Additional modules (ids, inputs, world, worldMap)
βββ engine/
β βββ abstractGame.ts # Generic game engine base class
β βββ schema.ts # Engine table schemas
βββ util/
βββ llm.ts # LLM client (OpenRouter/OpenAI/Together/Ollama)
βββ geometry.ts # Math helpers
βββ ... # Compression, async utils, types
SOLANApolis-UE5/ # Unreal Engine 5.7 project (optional)
βββ SOLANApolis.uproject # Project file (CesiumForUnreal + SolanaSDK + PixelStreaming)
βββ setup-plugins.sh # Symlink plugins into the UE5 project
βββ build-solanakit.sh # Build .NET 9 Solana runtime
βββ Source/
β βββ SOLANApolis.Target.cs # Game target rules
β βββ SOLANApolisEditor.Target.cs # Editor target rules
β βββ SOLANApolis/
β βββ SOLANApolis.Build.cs # Module build rules
β βββ SOLANApolisFlightPawn.h/.cpp # Flight pawn with Cesium globe anchor, Solana wallet, combat
β βββ SOLANApolisChainBridge.h/.cpp # Solana β UE5 bridge (balance, skins, kills)
βββ SolanaKit/
β βββ SOLANApolisRuntime.csproj # .NET 9 Solana runtime (Solnet 5.x)
βββ Plugins/ (symlinked)
βββ CesiumForUnreal β cesium-unreal-main
βββ SolanaSDK β Solana-Unreal-SDK-main
Solana-Unreal-SDK-main/ # Solana SDK for UE5
βββ SolanaSDK.uplugin # Plugin descriptor (UnrealSOLNET + LinkStream)
βββ ...
public/
βββ ai-town/
β βββ assets/ # Imported AI Town sprite sheets used by the main frontend
βββ plane.glb # Aircraft 3D model
βββ helius-icon.svg # Helius logo icon
βββ helius-logo.svg # Helius logo fullDeployment
npm Package
SOLANApolis is published as solanapolis on npm:
# Interactive terminal dashboard (no server needed)
npx solanapolis
# Full local game server
npx solanapolis --serve
# Custom port
npx solanapolis --serve --port 8080The current published package includes the Netlify live target and the updated AI Town frontend asset bridge.
To publish a new version:
# Bump version in package.json, then:
npm publish --access publicNetlify
The web app is deployed to Netlify. This repo already includes netlify.toml and the Next.js Netlify plugin.
Primary live deploy URL: https://solanpolis.netlify.app/
netlify deploy --prodRequired Netlify environment variables β add all variables from .env.local in the Netlify dashboard under Site configuration β Environment variables.
At minimum, production needs:
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_ANON_KEY=
SUPABASE_SERVICE_ROLE_KEY=
NEXT_PUBLIC_CONVEX_URL=
NEXT_PUBLIC_CONVEX_SITE_URL=
CONVEX_DEPLOYMENT=
HELIUS_API_KEY=
NEXT_PUBLIC_CESIUM_ION_TOKEN=
NEXT_PUBLIC_MAPBOX_TOKEN=
PHANTOM_APP_ID=If you use Netlify's Supabase integration, make sure you still expose the frontend variable names this app reads: NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_ANON_KEY.
If you change Convex schema or functions, redeploy Convex too:
npx convex deployIf private streamed chats do not connect, verify both Convex frontend URLs are set:
NEXT_PUBLIC_CONVEX_URL=https://your-deployment.convex.cloud
NEXT_PUBLIC_CONVEX_SITE_URL=https://your-deployment.convex.siteUE5 Pixel Streaming Deployment
For production UE5 streaming, deploy the built UE5 project to a GPU instance (AWS g4dn, Azure NV, etc.) with:
SOLANApolis -RenderOffscreen -PixelStreamingIP=0.0.0.0 -PixelStreamingPort=8888 -ForceRes -ResX=1920 -ResY=1080Then set NEXT_PUBLIC_PIXEL_STREAMING_URL to the WebSocket URL of the signaling server.
Phantom Connect Configuration
In the Phantom developer portal, configure your app with these redirect URLs:
https://solanapolis.com/auth/callbackhttps://solanpolis.netlify.app/auth/callbackhttps://heliopolis.ngrok.app/auth/callbackhttp://localhost:3000/auth/callback(for local dev)
Supabase Configuration
Enable the following in your Supabase project:
- Auth β Providers: Enable Twitter/X OAuth with your API keys
- Realtime: Enable broadcast on the
publicschema - Database: The app reads wallet addresses from the
walletstable - RPC function:
get_random_swaps(n)returns random swap events for car traffic - RPC function:
repair_unplaced_wallets()self-heals unplaced complete wallets
Performance
SOLANApolis is engineered for 60fps even with thousands of objects:
- Instanced rendering for all repeated geometry (buildings, skyscrapers, trees, lamp posts, cars, planes, road dashes)
- Custom GLSL shaders injected into Three.js standard PBR β no
onBeforeCompile(avoids program cache invalidation) - GPU particle system for swap burst effects with custom vertex/fragment shaders
- Frame-rate independent physics β all physics simulations use actual frame delta, never hardcoded timesteps
- Ref-based state for high-frequency updates (time, car positions, camera) to avoid React re-renders
- Lazy loading for heavy components (CesiumFlight, CesiumGlobe, CitizenCardModal)
- Spatial hash collision detection for O(1) car-building collision queries
- Cesium Ion streaming β terrain and building tiles loaded on-demand, not preloaded
- Pixel Streaming (optional) β stream UE5 rendering over WebRTC for high-fidelity clients
Credits
- Flight simulator physics adapted from cesium-flight-simulator
- Globe architecture inspired by Cesium VR tutorials (Viewing the Globe, Dynamic Metadata UI)
- Blockchain data powered by Helius
- Token prices from BirdEye
- Maps by Mapbox
- Satellite imagery via Cesium + OpenStreetMap
- OSM Buildings 3D Tiles via Cesium Ion asset #96188
- Solana SDK for UE5 by Bifrost Technologies
- Google Street View via Cesium Ion experimental API
