footprint

Project Url: vishal2376/footprint
Introduction: Footprint is a kotlin multiplatform app that turns everyday walks into an exploration game
More: Author   ReportBugs   
Tags:
Footprint is a kotlin multiplatform app that turns everyday walks into an exploration game. Every street you walk, every neighborhood you visit, gets permanently "unlocked" on your personal map.


### [ Watch Demo Video ]


💡 Motivation

Living in Bangalore, I often find myself taking evening walks through the city's countless lanes and neighborhoods. One day, while exploring a new area, I realized I had no idea how much of my own city I had actually seen. That thought stuck with me.

I started wondering, what if there was a way to visualize my explorations? Not just track kilometers walked, but actually see which parts of the city I've discovered and which remain unexplored.

That's how Footprint was born, a companion app that turns everyday walks into an exploration game. Every street you walk, every neighborhood you visit, gets permanently "unlocked" on your personal map. The unexplored areas remain hidden behind mysterious tiles, waiting to be discovered.


✨ Features

Map Reveal

  • Unexplored areas are hidden behind dark, mysterious tiles with "?" symbols. As you walk, tiles reveal themselves permanently, showing the actual map underneath.

Live GPS Tracking

  • Record your exploration tracks with real-time path drawing. See your journey unfold on the map as you move

Exploration Statistics

  • Total Distance - How far you've traveled across all tracks
  • Total Duration - Time spent exploring
  • Tiles Explored - Number of map tiles you've unlocked
  • World Percentage - What fraction of the world you've discovered

Modern UI/UX

  • Dark theme with cyan/blue gradient accents
  • Smooth animations (pulsing location marker, radar loading effect)
  • Bento grid dashboard with animated stats
  • Custom F1-style screen transitions

Gamified Experience

  • The mystery tiles create curiosity. The stats create motivation. Every walk becomes a small adventure.

🏗️ Architecture

Footprint follows Clean Architecture principles with clear separation between layers:

┌─────────────────────────────────────────────────────────────┐
│                    Presentation Layer                       │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────┐  │
│  │ HomeScreen  │  │  MapScreen  │  │ Components/Effects  │  │
│  │ + ViewModel │  │ + ViewModel │  │ (Shared UI)         │  │
│  └─────────────┘  └─────────────┘  └─────────────────────┘  │
├─────────────────────────────────────────────────────────────┤
│                      Domain Layer                           │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────┐  │
│  │   Models    │  │ Repositories│  │     Use Cases       │  │
│  │ Track,Tile  │  │ (Interfaces)│  │ GetLiveLocation     │  │
│  └─────────────┘  └─────────────┘  └─────────────────────┘  │
├─────────────────────────────────────────────────────────────┤
│                       Data Layer                            │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────┐  │
│  │  Room DB    │  │    DAOs     │  │   Repositories      │  │
│  │ (SQLite)    │  │ Track,Tile  │  │   (Implementations) │  │
│  └─────────────┘  └─────────────┘  └─────────────────────┘  │
└─────────────────────────────────────────────────────────────┘

Project Structure

composeApp/
├── src/
│   ├── commonMain/
│   │   └── kotlin/
│   │       ├── data/
│   │       │   ├── datasource/     # TileStreamProvider
│   │       │   ├── local/          # Room Database, DAOs, Entities
│   │       │   └── repository/     # Repository Implementations
│   │       ├── domain/
│   │       │   ├── model/          # Track, Location, MapConfig
│   │       │   ├── repository/     # Repository Interfaces
│   │       │   └── usecase/        # GetLiveLocationUseCase
│   │       ├── presentation/
│   │       │   ├── home_screen/    # Dashboard with stats
│   │       │   ├── map_screen/     # Interactive map
│   │       │   ├── common/         # Shared components
│   │       │   ├── navigation/     # Compose Navigation
│   │       │   └── theme/          # Colors, Typography
│   │       ├── di/                 # Koin Dependency Injection
│   │       └── util/               # Format, Time, Tile utilities
│   │
│   ├── androidMain/         # Android-specific
│   │   └── kotlin/
│   │       ├── MysteryTileGenerator  # Android Canvas rendering
│   │       ├── PermissionHandler     # Android permissions
│   │       └── LocationService       # Fused Location Provider
│   │
│   └── iosMain/             # iOS-specific
│       └── kotlin/
│           ├── MysteryTileGenerator  # CoreGraphics rendering
│           ├── PermissionHandler     # CLLocationManager
│           └── LocationService       # CoreLocation

🔧 Technical Details

Libraries & Technologies

Category Library Purpose
UI Compose Multiplatform Shared declarative UI
Navigation Compose Navigation Type-safe navigation
Database Room (KMP) Local persistence
DI Koin Dependency injection
Networking Ktor OSM(Open Street Map) tile fetching
Map Rendering MapCompose Tile map rendering
Async Kotlin Coroutines + Flow Reactive data streams

Key Technical Decisions

1. Fog of War Implementation

  • Custom TileStreamProvider that checks tile exploration status
  • Unexplored tiles render platform-specific mystery graphics (Android Canvas / iOS CoreGraphics)
  • Parent tile inheritance - exploring a tile at zoom 15 also "reveals" parent tiles

2. Tile System

  • Uses OSM standard: 256×256 pixel tiles
  • Zoom levels 10-18 supported
  • Tile key format: {zoom}_{x}_{y}
  • Efficient parent-child lookup for zoom transitions

3. Platform Abstraction

  • expect/actual pattern for location services, permissions, and mystery tile generation
  • Shared ViewModel logic, platform-specific hardware access

4. Performance Optimizations

  • Debounced tile reload (1000ms) to prevent flickering
  • Lazy Koin injection for database to avoid startup blocking
  • WAL mode enabled for Room database

🚀 How to Run

Prerequisites

  • Android Studio Ladybug (2024.2.1) or later
  • Xcode 15+ (for iOS)
  • JDK 17+
  • Android Emulator or physical device
  • iOS Simulator or physical device

Clone the Repository

git clone https://github.com/vishal2376/footprint.git
cd footprint

Android

  1. Open the project in Android Studio
  2. Wait for Gradle sync to complete
  3. Select composeApp configuration
  4. Choose an Android emulator or connected device
  5. Click Run

iOS

  1. Open iosApp/iosApp.xcodeproj in Xcode
  2. Select a simulator or connected device
  3. Click Run

🏁 Future Roadmap

  • [ ] Offline Maps — Download tiles for offline exploration
  • [ ] Achievement System — Badges for milestones (100 tiles, 10km walked, etc.)
  • [ ] Track History — View and replay past exploration tracks
  • [ ] Heat Map — Visualize frequently visited areas
  • [ ] Social Sharing — Share exploration stats with friends

🔒 License

This project is licensed under the MIT License - see the LICENSE file for details.


Made with ❤️ by Vishal Singh
Apps
About Me
GitHub: Trinea
Facebook: Dev Tools