solanapolis 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +518 -0
- package/bin/solanapolis.js +197 -0
- package/convex/_generated/api.d.ts +175 -0
- package/convex/_generated/api.js +23 -0
- package/convex/_generated/dataModel.d.ts +60 -0
- package/convex/_generated/server.d.ts +143 -0
- package/convex/_generated/server.js +93 -0
- package/convex/agent/conversation.ts +352 -0
- package/convex/agent/embeddingsCache.ts +110 -0
- package/convex/agent/memory.ts +450 -0
- package/convex/agent/schema.ts +53 -0
- package/convex/aiChat.ts +54 -0
- package/convex/aiTown/agent.ts +382 -0
- package/convex/aiTown/agentDescription.ts +27 -0
- package/convex/aiTown/agentInputs.ts +155 -0
- package/convex/aiTown/agentOperations.ts +178 -0
- package/convex/aiTown/conversation.ts +395 -0
- package/convex/aiTown/conversationMembership.ts +38 -0
- package/convex/aiTown/game.ts +371 -0
- package/convex/aiTown/ids.ts +32 -0
- package/convex/aiTown/inputHandler.ts +9 -0
- package/convex/aiTown/inputs.ts +25 -0
- package/convex/aiTown/insertInput.ts +20 -0
- package/convex/aiTown/location.ts +32 -0
- package/convex/aiTown/main.ts +154 -0
- package/convex/aiTown/movement.ts +189 -0
- package/convex/aiTown/player.ts +310 -0
- package/convex/aiTown/playerDescription.ts +35 -0
- package/convex/aiTown/schema.ts +79 -0
- package/convex/aiTown/world.ts +65 -0
- package/convex/aiTown/worldMap.ts +74 -0
- package/convex/chat.ts +79 -0
- package/convex/constants.ts +78 -0
- package/convex/convex.config.ts +6 -0
- package/convex/crons.ts +89 -0
- package/convex/engine/abstractGame.ts +199 -0
- package/convex/engine/historicalObject.ts +355 -0
- package/convex/engine/schema.ts +56 -0
- package/convex/http.ts +36 -0
- package/convex/init.ts +110 -0
- package/convex/messages.ts +53 -0
- package/convex/npcCarAgents.ts +415 -0
- package/convex/schema.ts +61 -0
- package/convex/streaming.ts +23 -0
- package/convex/testing.ts +202 -0
- package/convex/tsconfig.json +18 -0
- package/convex/util/FastIntegerCompression.ts +221 -0
- package/convex/util/assertNever.ts +4 -0
- package/convex/util/asyncMap.ts +20 -0
- package/convex/util/compression.ts +71 -0
- package/convex/util/geometry.ts +132 -0
- package/convex/util/isSimpleObject.ts +11 -0
- package/convex/util/llm.ts +724 -0
- package/convex/util/minheap.ts +38 -0
- package/convex/util/object.ts +22 -0
- package/convex/util/sleep.ts +3 -0
- package/convex/util/types.ts +33 -0
- package/convex/util/xxhash.ts +228 -0
- package/convex/world.ts +257 -0
- package/data/animations/campfire.json +45 -0
- package/data/animations/gentlesparkle.json +37 -0
- package/data/animations/gentlesplash.json +61 -0
- package/data/animations/gentlewaterfall.json +61 -0
- package/data/animations/windmill.json +78 -0
- package/data/characters.ts +121 -0
- package/data/convertMap.js +74 -0
- package/data/gentle.js +330 -0
- package/data/spritesheets/f1.ts +75 -0
- package/data/spritesheets/f2.ts +75 -0
- package/data/spritesheets/f3.ts +75 -0
- package/data/spritesheets/f4.ts +75 -0
- package/data/spritesheets/f5.ts +75 -0
- package/data/spritesheets/f6.ts +75 -0
- package/data/spritesheets/f7.ts +75 -0
- package/data/spritesheets/f8.ts +75 -0
- package/data/spritesheets/p1.ts +59 -0
- package/data/spritesheets/p2.ts +59 -0
- package/data/spritesheets/p3.ts +59 -0
- package/data/spritesheets/player.ts +59 -0
- package/data/spritesheets/types.ts +26 -0
- package/eslint.config.mjs +37 -0
- package/next.config.ts +7 -0
- package/package.json +85 -0
- package/postcss.config.mjs +7 -0
- package/public/file.svg +1 -0
- package/public/globe.svg +1 -0
- package/public/helius-icon.svg +84 -0
- package/public/helius-logo.svg +85 -0
- package/public/next.svg +1 -0
- package/public/plane.glb +0 -0
- package/public/vercel.svg +1 -0
- package/public/window.svg +1 -0
- package/scripts/clear-city.ts +74 -0
- package/scripts/seed-wallets.ts +185 -0
- package/scripts/setup-webhook.ts +73 -0
- package/src/app/api/auth/callback/route.ts +6 -0
- package/src/app/api/auth/link-wallet/route.ts +6 -0
- package/src/app/api/auth/phantom/route.ts +6 -0
- package/src/app/api/broadcast-position/route.ts +59 -0
- package/src/app/api/leaderboard/route.ts +85 -0
- package/src/app/api/network-stats/route.ts +86 -0
- package/src/app/api/parcel-reward/route.ts +181 -0
- package/src/app/api/queue-status/route.ts +30 -0
- package/src/app/api/snapshots/route.ts +37 -0
- package/src/app/api/transactions/enhanced/route.ts +57 -0
- package/src/app/api/treasury/route.ts +83 -0
- package/src/app/api/wallet/[address]/balances/route.ts +124 -0
- package/src/app/api/wallet/[address]/identity/route.ts +32 -0
- package/src/app/api/wallet/[address]/route.ts +216 -0
- package/src/app/api/wallet/[address]/traded-tokens/route.ts +41 -0
- package/src/app/api/wallets/route.ts +68 -0
- package/src/app/api/webhooks/helius/route.ts +76 -0
- package/src/app/auth/callback/page.tsx +29 -0
- package/src/app/favicon.ico +0 -0
- package/src/app/globals.css +39 -0
- package/src/app/layout.tsx +43 -0
- package/src/app/page.tsx +16 -0
- package/src/components/AITownNPCs.tsx +206 -0
- package/src/components/ActivityFeed.tsx +189 -0
- package/src/components/AuthPanel.tsx +163 -0
- package/src/components/BeachScene.tsx +280 -0
- package/src/components/Building.tsx +138 -0
- package/src/components/CesiumFlight.tsx +1768 -0
- package/src/components/CesiumGlobe.tsx +616 -0
- package/src/components/CitizenCard.tsx +442 -0
- package/src/components/CitizenCardModal.tsx +153 -0
- package/src/components/CityGrid.tsx +313 -0
- package/src/components/CityLandmarks.tsx +427 -0
- package/src/components/CityScene.tsx +1289 -0
- package/src/components/CitySlotsBadge.tsx +68 -0
- package/src/components/CockpitHUD.tsx +460 -0
- package/src/components/ConvexWrapper.tsx +19 -0
- package/src/components/DubaiDistrict.tsx +630 -0
- package/src/components/FlightMiniMap.tsx +133 -0
- package/src/components/GameChat.tsx +383 -0
- package/src/components/GameHUD.tsx +393 -0
- package/src/components/Ground.tsx +14 -0
- package/src/components/HowItWorksModal.tsx +251 -0
- package/src/components/IngestionBanner.tsx +123 -0
- package/src/components/InstancedBuildings.tsx +316 -0
- package/src/components/InstancedCars.tsx +504 -0
- package/src/components/InstancedCityPlanes.tsx +259 -0
- package/src/components/InstancedHouses.tsx +246 -0
- package/src/components/InstancedLampPosts.tsx +201 -0
- package/src/components/InstancedResidentCars.tsx +357 -0
- package/src/components/InstancedRoadDashes.tsx +42 -0
- package/src/components/InstancedSkyscrapers.tsx +434 -0
- package/src/components/InstancedTrees.tsx +67 -0
- package/src/components/LeaderboardPanel.tsx +136 -0
- package/src/components/MultiplayerPlanes.tsx +128 -0
- package/src/components/NetworkStats.tsx +83 -0
- package/src/components/NewBuildingSpotlight.tsx +93 -0
- package/src/components/ParcelChallengeBanner.tsx +242 -0
- package/src/components/ParcelReward.tsx +191 -0
- package/src/components/Park.tsx +42 -0
- package/src/components/PhantomWrapper.tsx +22 -0
- package/src/components/PixelStreamViewer.tsx +335 -0
- package/src/components/PlaneMode.tsx +190 -0
- package/src/components/PlayerCar.tsx +211 -0
- package/src/components/PlayerPlane.tsx +255 -0
- package/src/components/ProjectileRenderer.tsx +249 -0
- package/src/components/QueueStatusBanner.tsx +86 -0
- package/src/components/RealPlayerTags.tsx +82 -0
- package/src/components/SceneLighting.tsx +382 -0
- package/src/components/SelectionBeam.tsx +59 -0
- package/src/components/SwapPanel.tsx +104 -0
- package/src/components/SwapParticles.tsx +237 -0
- package/src/components/TreasureGate.tsx +505 -0
- package/src/components/WalletPanel.tsx +421 -0
- package/src/components/WalletSearch.tsx +244 -0
- package/src/components/WelcomeOverlay.tsx +135 -0
- package/src/components/WindowTooltip.tsx +498 -0
- package/src/context/AuthContext.tsx +230 -0
- package/src/lib/bot-detection.ts +125 -0
- package/src/lib/building-math.ts +136 -0
- package/src/lib/building-shader.ts +253 -0
- package/src/lib/car-paths.ts +244 -0
- package/src/lib/car-system.ts +182 -0
- package/src/lib/city-constants.ts +29 -0
- package/src/lib/city-slots.ts +35 -0
- package/src/lib/city-zoning.ts +64 -0
- package/src/lib/collision-map.ts +147 -0
- package/src/lib/day-night.ts +252 -0
- package/src/lib/export-card.ts +28 -0
- package/src/lib/helius-webhook.ts +90 -0
- package/src/lib/helius.ts +74 -0
- package/src/lib/house-shader.ts +119 -0
- package/src/lib/mock-data.ts +56 -0
- package/src/lib/multiplayer-manager.ts +329 -0
- package/src/lib/plane-physics.ts +66 -0
- package/src/lib/player-car.ts +147 -0
- package/src/lib/player-plane.ts +200 -0
- package/src/lib/projectile-system.ts +272 -0
- package/src/lib/skyscraper-types.ts +52 -0
- package/src/lib/sound-engine.ts +464 -0
- package/src/lib/supabase-admin.ts +9 -0
- package/src/lib/supabase.ts +8 -0
- package/src/lib/swap-events.ts +70 -0
- package/src/middleware.ts +37 -0
- package/src/types/phantom.d.ts +16 -0
- package/src/types/wallet.ts +20 -0
- package/tsconfig.json +34 -0
package/README.md
ADDED
|
@@ -0,0 +1,518 @@
|
|
|
1
|
+
# SOLANApolis
|
|
2
|
+
|
|
3
|
+
**powered by Heliopolis and Helius on Solana**
|
|
4
|
+
|
|
5
|
+
A real-time 3D city built from Solana wallet activity — claim your building, earn your plane, drive your car, explore the globe, and fly anywhere on Earth.
|
|
6
|
+
|
|
7
|
+
## What is this?
|
|
8
|
+
|
|
9
|
+
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.
|
|
10
|
+
|
|
11
|
+
## City Slots
|
|
12
|
+
|
|
13
|
+
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:
|
|
14
|
+
|
|
15
|
+
| Slot Type | Capacity | Perk |
|
|
16
|
+
|-----------|----------|------|
|
|
17
|
+
| ✈ **Planes** | 100 | First 100 wallets each get a personal plane that circles above their building |
|
|
18
|
+
| 🚗 **Cars** | 250 | First 250 wallets each get a resident car that drives the city streets |
|
|
19
|
+
| 🏢 **Buildings** | 1,000 | All wallets get a unique building sized by their on-chain activity |
|
|
20
|
+
|
|
21
|
+
- **Planes** orbit above their owner's building at unique altitudes, speeds, and colors
|
|
22
|
+
- **Cars** continuously cruise the streets near their owner's block, each with a distinct color from a 20-color palette
|
|
23
|
+
- **Clicking** any plane or car focuses the camera on the owner's building and shows their wallet info
|
|
24
|
+
- The **UI badge** in the top-left corner shows real-time slot fill progress for wallets, planes, and cars
|
|
25
|
+
|
|
26
|
+
## Features
|
|
27
|
+
|
|
28
|
+
### 3D Solana City
|
|
29
|
+
- Every Solana wallet address with swap history generates a unique building
|
|
30
|
+
- Building height, width, and detail scale with trading volume and transaction count
|
|
31
|
+
- Buildings are deterministically colored from wallet address — no two look alike
|
|
32
|
+
- Five **skyscraper types** for downtown buildings: Setback (Art Deco), Twin Peaks, Cantilever, Spire, and standard Box — each with multi-tier geometry and procedural windows
|
|
33
|
+
- **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
|
|
34
|
+
- Day/night cycle with dynamic lighting, fog, atmospheric haze, and stars
|
|
35
|
+
- Instanced mesh rendering for thousands of buildings at 60fps
|
|
36
|
+
- Parks, trees, lamp posts, road dashes, and sidewalks — all instanced
|
|
37
|
+
- **Beach scene** with animated ocean, waves, seagulls, and boats along the southern shoreline
|
|
38
|
+
|
|
39
|
+
### 🌍 Globe View (NEW)
|
|
40
|
+
- **Interactive 3D Earth** powered by CesiumJS with real satellite imagery and terrain
|
|
41
|
+
- **OSM Buildings 3D Tiles** (Cesium Ion asset #96188) — millions of real-world buildings with height-based color coding:
|
|
42
|
+
- 🔴 Red: 200m+ (skyscrapers)
|
|
43
|
+
- 🟠 Orange: 100–200m (major towers)
|
|
44
|
+
- 🟡 Yellow: 50–100m (tall buildings)
|
|
45
|
+
- 🟢 Teal: 20–50m (mid-rise)
|
|
46
|
+
- 🔵 Blue: under 20m (low-rise)
|
|
47
|
+
- **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)
|
|
48
|
+
- **📍 Locations** — instant fly-to for 9 world cities: New York, London, Tokyo, Dubai, Paris, San Francisco, Sydney, Giza, Solana Beach
|
|
49
|
+
- **🌏 Earth View** — zoom out to see the full planet from space
|
|
50
|
+
- **Double-click** any location to transition directly to the Cesium flight simulator there
|
|
51
|
+
- **Shift+click** — Google Street View panel via Cesium Ion's experimental `/experimental/panoramas/google` endpoint
|
|
52
|
+
- **Live HUD** showing real-time LAT / LON / ALT as you navigate
|
|
53
|
+
- **B** toggle buildings on/off, **L** toggle locations panel, **Esc** return to city
|
|
54
|
+
|
|
55
|
+
### Cesium Flight Simulator
|
|
56
|
+
- Full-screen flight simulator powered by Cesium.js with real satellite imagery and 3D terrain
|
|
57
|
+
- Spawns at London (51.5074°N, 0.1278°W) at 500m altitude, or at coordinates selected from the Globe view
|
|
58
|
+
- Aircraft physics with realistic banking:
|
|
59
|
+
- Throttle controls (W/S) with realistic acceleration
|
|
60
|
+
- Roll-induced yaw for realistic banking turns (A/D keys)
|
|
61
|
+
- Climb rate tied to pitch (Space/E)
|
|
62
|
+
- Gravity and stall simulation
|
|
63
|
+
- Crash detection when altitude < 5m
|
|
64
|
+
- Follow camera positioned correctly **behind** the aircraft with banking tilt and dynamic FOV
|
|
65
|
+
- Camera toggle (C) between follow and orbit views
|
|
66
|
+
- HUD showing speed (km/h), altitude (m), and heading (°)
|
|
67
|
+
- Crash screen with instant restart
|
|
68
|
+
- Error handling with retry/exit UI when initialization fails
|
|
69
|
+
|
|
70
|
+
### Resident Planes (100 slots)
|
|
71
|
+
- First 100 wallets each get a 3D plane (fuselage, wings, tail fin) rendered via instanced meshes
|
|
72
|
+
- Each plane circles above its owner's building with unique orbit radius (8–26 units), altitude, angular speed, and warm color tint
|
|
73
|
+
- Planes bank gently into turns and oscillate in altitude
|
|
74
|
+
- Hover to see wallet info tooltip; click to navigate to the building
|
|
75
|
+
|
|
76
|
+
### Resident Cars (250 slots)
|
|
77
|
+
- First 250 wallets each get a detailed 3D car (body, glass cabin, 4 wheels, floating diamond marker)
|
|
78
|
+
- Cars continuously drive city streets following paths generated from their building's block
|
|
79
|
+
- Each car has a unique color from a curated 20-color palette
|
|
80
|
+
- Cars automatically regenerate new routes when they reach the end of a path
|
|
81
|
+
- Hover to see wallet info; click to zoom to the owner's building
|
|
82
|
+
|
|
83
|
+
### Swap Cars (AI Traffic)
|
|
84
|
+
- Live swap events from the database spawn AI-driven cars that drive through the city
|
|
85
|
+
- Up to 60 concurrent swap cars with fade-in/drive/fade-out lifecycle
|
|
86
|
+
- Each car carries swap metadata (token in/out, SOL amount)
|
|
87
|
+
- Click any swap car to open the swap info panel and follow it with the camera
|
|
88
|
+
- **Swap particles**: GPU-accelerated particle bursts fire at buildings when their wallet's swap car spawns — frame-rate independent physics
|
|
89
|
+
|
|
90
|
+
### New Building Spotlight
|
|
91
|
+
- When a new wallet connects, a gold pulsing spotlight beam appears on their building
|
|
92
|
+
- Animated ring + point light effect that fades out after 8 seconds
|
|
93
|
+
- Triggered by new Phantom wallet connections in real time
|
|
94
|
+
|
|
95
|
+
### Phantom Connect
|
|
96
|
+
- Sign in with your Solana wallet via Phantom Connect SDK
|
|
97
|
+
- Supports Google, Apple, and injected wallet providers
|
|
98
|
+
- OAuth redirect flow works on both `heliopolis-main.vercel.app` and `heliopolis.ngrok.app`
|
|
99
|
+
- Your wallet address auto-generates your building the moment you connect
|
|
100
|
+
- If you're among the first 100/250, your plane or car appears automatically
|
|
101
|
+
|
|
102
|
+
### Three.js Plane Mode
|
|
103
|
+
- 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)
|
|
104
|
+
- YXZ Euler rotation order for proper heading/pitch/roll (standard aircraft convention)
|
|
105
|
+
- WASD + Q/E controls with pointer-lock mouse look
|
|
106
|
+
- Chase camera follows behind and above the plane
|
|
107
|
+
|
|
108
|
+
### Mapbox Mini-Map
|
|
109
|
+
- Live 180×180px Mapbox GL mini-map in the flight simulator overlay
|
|
110
|
+
- Dark map style with an orange aircraft marker that rotates to match your heading
|
|
111
|
+
- Smooth `easeTo()` camera following at ~10fps updates
|
|
112
|
+
|
|
113
|
+
### Multiplayer Flying
|
|
114
|
+
- Two separate Supabase Realtime broadcast channels:
|
|
115
|
+
- `heliopolis-planes` — Three.js city fly-through mode (XYZ coordinates)
|
|
116
|
+
- `heliopolis-cesium-planes` — Cesium flight simulator mode (lat/lon/alt/heading)
|
|
117
|
+
- See other connected wallets flying as 3D plane meshes in real time
|
|
118
|
+
- Remote planes use smooth lerp/slerp interpolation for fluid motion
|
|
119
|
+
- Plane color is deterministically derived from wallet address
|
|
120
|
+
|
|
121
|
+
### Player Car Mode
|
|
122
|
+
- Drive a car through the city streets in third-person
|
|
123
|
+
- Bicycle-model physics with acceleration, braking, and steering
|
|
124
|
+
- AABB collision detection against all buildings and houses
|
|
125
|
+
- Chase camera follows behind and above the car
|
|
126
|
+
- WASD + Space controls
|
|
127
|
+
- **Combat-ready** — fire projectiles with F or left-click while driving
|
|
128
|
+
|
|
129
|
+
### Combat System
|
|
130
|
+
- **Available in both car and plane modes** — enter Drive or Fly mode to start shooting
|
|
131
|
+
- Press **F** or **left-click** to fire projectiles
|
|
132
|
+
- Projectiles travel at 120 units/sec with slight gravity drop
|
|
133
|
+
- Fire rate: ~6.6 shots/sec (0.15s cooldown), up to 50 active projectiles
|
|
134
|
+
- **Hit detection**: sphere-based collision against all 100 resident planes and 250 resident cars
|
|
135
|
+
- **Scoring**: 50 points per plane hit, 25 points per car hit
|
|
136
|
+
- **Visual effects**:
|
|
137
|
+
- Glowing orange bullet heads (sphere geometry)
|
|
138
|
+
- Velocity-aligned stretch trails behind each projectile
|
|
139
|
+
- Expanding icosahedron explosions at hit locations (1 second lifetime)
|
|
140
|
+
- Muzzle flash point light when firing
|
|
141
|
+
- On-screen hit marker (✕) flash on successful hits
|
|
142
|
+
|
|
143
|
+
### Game HUD & Minimap
|
|
144
|
+
- **Real-time tactical minimap** (200×200px canvas, top-right corner)
|
|
145
|
+
- All buildings shown as gray dots
|
|
146
|
+
- Resident planes as amber dots
|
|
147
|
+
- Resident cars as indigo dots
|
|
148
|
+
- Active projectiles as red dots
|
|
149
|
+
- Hit locations as expanding red rings (2 second fadeout)
|
|
150
|
+
- Player position as an orange triangle with heading indicator
|
|
151
|
+
- FOV cone showing player's field of view
|
|
152
|
+
- Pulsing ring around the player position
|
|
153
|
+
- Grid overlay for spatial reference
|
|
154
|
+
- Legend showing dot color meanings
|
|
155
|
+
- **Score bar** (top-center) showing:
|
|
156
|
+
- Current mode (✈ AIR / 🚗 GROUND)
|
|
157
|
+
- Live score counter (smooth animation)
|
|
158
|
+
- Hit count
|
|
159
|
+
- Active projectile count
|
|
160
|
+
- Fire key hint
|
|
161
|
+
- **Crosshair** (center screen) — bracket-style with orange center dot
|
|
162
|
+
- All HUD elements auto-show when entering car/plane mode, auto-hide when exiting
|
|
163
|
+
|
|
164
|
+
### Day/Night Cycle
|
|
165
|
+
- 8-keyframe system covering dawn, sunrise, day, golden hour, sunset, dusk, night, and late night
|
|
166
|
+
- Smooth interpolation of sky color, fog, ambient/directional/hemisphere/accent lights, sun position, and star opacity
|
|
167
|
+
- Procedural window illumination that responds to time — windows turn on at sunset, glow through the night, and switch off at dawn
|
|
168
|
+
- Lamp posts illuminate at night with emissive glow decals
|
|
169
|
+
|
|
170
|
+
### Building Interaction
|
|
171
|
+
- Click any building to open the wallet info panel (transaction count, volume, age, fees, token list)
|
|
172
|
+
- Hover windows on selected buildings to see per-window token tooltips
|
|
173
|
+
- Selection beam highlight with animated glow
|
|
174
|
+
- Window hover detection uses the same UV math as the shader for pixel-perfect accuracy
|
|
175
|
+
|
|
176
|
+
### Network Stats HUD
|
|
177
|
+
- Live Solana network stats: TPS (with color-coded delta), slot number, and epoch progress bar
|
|
178
|
+
- Polls every 10 seconds
|
|
179
|
+
- Gradient progress bar from indigo → orange
|
|
180
|
+
|
|
181
|
+
### Twitter Auth
|
|
182
|
+
- Sign in with Twitter/X via Supabase OAuth
|
|
183
|
+
- Auth state persists across sessions
|
|
184
|
+
- Citizen ID Card modal for authenticated wallets
|
|
185
|
+
|
|
186
|
+
## Tech Stack
|
|
187
|
+
|
|
188
|
+
| Layer | Technology |
|
|
189
|
+
|-------|-----------|
|
|
190
|
+
| Framework | Next.js 16 (App Router, Turbopack) |
|
|
191
|
+
| 3D City | React Three Fiber + drei + Three.js |
|
|
192
|
+
| Shaders | Custom GLSL (PBR building shader, house shader, headlight decals, GPU particles) |
|
|
193
|
+
| Globe & Flight | Cesium.js v1.139 + Cesium Ion (3D terrain + OSM Buildings) |
|
|
194
|
+
| Street View | Cesium Ion Experimental API (`/experimental/panoramas/google`) |
|
|
195
|
+
| Mini-Map | Mapbox GL v3 |
|
|
196
|
+
| Wallet Auth | @phantom/react-sdk |
|
|
197
|
+
| OAuth | Supabase Auth (Twitter) |
|
|
198
|
+
| Multiplayer | Supabase Realtime Broadcast |
|
|
199
|
+
| Blockchain Data | Helius API (Solana) |
|
|
200
|
+
| Token Prices | BirdEye API |
|
|
201
|
+
| Styling | Tailwind CSS |
|
|
202
|
+
| Deployment | Vercel |
|
|
203
|
+
| UE5 Backend | Unreal Engine 5.7 + CesiumForUnreal + SolanaSDK + Pixel Streaming |
|
|
204
|
+
| Solana Runtime | .NET 9 + Solnet 5.x (SOLANApolisRuntime) |
|
|
205
|
+
|
|
206
|
+
## Controls
|
|
207
|
+
|
|
208
|
+
### 🌍 Globe View
|
|
209
|
+
| Input | Action |
|
|
210
|
+
|-------|--------|
|
|
211
|
+
| Left-click drag | Rotate globe |
|
|
212
|
+
| Right-click drag | Pan |
|
|
213
|
+
| Scroll | Zoom |
|
|
214
|
+
| Middle-click | Tilt |
|
|
215
|
+
| Double-click | Fly to location (opens Cesium flight) |
|
|
216
|
+
| Shift+click | Open Street View panel |
|
|
217
|
+
| B | Toggle OSM buildings |
|
|
218
|
+
| L | Toggle locations panel |
|
|
219
|
+
| 📍 Locations | Quick-jump to 9 world cities |
|
|
220
|
+
| 🌏 Earth | Zoom out to full Earth |
|
|
221
|
+
| Esc | Return to city |
|
|
222
|
+
|
|
223
|
+
### Cesium Flight Simulator
|
|
224
|
+
| Key | Action |
|
|
225
|
+
|-----|--------|
|
|
226
|
+
| W | Increase throttle |
|
|
227
|
+
| S | Decrease throttle |
|
|
228
|
+
| A | Bank left |
|
|
229
|
+
| D | Bank right |
|
|
230
|
+
| Space | Climb |
|
|
231
|
+
| Q | Roll left |
|
|
232
|
+
| E | Roll right / Descend |
|
|
233
|
+
| C | Toggle camera mode |
|
|
234
|
+
| Esc | Exit flight simulator |
|
|
235
|
+
|
|
236
|
+
### Three.js Plane Mode
|
|
237
|
+
| Key | Action |
|
|
238
|
+
|-----|--------|
|
|
239
|
+
| W / ↑ | Throttle up |
|
|
240
|
+
| S / ↓ | Throttle down |
|
|
241
|
+
| A / ← | Bank left |
|
|
242
|
+
| D / → | Bank right |
|
|
243
|
+
| Q / Space | Climb |
|
|
244
|
+
| E | Descend |
|
|
245
|
+
| F / Left-click | Fire projectile |
|
|
246
|
+
| Esc | Exit plane mode |
|
|
247
|
+
|
|
248
|
+
### Car Mode
|
|
249
|
+
| Key | Action |
|
|
250
|
+
|-----|--------|
|
|
251
|
+
| W / ↑ | Accelerate |
|
|
252
|
+
| S / ↓ | Brake / Reverse |
|
|
253
|
+
| A / ← | Steer left |
|
|
254
|
+
| D / → | Steer right |
|
|
255
|
+
| Space | Brake |
|
|
256
|
+
| F / Left-click | Fire projectile |
|
|
257
|
+
| Esc | Exit car mode |
|
|
258
|
+
|
|
259
|
+
### City View
|
|
260
|
+
| Input | Action |
|
|
261
|
+
|-------|--------|
|
|
262
|
+
| Left-click + drag | Pan / Orbit |
|
|
263
|
+
| Right-click + drag | Rotate / Pan |
|
|
264
|
+
| Scroll | Zoom |
|
|
265
|
+
| Click building | Select wallet |
|
|
266
|
+
| Click car | Follow car |
|
|
267
|
+
|
|
268
|
+
## Setup
|
|
269
|
+
|
|
270
|
+
### Prerequisites
|
|
271
|
+
- Node.js 18+
|
|
272
|
+
- A Vercel account (for deployment)
|
|
273
|
+
- .NET 9 (for SOLANApolisRuntime, optional)
|
|
274
|
+
- Unreal Engine 5.7 (for UE5 backend, optional)
|
|
275
|
+
|
|
276
|
+
### Environment Variables
|
|
277
|
+
|
|
278
|
+
Create `.env.local`:
|
|
279
|
+
|
|
280
|
+
```env
|
|
281
|
+
# Helius (Solana RPC)
|
|
282
|
+
HELIUS_API_KEY=your_helius_api_key
|
|
283
|
+
HELIUS_RPC_URL=https://mainnet.helius-rpc.com/?api-key=your_key
|
|
284
|
+
HELIUS_WSS_URL=wss://mainnet.helius-rpc.com/?api-key=your_key
|
|
285
|
+
HELIUS_WEBHOOK_SECRET=your_webhook_secret
|
|
286
|
+
HELIUS_WEBHOOK_ID=your_webhook_id
|
|
287
|
+
|
|
288
|
+
# Supabase
|
|
289
|
+
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
|
|
290
|
+
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key
|
|
291
|
+
SUPABASE_SERVICE_ROLE_KEY=your_service_role_key
|
|
292
|
+
|
|
293
|
+
# Phantom Connect
|
|
294
|
+
PHANTOM_APP_ID=your_phantom_app_id
|
|
295
|
+
|
|
296
|
+
# BirdEye
|
|
297
|
+
BIRDEYE_API_KEY=your_birdeye_api_key
|
|
298
|
+
BIRDEYE_WSS_URL=wss://public-api.birdeye.so/socket/solana?x-api-key=your_key
|
|
299
|
+
|
|
300
|
+
# Cesium Ion (required for Globe + Flight)
|
|
301
|
+
NEXT_PUBLIC_CESIUM_ION_TOKEN=your_cesium_ion_token
|
|
302
|
+
|
|
303
|
+
# Mapbox
|
|
304
|
+
NEXT_PUBLIC_MAPBOX_TOKEN=your_mapbox_token
|
|
305
|
+
|
|
306
|
+
# Pixel Streaming (optional, for UE5 backend)
|
|
307
|
+
NEXT_PUBLIC_PIXEL_STREAMING_URL=ws://localhost:8888
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### Install & Run
|
|
311
|
+
|
|
312
|
+
```bash
|
|
313
|
+
npm install
|
|
314
|
+
npm run dev
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
Open [http://localhost:3000](http://localhost:3000).
|
|
318
|
+
|
|
319
|
+
### Build
|
|
320
|
+
|
|
321
|
+
```bash
|
|
322
|
+
npm run build
|
|
323
|
+
npm start
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
### UE5 Backend Setup (Optional)
|
|
327
|
+
|
|
328
|
+
The UE5 backend provides high-fidelity rendering streamed via Pixel Streaming:
|
|
329
|
+
|
|
330
|
+
```bash
|
|
331
|
+
# 1. Link plugins into the UE5 project
|
|
332
|
+
cd SOLANApolis-UE5
|
|
333
|
+
./setup-plugins.sh
|
|
334
|
+
|
|
335
|
+
# 2. Build the Solana runtime (.NET 9)
|
|
336
|
+
./build-solanakit.sh
|
|
337
|
+
|
|
338
|
+
# 3. Open in Unreal Engine 5.7.x
|
|
339
|
+
# SOLANApolis-UE5/SOLANApolis.uproject
|
|
340
|
+
|
|
341
|
+
# 4. Configure Cesium Ion token in Project Settings → Plugins → Cesium
|
|
342
|
+
|
|
343
|
+
# 5. Launch with Pixel Streaming
|
|
344
|
+
SOLANApolis -PixelStreamingIP=0.0.0.0 -PixelStreamingPort=8888
|
|
345
|
+
|
|
346
|
+
# 6. Set NEXT_PUBLIC_PIXEL_STREAMING_URL=ws://your-server:8888 in .env.local
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
## Architecture
|
|
350
|
+
|
|
351
|
+
```
|
|
352
|
+
src/
|
|
353
|
+
├── app/
|
|
354
|
+
│ ├── layout.tsx # PhantomWrapper + AuthProvider
|
|
355
|
+
│ ├── page.tsx # Main entry — dynamic import of CityScene
|
|
356
|
+
│ ├── globals.css # Tailwind + activity animation keyframes
|
|
357
|
+
│ ├── auth/callback/page.tsx # Phantom OAuth redirect handler
|
|
358
|
+
│ └── api/
|
|
359
|
+
│ ├── wallets/route.ts # GET all placed wallets with identity data
|
|
360
|
+
│ ├── wallet/[address]/ # Wallet lookup, balances, identity, tokens
|
|
361
|
+
│ ├── network-stats/route.ts # Solana TPS, slot, epoch progress
|
|
362
|
+
│ ├── webhooks/helius/ # Helius webhook receiver
|
|
363
|
+
│ └── auth/ # Phantom auth, callback, link-wallet
|
|
364
|
+
├── components/
|
|
365
|
+
│ ├── CityScene.tsx # Root 3D scene — orchestrates all components
|
|
366
|
+
│ ├── CityGrid.tsx # City layout: roads, sidewalks, blocks, parks
|
|
367
|
+
│ ├── CesiumGlobe.tsx # 🌍 Interactive 3D Earth + OSM Buildings + metadata
|
|
368
|
+
│ ├── CesiumFlight.tsx # ✈ Full Cesium flight simulator
|
|
369
|
+
│ ├── PixelStreamViewer.tsx # UE5 Pixel Streaming WebRTC viewer
|
|
370
|
+
│ ├── InstancedBuildings.tsx # Plain box buildings (instanced mesh + PBR shader)
|
|
371
|
+
│ ├── InstancedSkyscrapers.tsx # Multi-tier skyscrapers (setback, twin, cantilever, spire)
|
|
372
|
+
│ ├── InstancedCityPlanes.tsx # 100 resident planes circling owner buildings
|
|
373
|
+
│ ├── InstancedResidentCars.tsx # 250 resident cars driving city streets
|
|
374
|
+
│ ├── InstancedCars.tsx # AI swap-event cars (up to 60)
|
|
375
|
+
│ ├── InstancedHouses.tsx # Low-rise placeholder houses
|
|
376
|
+
│ ├── InstancedTrees.tsx # Park + sidewalk trees
|
|
377
|
+
│ ├── InstancedLampPosts.tsx # Street lamps with night glow
|
|
378
|
+
│ ├── InstancedRoadDashes.tsx # Road center-line dashes
|
|
379
|
+
│ ├── FlightMiniMap.tsx # Mapbox mini-map overlay
|
|
380
|
+
│ ├── PlaneMode.tsx # Three.js in-city plane mode
|
|
381
|
+
│ ├── PlayerPlane.tsx # Player-controlled plane (detailed 3D mesh)
|
|
382
|
+
│ ├── PlayerCar.tsx # Player-controlled car with collision
|
|
383
|
+
│ ├── MultiplayerPlanes.tsx # Supabase Realtime multiplayer
|
|
384
|
+
│ ├── BeachScene.tsx # Animated ocean, waves, seagulls, boats
|
|
385
|
+
│ ├── SceneLighting.tsx # 5-light rig + stars + fog
|
|
386
|
+
│ ├── SelectionBeam.tsx # Building selection glow beam
|
|
387
|
+
│ ├── SwapParticles.tsx # GPU particle bursts on swap events
|
|
388
|
+
│ ├── NewBuildingSpotlight.tsx # Gold spotlight on new buildings
|
|
389
|
+
│ ├── ProjectileRenderer.tsx # Instanced projectile bullets + explosions
|
|
390
|
+
│ ├── GameHUD.tsx # Real-time minimap + score bar + crosshair
|
|
391
|
+
│ ├── CitySlotsBadge.tsx # UI: wallet/plane/car slot counters
|
|
392
|
+
│ ├── WalletPanel.tsx # Wallet info side panel
|
|
393
|
+
│ ├── SwapPanel.tsx # Swap car info panel
|
|
394
|
+
│ ├── WindowTooltip.tsx # Building/token hover tooltip
|
|
395
|
+
│ ├── WalletSearch.tsx # Top search bar with autocomplete
|
|
396
|
+
│ ├── ActivityFeed.tsx # Left-side activity stream
|
|
397
|
+
│ ├── NetworkStats.tsx # Bottom-right TPS/slot/epoch HUD
|
|
398
|
+
│ ├── AuthPanel.tsx # Wallet + Twitter auth UI
|
|
399
|
+
│ ├── HowItWorksModal.tsx # Info modal
|
|
400
|
+
│ ├── CitizenCardModal.tsx # Citizen ID card (lazy loaded)
|
|
401
|
+
│ ├── Ground.tsx # Ground plane mesh
|
|
402
|
+
│ ├── Park.tsx # Park block with grass
|
|
403
|
+
│ ├── LeaderboardPanel.tsx # Combat leaderboard
|
|
404
|
+
│ ├── GameChat.tsx # In-game chat
|
|
405
|
+
│ └── PhantomWrapper.tsx # Client-side PhantomProvider wrapper
|
|
406
|
+
├── context/
|
|
407
|
+
│ └── AuthContext.tsx # Auth state (Supabase + Phantom)
|
|
408
|
+
├── lib/
|
|
409
|
+
│ ├── city-slots.ts # Slot constants (1000 wallets, 100 planes, 250 cars)
|
|
410
|
+
│ ├── city-constants.ts # Grid layout: block size, road positions, park blocks
|
|
411
|
+
│ ├── city-zoning.ts # Zone classification: downtown, midrise, lowrise, park
|
|
412
|
+
│ ├── building-math.ts # Building dimensions, colors, window attributes
|
|
413
|
+
│ ├── building-shader.ts # Custom GLSL PBR shader with procedural windows
|
|
414
|
+
│ ├── house-shader.ts # House PBR shader with day/night tinting
|
|
415
|
+
│ ├── skyscraper-types.ts # Skyscraper tier definitions (setback, twin, etc.)
|
|
416
|
+
│ ├── player-plane.ts # Plane physics engine (speed, heading, pitch, roll)
|
|
417
|
+
│ ├── player-car.ts # Car physics engine (bicycle model + collision)
|
|
418
|
+
│ ├── collision-map.ts # AABB spatial hash collision detection
|
|
419
|
+
│ ├── car-system.ts # AI car lifecycle manager (spawn, update, despawn)
|
|
420
|
+
│ ├── car-paths.ts # City path generation for AI cars
|
|
421
|
+
│ ├── day-night.ts # 8-keyframe day/night interpolation system
|
|
422
|
+
│ ├── swap-events.ts # Swap event polling from Supabase
|
|
423
|
+
│ ├── projectile-system.ts # Projectile physics, lifecycle, and hit detection
|
|
424
|
+
│ ├── multiplayer-manager.ts # Supabase Realtime multiplayer sync
|
|
425
|
+
│ ├── sound-engine.ts # Audio engine: plane engine, clicks
|
|
426
|
+
│ ├── supabase.ts # Supabase client (browser)
|
|
427
|
+
│ └── supabase-admin.ts # Supabase admin client (server)
|
|
428
|
+
├── types/
|
|
429
|
+
│ └── wallet.ts # WalletBuilding + PlacedWallet interfaces
|
|
430
|
+
|
|
431
|
+
SOLANApolis-UE5/ # Unreal Engine 5.7 project (optional)
|
|
432
|
+
├── SOLANApolis.uproject # Project file (CesiumForUnreal + SolanaSDK + PixelStreaming)
|
|
433
|
+
├── setup-plugins.sh # Symlink plugins into the UE5 project
|
|
434
|
+
├── build-solanakit.sh # Build .NET 9 Solana runtime
|
|
435
|
+
├── Source/
|
|
436
|
+
│ ├── SOLANApolis.Target.cs # Game target rules
|
|
437
|
+
│ ├── SOLANApolisEditor.Target.cs # Editor target rules
|
|
438
|
+
│ └── SOLANApolis/
|
|
439
|
+
│ ├── SOLANApolis.Build.cs # Module build rules
|
|
440
|
+
│ ├── SOLANApolisFlightPawn.h/.cpp # Flight pawn with Cesium globe anchor, Solana wallet, combat
|
|
441
|
+
│ └── SOLANApolisChainBridge.h/.cpp # Solana → UE5 bridge (balance, skins, kills)
|
|
442
|
+
├── SolanaKit/
|
|
443
|
+
│ └── SOLANApolisRuntime.csproj # .NET 9 Solana runtime (Solnet 5.x)
|
|
444
|
+
└── Plugins/ (symlinked)
|
|
445
|
+
├── CesiumForUnreal → cesium-unreal-main
|
|
446
|
+
└── SolanaSDK → Solana-Unreal-SDK-main
|
|
447
|
+
|
|
448
|
+
Solana-Unreal-SDK-main/ # Solana SDK for UE5
|
|
449
|
+
├── SolanaSDK.uplugin # Plugin descriptor (UnrealSOLNET + LinkStream)
|
|
450
|
+
└── ...
|
|
451
|
+
|
|
452
|
+
public/
|
|
453
|
+
├── plane.glb # Aircraft 3D model
|
|
454
|
+
├── helius-icon.svg # Helius logo icon
|
|
455
|
+
└── helius-logo.svg # Helius logo full
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
## Deployment
|
|
459
|
+
|
|
460
|
+
The web app is deployed to Vercel:
|
|
461
|
+
|
|
462
|
+
```bash
|
|
463
|
+
vercel --prod
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
**Required Vercel environment variables** — add all variables from `.env.local` in the Vercel dashboard under Project Settings → Environment Variables.
|
|
467
|
+
|
|
468
|
+
### UE5 Pixel Streaming Deployment
|
|
469
|
+
|
|
470
|
+
For production UE5 streaming, deploy the built UE5 project to a GPU instance (AWS g4dn, Azure NV, etc.) with:
|
|
471
|
+
|
|
472
|
+
```bash
|
|
473
|
+
SOLANApolis -RenderOffscreen -PixelStreamingIP=0.0.0.0 -PixelStreamingPort=8888 -ForceRes -ResX=1920 -ResY=1080
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
Then set `NEXT_PUBLIC_PIXEL_STREAMING_URL` to the WebSocket URL of the signaling server.
|
|
477
|
+
|
|
478
|
+
## Phantom Connect Configuration
|
|
479
|
+
|
|
480
|
+
In the [Phantom developer portal](https://developer.phantom.com), configure your app with these redirect URLs:
|
|
481
|
+
- `https://heliopolis-main.vercel.app/auth/callback`
|
|
482
|
+
- `https://heliopolis.ngrok.app/auth/callback`
|
|
483
|
+
- `http://localhost:3000/auth/callback` (for local dev)
|
|
484
|
+
|
|
485
|
+
## Supabase Configuration
|
|
486
|
+
|
|
487
|
+
Enable the following in your Supabase project:
|
|
488
|
+
- **Auth → Providers**: Enable Twitter/X OAuth with your API keys
|
|
489
|
+
- **Realtime**: Enable broadcast on the `public` schema
|
|
490
|
+
- **Database**: The app reads wallet addresses from the `wallets` table
|
|
491
|
+
- **RPC function**: `get_random_swaps(n)` returns random swap events for car traffic
|
|
492
|
+
- **RPC function**: `repair_unplaced_wallets()` self-heals unplaced complete wallets
|
|
493
|
+
|
|
494
|
+
## Performance
|
|
495
|
+
|
|
496
|
+
SOLANApolis is engineered for 60fps even with thousands of objects:
|
|
497
|
+
|
|
498
|
+
- **Instanced rendering** for all repeated geometry (buildings, skyscrapers, trees, lamp posts, cars, planes, road dashes)
|
|
499
|
+
- **Custom GLSL shaders** injected into Three.js standard PBR — no `onBeforeCompile` (avoids program cache invalidation)
|
|
500
|
+
- **GPU particle system** for swap burst effects with custom vertex/fragment shaders
|
|
501
|
+
- **Frame-rate independent physics** — all physics simulations use actual frame delta, never hardcoded timesteps
|
|
502
|
+
- **Ref-based state** for high-frequency updates (time, car positions, camera) to avoid React re-renders
|
|
503
|
+
- **Lazy loading** for heavy components (CesiumFlight, CesiumGlobe, CitizenCardModal)
|
|
504
|
+
- **Spatial hash** collision detection for O(1) car-building collision queries
|
|
505
|
+
- **Cesium Ion streaming** — terrain and building tiles loaded on-demand, not preloaded
|
|
506
|
+
- **Pixel Streaming** (optional) — stream UE5 rendering over WebRTC for high-fidelity clients
|
|
507
|
+
|
|
508
|
+
## Credits
|
|
509
|
+
|
|
510
|
+
- Flight simulator physics adapted from [cesium-flight-simulator](https://github.com/nicktarnold/cesium-flight-simulator)
|
|
511
|
+
- Globe architecture inspired by [Cesium VR tutorials](https://cesium.com/learn/) (Viewing the Globe, Dynamic Metadata UI)
|
|
512
|
+
- Blockchain data powered by [Helius](https://helius.dev)
|
|
513
|
+
- Token prices from [BirdEye](https://birdeye.so)
|
|
514
|
+
- Maps by [Mapbox](https://mapbox.com)
|
|
515
|
+
- Satellite imagery via [Cesium](https://cesium.com) + OpenStreetMap
|
|
516
|
+
- OSM Buildings 3D Tiles via [Cesium Ion](https://ion.cesium.com) asset #96188
|
|
517
|
+
- Solana SDK for UE5 by [Bifrost Technologies](https://github.com/Bifrost-Technologies/Solana-Unreal-SDK)
|
|
518
|
+
- Google Street View via [Cesium Ion experimental API](https://cesium.com/docs/rest-api/)
|