0% found this document useful (0 votes)
6 views20 pages

Hexfront Build Guide

Uploaded by

sharmaji66662
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views20 pages

Hexfront Build Guide

Uploaded by

sharmaji66662
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

HEXFRONT

Build Guide & Technical Blueprint


The Real-World Hex Turf War Running App

Version 1.0 | Confidential | 2025


1. Concept Overview & App Name

What is HEXFRONT?
HEXFRONT is a real-world, multiplayer, location-based turf war app where players physically
run to capture and defend hexagonal territories on a live city map. Every run you complete
doesn't just burn calories — it conquers land. Every neighborhood block becomes a battlefield.
Every rival runner is a threat to your empire.
The name HEXFRONT was chosen deliberately:
• HEX — refers to the hexagonal H3 grid system that divides the entire world map into
game tiles
• FRONT — evokes a war front, a battle line, the razor's edge between your territory and
your enemy's
Together, it's sharp, memorable, and instantly communicates the strategic + physical nature of
the game.

Core Gameplay Loop


The experience is simple to understand but endlessly deep in practice:
1. Open HEXFRONT → tap DEPLOY to start your run
2. Your GPS traces a live path on the dark map as you move
3. Every H3 hexagon you run through turns your color
4. Captured hexagons decay slowly unless you reinforce them
5. If a rival runs through your hex faster than you claimed it, they steal it
6. Factions of runners coordinate city-wide conquest campaigns

💡 The psychological hook: territory you've physically earned with sweat feels viscerally yours.
Losing it feels personal. This drives runners back out the next morning.
2. Recommended Tech Stack

The following stack was selected for speed of development, scalability, and suitability for
geospatial + real-time requirements. It intentionally departs from generic recommendations by
using Supabase as a unified backend layer to dramatically reduce boilerplate.

Layer Technology Why This Choice


Mobile App React Native (Expo) Cross-platform, fast iteration, deep
GPS/accelerometer access
Maps Mapbox GL JS (React Native Custom dark tile styles, high performance
Maps Mapbox) hex overlay rendering
Hex Grid Uber H3 (h3-js) Industry-standard hexagonal indexing, open
source, deterministic
Backend API Python FastAPI Async-native, ideal for real-time endpoints,
great PostGIS library support
Database PostgreSQL + PostGIS Non-negotiable for geospatial queries and
polygon operations
Auth + DB BaaS Supabase Manages Postgres + Auth + Realtime
subscriptions in one service
Real-Time Supabase Realtime / Push live map updates and 'Under Attack'
WebSockets alerts to clients
Push Notifs Expo Push + Firebase FCM Cross-platform device notifications for
attack alerts
AI Agents Python + LangChain / Orchestrate Adjudicator + Rogue Runner
LangGraph agent logic
Hosting Railway (Backend) + One-click deploys, scales automatically,
Supabase (DB) generous free tier
Scheduler APScheduler (Python) Run cron jobs: territory decay, AI agent
spawns, leaderboard refresh

💡 Why Supabase instead of raw Node + Express? Supabase gives you managed Postgres with
PostGIS pre-installed, built-in Auth (JWT), and Realtime subscriptions out of the box. This alone
saves 2-3 weeks of backend scaffolding.
3. Project Structure

Organize the monorepo with the following top-level structure. Each sub-folder is an
independently deployable service:
hexfront/
├── mobile/ ← React Native (Expo) app
│ ├── app/ ← Expo Router screens
│ ├── components/ ← Reusable UI components
│ ├── hooks/ ← GPS, WebSocket, auth hooks
│ ├── lib/ ← h3-js utils, API clients
│ └── assets/ ← Fonts, icons
├── backend/ ← Python FastAPI server
│ ├── api/ ← Route handlers
│ ├── agents/ ← AI agent logic
│ ├── db/ ← Database models + migrations
│ └── scheduler/ ← Cron jobs
├── supabase/ ← SQL migrations, edge functions
└── docs/ ← This document!
4. Database Schema (PostGIS)

