Skip to content

seamushinz/FogBound

Repository files navigation

FogBound

A location-based mobile app that reveals an interactive fog-of-war map as you explore the real world. Built with React Native and Expo, FogBound combines gaming mechanics with exploration to encourage outdoor discovery.

Table of Contents

Overview

FogBound creates a persistent fog-of-war overlay on a map that clears as you physically visit locations. The app tracks your movement using GPS, divides the world into grid cells, and stores visited cells locally using SQLite. Points of interest (POIs) are hidden until discovered, creating an exploration-based experience.

Features

  • Fog-of-War System: Real-time fog overlay that clears as you explore
  • Deterministic Grid System: 200m Web Mercator cells with consistent coordinates
  • Persistent Storage: SQLite database for offline-first visited cell tracking
  • POI Discovery: Hidden points of interest revealed as you explore
  • Daily Mystery POIs: Time-limited discoverable locations
  • Background Tracking: Continuous location tracking even when app is backgrounded
  • Performance Optimized: Adaptive LOD system, LRU caching, and viewport-based rendering
  • Cross-Platform: Works on iOS, Android, and Web

Demo

Demo video and live deployment links will be added here:

  • Video Demo: [Coming Soon]
  • Live Demo: [Coming Soon]

Tech Stack

Frontend

  • React Native 0.81.5
  • Expo SDK 54
  • TypeScript 5.9
  • Expo Router (file-based routing)
  • React Native Maps
  • Expo SQLite
  • Zustand (state management)
  • React Native Skia (shader-based fog rendering)

Backend

  • Node.js 20+
  • Express.js
  • TypeScript
  • MongoDB (optional, currently using in-memory storage)
  • Zod (validation)

Key Libraries

  • expo-location: GPS tracking and geofencing
  • expo-task-manager: Background location updates
  • expo-secure-store: Secure credential storage

Installation

Prerequisites

  • Node.js 20 or higher
  • npm or yarn package manager
  • Expo Go app on your phone:
  • For iOS development: macOS with Xcode
  • For Android development: Android Studio

Clone and Install

  1. Clone the repository:
git clone https://github.com/seamushinz/FogBound.git
cd FogBound
  1. Install frontend dependencies:
npm install

Running the App

Option 1: Expo Go (Recommended for Quick Start)

  1. Start the Expo development server:
npm start
  1. Scan the QR code with:
    • iOS: Camera app (will open in Expo Go)
    • Android: Expo Go app

Option 2: iOS Simulator (macOS only)

npx expo run:ios

Option 3: Android Emulator

npm run android

Option 4: Web Browser

npm run web

Note: Location features are limited in web browsers and simulators. For full experience, use a physical device.

Backend Setup

The backend is optional for basic functionality (local-only mode). To enable cloud sync:

Quick Start (In-Memory Mode)

  1. Navigate to backend directory:
cd backend
  1. Install dependencies:
npm install
  1. Create environment file:
cp .env.example .env
  1. Start development server:
npm run dev

Server runs on http://localhost:3000 by default.

MongoDB Setup (Optional)

For persistent cloud storage:

  1. Create a MongoDB Atlas cluster at mongodb.com/cloud/atlas

  2. Create a database named fogbound with collections for cells and user data

  3. Update .env with your MongoDB connection string:

MONGODB_URI=mongodb+srv://<username>:<password>@<cluster-url>/fogbound?retryWrites=true&w=majority

Replace <username>, <password>, and <cluster-url> with your actual MongoDB credentials.

  1. Update backend/src/app.ts to use MongoCellRepo instead of InMemoryCellRepo

API Endpoints

  • GET /health - Health check
  • POST /cells/sync - Upload cell visit data (requires auth)
  • GET /cells/bbox - Retrieve cells in bounding box (requires auth)

See backend/README.md for detailed API documentation.

Project Architecture