The database is the brain of HEXFRONT. Every territory claim, run session, and player stat
lives here. Run all migrations in Supabase's SQL editor or via the Supabase CLI.

Enable PostGIS Extension


First, enable the geospatial extension in your Supabase project:
-- Run in Supabase SQL Editor
CREATE EXTENSION IF NOT EXISTS postgis;
CREATE EXTENSION IF NOT EXISTS h3; -- optional: h3-pg extension

Table 1: users
Extends Supabase Auth. Stores game-specific user data.
CREATE TABLE [Link] (
id UUID PRIMARY KEY REFERENCES [Link](id),
username TEXT UNIQUE NOT NULL,
faction TEXT, -- e.g. 'Neon Syndicate'
total_hexes INT DEFAULT 0,
total_km FLOAT DEFAULT 0,
rank INT DEFAULT 9999,
created_at TIMESTAMPTZ DEFAULT NOW()
);

Table 2: hexagons (Core Territory Table)


This is the most important table. Each row is one H3 hex cell on the world map.
CREATE TABLE [Link] (
hex_id TEXT PRIMARY KEY, -- H3 index string e.g. '8928308280fffff'
owner_id UUID REFERENCES profiles(id) ON DELETE SET NULL,
faction TEXT,
captured_at TIMESTAMPTZ,
pace_score FLOAT, -- pace (sec/km) when captured
health INT DEFAULT 100, -- 0-100; decays over time
center GEOGRAPHY(POINT, 4326) -- lat/lon center of hex
);
CREATE INDEX hexagons_owner_idx ON hexagons(owner_id);
CREATE INDEX hexagons_health_idx ON hexagons(health);
Table 3: run_sessions
Records every completed run with its GPS path stored as a PostGIS LineString.
CREATE TABLE public.run_sessions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES profiles(id),
started_at TIMESTAMPTZ,
ended_at TIMESTAMPTZ,
distance_m FLOAT,
avg_pace FLOAT, -- seconds per km
hex_ids TEXT[], -- array of captured hex_ids
path GEOGRAPHY(LINESTRING, 4326)-- full GPS route
created_at TIMESTAMPTZ DEFAULT NOW()
);

Table 4: events (Activity Feed)


CREATE TABLE [Link] (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
type TEXT, -- 'capture', 'stolen', 'defended', 'ai_attack'
actor_id UUID REFERENCES profiles(id),
target_id UUID REFERENCES profiles(id),
hex_id TEXT,
created_at TIMESTAMPTZ DEFAULT NOW()
);
5. Backend API (FastAPI)

The FastAPI backend handles the complex geospatial logic that can't live purely in the
database. It receives completed run data, processes H3 hex claims, triggers notifications, and
runs the AI agent scheduler.

Setup & Installation


# From /backend directory
python -m venv venv && source venv/bin/activate
pip install fastapi uvicorn asyncpg supabase h3 shapely
pip install langchain langgraph apscheduler httpx python-jose

Core API Endpoints


Method Endpoint Description
POST /runs/complete Receives GPS path → converts to H3 hexes → updates
territory ownership
GET /hexagons/nearby Returns hex states within a bounding box (for live map
rendering)
GET /leaderboard Returns top players by hex count, filterable by city/faction
GET /profile/{id} Returns user stats: total hexes, km run, current streak
POST /faction/join Assigns user to a faction; updates all owned hexes to
faction color
GET /map/heatmap Returns aggregated activity density for heatmap overlay
WS /ws/live WebSocket endpoint: streams live position broadcasts +
attack alerts

The Core Territory Claim Logic


This is the most critical function in the entire backend. It runs when a user finishes a run:
# backend/api/[Link]
import h3
from [Link] import LineString

async def process_run(user_id: str, gps_coords: list[tuple], avg_pace: float):


# Step 1: Convert GPS coordinates to H3 hex IDs (resolution 9 ≈ 174m² per hex)
hex_ids = set()
for lat, lng in gps_coords:
hex_id = h3.geo_to_h3(lat, lng, resolution=9)
hex_ids.add(hex_id)

# Step 2: For each hex, check current owner


for hex_id in hex_ids:
existing = await db.get_hex(hex_id)

if existing is None:
# Unclaimed land — capture it
await db.claim_hex(hex_id, user_id, avg_pace)

elif existing.owner_id == user_id:


# Own land — reinforce health
await db.reinforce_hex(hex_id, min([Link] + 20, 100))

elif avg_pace < existing.pace_score * 0.95:


# Faster runner steals the hex
await db.steal_hex(hex_id, user_id, avg_pace)
await notify_attack(existing.owner_id, hex_id, user_id)

await db.save_run_session(user_id, gps_coords, hex_ids, avg_pace)


6. Mobile App (React Native / Expo)

Setup
npx create-expo-app hexfront-mobile --template blank-typescript
cd hexfront-mobile
npx expo install expo-location expo-task-manager
npx expo install react-native-maps @rnmapbox/maps
npm install h3-js @supabase/supabase-js zustand

Screen Architecture (Expo Router)


app/
(auth)/
[Link] ← Supabase auth sign-in
[Link]
(tabs)/
[Link] ← Main Map Screen (the core experience)
[Link] ← Player stats dashboard
[Link] ← Global/city/faction rankings
[Link] ← Faction info & recruitment

Background GPS Tracking


Background location tracking is the hardest mobile engineering challenge in the app. The phone
must continuously poll GPS every 3 seconds even when the screen is locked. Expo's
TaskManager handles this:
// hooks/[Link]
import * as Location from 'expo-location';
import * as TaskManager from 'expo-task-manager';

const TASK_NAME = 'hexfront-tracking';

// Define the background task OUTSIDE any component


[Link](TASK_NAME, async ({ data, error }) => {
if (data) {
const { locations } = data as any;
const { latitude, longitude } = locations[0].coords;
// Apply GPS drift filter (ignore if speed > 40 km/h)
if (locations[0].[Link] < 11) { // 11 m/s = 40 km/h
await appendCoordinate({ latitude, longitude });
}
}
});

export async function startTracking() {


await [Link]();
await [Link](TASK_NAME, {
accuracy: [Link],
timeInterval: 3000, // poll every 3 seconds
distanceInterval: 10, // or every 10 meters, whichever comes first
showsBackgroundLocationIndicator: true,
});
}

Live Map Screen (Mapbox + H3 Overlay)


The map renders colored hexagon polygons over a dark Mapbox base map. Each hex is drawn
using its boundary coordinates from h3-js:
// components/[Link] — simplified
import { h3ToGeoBoundary } from 'h3-js';

const HexLayer = ({ hexagons }) => {


const features = [Link](hex => ({
type: 'Feature',
geometry: {
type: 'Polygon',
coordinates: [h3ToGeoBoundary(hex.hex_id, true)] // GeoJSON format
},
properties: { color: getFactionColor([Link]), opacity: [Link] / 100 }
}));

return (
<ShapeSource id='hexes' shape={{ type: 'FeatureCollection', features }}>
<FillLayer id='hex-fill' style={{
fillColor: ['get', 'color'],
fillOpacity: ['get', 'opacity']
}} />
</ShapeSource>
);
};
7. AI Agent System — "The Council"

HEXFRONT uses a multi-agent architecture to keep the map alive and balanced 24/7, even
when no human players are active. The three agents — Adjudicator, Rogue Runner, and
Bounty Agent — run as a Python scheduled process using APScheduler.

Agent 1: The Adjudicator (Game Master)


Runs every 2 hours. Analyzes the map for imbalances and dispatches other agents to correct
them. It never acts on the map directly — it only decides and delegates.
# agents/[Link]
async def adjudicator_tick():
# Find zones with no human activity in last 48 hours
stagnant_zones = await [Link]('''
SELECT hex_id FROM hexagons
WHERE captured_at < NOW() - INTERVAL '48 hours'
AND owner_id IS NOT NULL
GROUP BY GEOGRAPHY_CLUSTER(center, 500) -- cluster nearby hexes
''')

for zone in stagnant_zones[:3]: # max 3 dispatches per tick


await spawn_rogue_runner(zone)

# Find monopoly zones (one player owns >80% of a bbox)


monopolies = await db.get_monopoly_zones()
for zone in monopolies:
await drop_bounty(zone, multiplier=3.0)

Agent 2: Rogue Runner (PvE Adversary)


Simulates a real runner taking a route through stagnant territory. Uses a cron job to update its
GPS position every 5 seconds, making it appear as a live competitor on the map.
# agents/rogue_runner.py
import httpx

async def spawn_rogue_runner(target_zone):


# Get a realistic running route via Mapbox Directions API
route = await get_running_route(target_zone.center, radius_km=2)

# Create AI runner record in database


runner_id = await db.create_ai_runner({
'name': generate_ai_name(), # e.g. 'GHOST_UNIT_07'
'pace': [Link](5.0, 6.5), # min/km — realistic human pace
'route': [Link],
'is_ai': True
})

# Schedule position updates (simulates real movement)


scheduler.add_job(
advance_runner_position,
'interval', seconds=5,
args=[runner_id, route],
id=f'runner_{runner_id}'
)

# Push notification to players in the area


await notify_area(target_zone, 'GHOST UNIT detected. Intercept to reclaim
territory.')

Agent 3: Bounty Agent (Incentive Engine)


Drops temporary high-value multiplier zones in low-traffic areas to coax players into exploring
new routes.
# agents/bounty_agent.py
async def drop_bounty(zone, multiplier=3.0):
await [Link]('bounties', {
'hex_id': zone.hex_id,
'multiplier': multiplier,
'expires_at': [Link]() + timedelta(hours=12),
'claimed': False
})
# Broadcast to all users in same city
await [Link]('map-updates', {
'type': 'bounty_dropped',
'hex_id': zone.hex_id,
'multiplier': multiplier
})
8. Territory Decay & Anti-Cheat

Territory Decay Cron Job


Runs every 6 hours. Reduces the 'health' of all hexagons by a small amount. This forces
players to regularly re-run their turf, keeping the map dynamic:
-- SQL job via Supabase pg_cron (enable in project settings)
SELECT [Link](
'decay-territory',
'0 */6 * * *', -- every 6 hours
$$
UPDATE hexagons
SET health = GREATEST(0, health - 8)
WHERE owner_id IS NOT NULL;

-- Remove dead territories (fully decayed)


UPDATE hexagons
SET owner_id = NULL, faction = NULL, health = 100
WHERE health = 0;
$$
);

Anti-Cheat System
Three-layer cheat detection runs server-side on every run submission:
• Speed Filter (Layer 1): Any GPS coordinate with a calculated speed above 25 km/h
between consecutive points is discarded as drift or vehicle movement. The remaining
valid points are used for hex calculation.
• Accelerometer Validation (Layer 2): The mobile app also sends accelerometer cadence
data. Running has a distinct step frequency (1.5–3 Hz). If a session shows movement
but zero accelerometer signature, it is flagged automatically.
• Pattern Analysis (Layer 3): A daily ML job (Python + scikit-learn) analyzes run patterns.
Perfectly straight lines, impossibly consistent pacing, or routes that never repeat are red
flags. Flagged accounts are queued for manual review before banning.
9. Real-Time System (Supabase + WebSockets)

Real-time responsiveness is what separates HEXFRONT from a static fitness tracker. Three
real-time channels handle different update types:

Channel Trigger Subscriber Action


map-updates Hex Re-render affected hex on all nearby clients'
captured/stolen/bounty maps
dropped
user:{user_id} Own hex is stolen Show 'TERRITORY BREACH' modal with
crimson alert
faction:{faction} Faction war event, AI Faction-wide broadcast banner at top of
agent attack screen

On the mobile client, the Supabase Realtime client subscribes to these channels on app startup:
// hooks/[Link]
import { supabase } from '../lib/supabase';

export function useRealtimeAlerts(userId: string) {


useEffect(() => {
const channel = supabase
.channel(`user:${userId}`)
.on('broadcast', { event: 'territory_stolen' }, (payload) => {
showAttackModal([Link]); // launch crimson alert modal
triggerHaptic('heavy'); // buzz the phone
})
.subscribe();

return () => [Link](channel);


}, [userId]);
}
10. MVP Development Phases

Build in four tightly scoped phases. Ship each phase before moving to the next to avoid scope
creep.

Phase 1 — Single Player Proof of Concept (Weeks 1–2)


Goal: One user can run and see their territory appear on a map. Nothing else.
• Set up Supabase project, enable PostGIS, run schema migrations
• Build Expo app with background GPS tracking using expo-location
• Implement H3 hex conversion from GPS coordinates on the backend
• Render captured hexagons as colored polygons on Mapbox dark map
• Save completed runs to run_sessions table
💡 Success criteria: You go for a jog around your block, open the app, and see a glowing hex
cluster in your exact route. The database shows the correct hex_ids.

Phase 2 — Territory Logic & Database Brain (Weeks 3–4)


Goal: Ownership, conflict resolution, leaderboards, and health decay all work correctly.
• Implement the full territory claim/steal logic in the FastAPI backend
• Wire up territory health decay via pg_cron
• Build leaderboard query (top players by hex count in each city)
• Add basic user profiles with hex stats
• Test: two test accounts, simulate one stealing territory from the other
💡 Success criteria: Running the same hex with a faster pace successfully transfers ownership
and logs the event in the events table.

Phase 3 — Multiplayer & Alerts (Weeks 5–6)


Goal: The app feels multiplayer and reactive. Attacks feel dramatic.
• Implement Supabase Realtime channels for live hex map updates
• Build the 'TERRITORY BREACH' modal with crimson styling
• Integrate Expo Push Notifications for background attack alerts
• Build basic faction system (join a faction, see faction leaderboard)
• Add the War Room dashboard screen with player stats
💡 Success criteria: With two real phones, stealing a hex on phone A immediately triggers the
crimson alert on phone B within 3 seconds.
Phase 4 — AI Agents & Polish (Weeks 7–9)
Goal: The map feels alive. The app looks and feels like a premium game.
• Build the Adjudicator, Rogue Runner, and Bounty Agent cron system
• Implement the accelerometer anti-cheat validation
• Apply full dark holographic UI polish: hex glow effects, neon color coding by faction
• Add progression: titles, streak tracking, territory flags for top players
• Internal beta with 20–50 runners in one city
11. UI Design — Vibe Coding Prompts

Use these prompts directly in Cursor, Lovable, [Link], or any AI coding assistant to generate
the frontend components with the correct aesthetic. The design language is cyber-corporate:
sharp edges, dark backgrounds, neon accents, no rounded bubbles.

Prompt A: Main Map HUD


Drop this into your AI coding tool:
"Create a React Native Expo map screen using Mapbox GL. The base map must use a dark custom
style (deep charcoal, pure black water). Overlay a transparent HUD. Top bar: user Territory Owned in
sq meters + Global Rank using Space Mono font, neon cyan (#00FFFF) text on pure black. Bottom: a
large DEPLOY button — sharp rectangular corners, neon cyan glow, glassmorphism fill, no border-
radius. On press, button turns crimson (#E94560) and text changes to MISSION ACTIVE. Aesthetic:
cyber-corporate, high contrast, no bubbles, no gradients."

Prompt B: Territory Breach Modal


"Build a React Native Modal component for a territory breach alert. Background: semi-transparent
black overlay. Central panel: sharp right angles, 1px solid border with neon crimson (#E94560) glow,
dark charcoal fill. Header text: TERRITORY BREACH DETECTED in uppercase, Space Mono,
crimson, subtle pulse animation. Body: [Username] is overwriting Sector [N]. Your hex health is
critically low. Two buttons: DISMISS in muted #333 with white text, and MOBILIZE in solid crimson
with black text. Both are sharp rectangles, no border-radius. Whole vibe: sci-fi emergency system
alert."

Prompt C: War Room Dashboard


"Design a React Native player profile screen called the War Room. Background: pure black #000000.
Accent colors: neon purple #B026FF and cyan #00FFFF. Show a 2x2 stat grid: Total Distance (km),
Hexes Controlled, Current Streak (days), Global Rank. Each stat is in a dark grey card (#111) with
1px glowing purple border, monospace font for numbers. Below: Recent Skirmishes list — green text
for DEFENDED events, red for LOST, white for CAPTURED. Bottom: faction badge with faction
name in neon. Aesthetic: data-dense, minimalist cyberpunk, no decorative elements."
12. Monetization Strategy

HEXFRONT should launch free with no pay-to-win mechanics. All paid features must be
cosmetic or analytical — never giving paying users a competitive edge in territory claiming.

Revenue Stream Model Details


HEXFRONT Pro Subscription Detailed run analytics, custom hex colors, 3
₹149/mo faction slots, performance heatmaps
Cosmetic Packs One-time IAP Animated hex trails (e.g. fire, lightning), avatar
frames, territory flags
City Championships Entry fee ₹99 Bracketed monthly events: top faction in a city
wins physical prize or credits
Brand Bounties B2B Partnership Local businesses sponsor high-value bounty
zones near their locations
Data Insights (B2B) Enterprise Anonymized city mobility heatmaps sold to
urban planners & brands

13. Launch Strategy (India First)

India is the ideal first market: massive young population of competitive runners, extremely high
smartphone penetration, and — critically — no competitor currently occupies this space.

City-by-City Rollout
Do not launch nationally. A turf war game with 10 players feels dead. A turf war game with 500
players in one dense neighborhood feels intensely alive. Launch in exactly one city first —
Bengaluru is the recommended target due to its running culture (Cubbon Park, Nandi Hills
community) and tech-savvy demographic.
• Month 1: Closed beta with 50 hand-picked runners in Bengaluru. Use Discord for
feedback.
• Month 2: Open launch in Bengaluru + create the 'BLR Conquest' inaugural faction war
event
• Month 3: Expand to Mumbai, Delhi, and Hyderabad simultaneously using referral
rewards
• Month 6: Pan-India with inter-city faction wars (Delhi vs. Mumbai bragging rights)
Organic Growth Hooks
• Every run generates a shareable, auto-rendered clip of the player's territory expanding
— perfect for Instagram Reels and Strava
• Leaderboards are public and searchable by city/neighborhood, creating natural rivalry
and word-of-mouth
• Faction wars create natural communities and group runs, generating UGC without any
marketing spend
14. Quick Reference Cheatsheet

Concept Key Detail


H3 Resolution Use Resolution 9 (≈174m² hex). Resolution 8 is too large, 10 is too
small for city running
GPS Poll Rate 3 seconds / 10 meters — whichever triggers first. Anything faster kills
battery
Cheat Speed Threshold Discard coordinates showing speed > 25 km/h (roughly a bicycle)
Health Decay Rate 8 points per 6 hours → full decay in 75 hours (≈3 days without
revisit)
Steal Condition Rival's pace must be >5% faster than original capture pace
Mapbox Token Get a free token at [Link]. Dark style ID:
mapbox://styles/mapbox/dark-v11
Supabase Free Tier 500 MB database + 50,000 monthly active users — sufficient for city-
scale beta
AI Runner Pace Assign random realistic pace: 4:30–7:00 min/km. This is human
marathon-to-jogger range
Bounty Duration 12-hour expiry, 3x multiplier. Creates daily urgency without being
oppressive

HEXFRONT — Confidential Build Document


The map is waiting. Claim it.

You might also like