FogBound/
├── app/                    # Expo Router screens and navigation
│   ├── (tabs)/            # Tab-based navigation screens
│   │   ├── index.tsx      # Main map screen with fog overlay
│   │   ├── history.tsx    # User history and statistics
│   │   ├── account.tsx    # User account management
│   │   └── debug.tsx      # Debug tools and settings
│   ├── auth.tsx           # Authentication screen
│   └── _layout.tsx        # Root layout and navigation
├── components/            # Reusable UI components
│   ├── FogOverlay.tsx     # Polygon-based fog rendering
│   ├── FogShaderOverlay.tsx # Skia shader-based fog rendering
│   └── ui/                # UI components
├── db/                    # SQLite database operations
│   ├── cellDatabase.ts    # Visited cell CRUD operations
│   ├── pois.ts            # POI storage and queries
│   └── dailyMysteryPois.ts # Daily mystery POI tracking
├── services/              # External service integrations
│   ├── overpass.ts        # OpenStreetMap POI fetching
│   └── LocationTask.ts    # Background location tracking
├── utils/                 # Utility functions and helpers
│   ├── mercator.ts        # Web Mercator coordinate conversion
│   ├── grid.ts            # Grid cell calculations
│   ├── locationTracker.ts # Location update handling
│   └── poiVisibility.ts   # POI classification logic
├── store/                 # Global state management (Zustand)
├── assets/                # Images, fonts, and static assets
├── backend/               # REST API server
│   ├── src/
│   │   ├── routes/        # API route handlers
│   │   ├── middleware/    # Auth and error handling
│   │   └── repositories/  # Data access layer
│   └── package.json
└── package.json

Fog System Architecture

FogBound uses a deterministic grid-based fog-of-war system:

  1. Web Mercator Grid: Fixed 200m rectangular cells aligned consistently across zoom levels
  2. SQLite Storage: Persistent visited cell tracking with x/y coordinates
  3. Viewport Rendering: Only renders visible cells plus padding (never the whole world)
  4. Performance Optimization:
    • Level-of-Detail (LOD) system with adaptive cell grouping
    • LRU caching with quantized keys
    • Rectangle merging to reduce polygon count
    • Adaptive padding based on zoom level
    • Throttled fog refresh during panning

See FOG_SYSTEM.md for detailed technical documentation.

Development

Available Scripts

Frontend

  • npm start - Start Expo development server
  • npm run ios - Run on iOS simulator (macOS only)
  • npm run android - Run on Android emulator
  • npm run web - Run in web browser

Backend

  • npm run dev - Start development server with hot reload
  • npm run build - Compile TypeScript to JavaScript
  • npm start - Run compiled production server
  • npm run lint - Type-check without emitting files

Environment Variables

Create a .env file in the backend directory:

PORT=3000
# MONGODB_URI=mongodb+srv://...  # Optional

Location Permissions

The app requires location permissions to function:

  • iOS: "Allow While Using App" or "Allow Always" for background tracking
  • Android: Location permission with background access

Permissions are requested on first app launch.

Troubleshooting

Fog not rendering

  1. Check that location permissions are granted
  2. Verify database initialization in console logs
  3. Ensure you're testing on a physical device (simulators have limited GPS)
  4. Check that FogOverlay component is inside MapView

Performance issues

  1. Reduce maxPolygons prop on FogOverlay component
  2. Increase CELL_SIZE_M in utils/grid.ts for coarser grid
  3. Check device frame rate in React Native profiler

Backend connection issues

  1. Verify backend server is running on correct port
  2. Check firewall settings allow connections
  3. Update frontend API endpoint configuration
  4. For MongoDB: verify connection string and network access

Build errors

  1. Clear Expo cache: npx expo start -c
  2. Reinstall dependencies: rm -rf node_modules && npm install
  3. For iOS: cd ios && pod install (if using bare workflow)
  4. For Android: Clean gradle cache

Location tracking not working

  1. Ensure location permissions are granted in device settings
  2. Check that device location services are enabled
  3. For iOS: Verify location permission strings in app.json
  4. For Android: Check background location permission is granted

Contributing

This project was developed as part of a hackathon. Contributions are welcome through pull requests.

Development Guidelines

  1. Follow existing code structure and conventions
  2. Keep components focused and reusable
  3. Document complex logic with comments
  4. Test on both iOS and Android when possible
  5. Use TypeScript for type safety

Demo Link

https://youtu.be/ddVi5jzmrD0

License

MIT

Acknowledgments

  • Built with Expo and React Native
  • POI data from OpenStreetMap via Overpass API
  • Map tiles from react-native-maps default providers

About

Swamphacks XI Hackathon Project

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors