A full-stack location-based augmented reality mobile game featuring real-time multiplayer interactions, geospatial gameplay, and push notifications. Players place "curses" (virtual entities) at real-world locations or on other users, competing to level up through strategic placement and destruction of these AR/GIS entities.
PรSSESSฦD is an innovative location-based AR game where players "possess the world" by placing curses at real-world GPS coordinates or directly on other players. The game combines real-world exploration with strategic gameplay, encouraging players to explore their surroundings while competing against others in a persistent multiplayer world.
Core Gameplay:
- Place curses at physical locations or on other users
- Destroy curses placed by others to gain experience
- Level up your character through conquest
- Earn and spend "curse credits" (in-app currency)
- Compete on leaderboards
- Real-time notifications when your curses are destroyed
- Strategic resource management (energy, weapons, credits)
- Framework: React Native 0.66.3
- State Management: Redux Toolkit with Redux Persist
- Navigation: React Navigation 4.x (Stack, Drawer, Tabs)
- Maps: React Native Maps with Geolocation tracking
- Real-time: Socket.IO Client for live multiplayer events
- UI Components: React Native Elements
- Animations: React Native Animatable & Reanimated
- Storage: AsyncStorage with Redux Persist
- Language: TypeScript
- HTTP Client: Axios
- Runtime: Node.js 14.x
- Framework: Express.js
- Database: MongoDB with Mongoose ODM
- Caching: Redis with Redis Adapter for Socket.IO
- Real-time: Socket.IO Server (with Redis pub/sub for scaling)
- Authentication: JWT (JSON Web Tokens) with BCrypt password hashing
- Push Notifications: Apple Push Notification Service (APN)
- Email: Gmail integration via gmail-send
- Cloud Services: AWS Lambda client integration
- Rate Limiting: redis-rate-limiter for API protection
- Testing: Jest with MongoDB Memory Server
- ID Generation: shortid for unique entity IDs
โโโโโโโโโโโโโโโโโโโ
โ Mobile App โ (React Native)
โ (iOS/Android) โ
โโโโโโโโโโฌโโโโโโโโโ
โ
โ REST API (HTTP)
โ WebSocket (Socket.IO)
โ
โโโโโโโโโโผโโโโโโโโโ
โ Express Server โ
โ + Socket.IO โ
โโโโโโโโโโฌโโโโโโโโโ
โ
โโโโโโดโโโโโ
โ โ
โโโโโผโโโ โโโโผโโโโ
โMongoDBโ โ Redisโ
โ (Data)โ โ(Cacheโ
โโโโโโโโโ โ& Pub/โ
โ Sub) โ
โโโโโโโโ
-
Express REST API (
packages/backend)- User authentication and management
- AR/GIS entity CRUD operations (curses)
- Activity feed tracking
- Leaderboard queries
- Admin utilities (push notifications, contact forms)
- Static landing page serving
-
Socket.IO Real-time Server (
packages/backend/api/library/socket.js)- Real-time event broadcasting
- User room subscriptions
- Redis adapter for horizontal scaling
- Events:
userCursed,creditRateChanged
-
MongoDB Database (Mongoose models)
- Users: Player profiles, stats, credentials, device tokens
- ArGis: Curse entities with geospatial data (location or user-targeted)
- Activity: Player actions (attach location/user, destroy, friend)
-
React Native Mobile App (
packages/mobile-app)- Redux Toolkit for state management
- React Native Maps for geolocation visualization
- Socket.IO client for real-time updates
- Persistent storage with Redux Persist
Curse System:
- Location-Based Curses: Place curses at real-world GPS coordinates tied to named locations
- User-Targeted Curses: Attack other players directly by placing curses on them
- Curse Credits: In-app currency used to place curses (costs vary)
- Destruction: Destroy enemy curses to gain experience and reduce their credit earnings
- Anonymous Placement: Option to place curses anonymously
Character Progression:
- Experience & Leveling: Gain XP by destroying curses; level up at
(level^1.2) * 30XP - Level-Up Points: Spend on permanent upgrades (energy, weapons, regeneration)
- Stats:
experience: Current XP towards next levellevel: Current character levellevelUps: Available upgrade pointscurseCredits: Currency for placing cursestotalEnergyFactor: Max energy capacity multiplierenergyRegenerationFactor: Energy recovery speed multiplierweaponRegenerationFactor: Weapon recharge speed multiplier
Resource Management:
- Energy System: Time-based regeneration for actions
- Credit Refresh: Periodic credit regeneration mechanism
- Session Tracking:
creditsEarnedSessiontracks earnings per session
- โ Activity feed (friend actions, attachments, destroys)
- โ Leaderboard system (by experience/level)
- โ User search functionality
- โ Real-time notifications when cursed or destroyed
- โ Tutorial system for new players
- โ JWT-based authentication with bcrypt password hashing
- โ Redis-based rate limiting (IP and token-based)
- โ Geospatial queries with MongoDB Point schema
- โ Real-time multiplayer via Socket.IO with Redis adapter
- โ iOS push notifications via APN
- โ Email notifications (Gmail SMTP)
- โ Password reset functionality
- โ CORS-enabled admin endpoints
- โ Static landing page with game info
- โ Privacy policy & terms of service pages
- Node.js 14.x or later
- MongoDB (local or hosted)
- Redis (local or hosted)
- React Native development environment
- iOS: Xcode with CocoaPods
- Android: Android Studio with SDK
- (Optional) Apple Developer account for push notifications
cd packages/backend
# Install dependencies
npm install
# Configure environment variables
cp .env.example .env
# Edit .env with your configuration:
# - MONGODB_URI: MongoDB connection string
# - REDIS_HOST, REDIS_PORT, REDIS_KEY: Redis connection details
# - JWT_SECRET: Secret for JWT token signing
# - GMAIL_USER, GMAIL_PASS: Gmail SMTP credentials
# - APN_KEY_ID, APN_TEAM_ID, APN_KEY: Apple Push Notification credentials
# Start MongoDB (if running locally)
mongod
# Start Redis (if running locally)
redis-server
# Run development server (defaults to port 2012)
npm run start-dev
# Run production server (uses PORT env variable)
npm start
# Run tests
npm testcd packages/mobile-app
# Install dependencies
npm install
# iOS: Install CocoaPods dependencies
cd ios && pod install && cd ..
# Configure environment
cp .env.example .env
# Edit .env with your backend API URL
# Run on iOS
npm run ios
# Run on Android
npm run android
# Run tests
npm test
# Run linter
npm run lint
# Format code
npm run prettypossessed-monorepo/
โโโ packages/
โ โโโ mobile-app/ # React Native mobile application
โ โ โโโ __tests__/ # Jest test files
โ โ โโโ android/ # Android native code
โ โ โโโ ios/ # iOS native code
โ โ โโโ app/ # Application source code
โ โ โโโ actions/ # Redux action creators
โ โ โโโ components/ # Reusable UI components
โ โ โ โโโ activities/ # Activity feed components
โ โ โ โโโ curseWorld.tsx
โ โ โ โโโ demonPreview.tsx
โ โ โ โโโ ...
โ โ โโโ containers/ # Connected container components
โ โ โโโ hooks/ # Custom React hooks
โ โ โโโ reducers/ # Redux reducers
โ โ โโโ services/ # API service layer
โ โ โโโ types/ # TypeScript type definitions
โ โ โโโ utils.ts # Utility functions
โ โ โโโ store.ts # Redux store configuration
โ โ โโโ navigation.tsx # React Navigation setup
โ โ
โ โโโ backend/ # Node.js backend server
โ โโโ api/ # API modules
โ โ โโโ arGis/ # AR/GIS entity management
โ โ โ โโโ model/ # Mongoose schema
โ โ โ โ โโโ ar-gis-model.js
โ โ โ โ โโโ ar-gis-types.js
โ โ โ โโโ dao/ # Data access layer
โ โ โ โโโ controller/ # Request handlers
โ โ โ โโโ routes/ # Express routes
โ โ โ โโโ arGisLibrary.js # Business logic
โ โ โโโ users/ # User management
โ โ โ โโโ model/ # User schema
โ โ โ โโโ dao/
โ โ โ โโโ controller/
โ โ โ โโโ routes/
โ โ โโโ activity/ # Activity feed
โ โ โ โโโ model/ # Activity schema
โ โ โ โโโ dao/
โ โ โ โโโ controller/
โ โ โ โโโ routes/
โ โ โโโ admin/ # Admin utilities
โ โ โ โโโ routes.js
โ โ โ โโโ admin-controller.js
โ โ โโโ library/ # Shared utilities
โ โ โ โโโ socket.js # Socket.IO setup
โ โ โ โโโ notifications.js
โ โ โโโ middleware/ # Express middleware
โ โ โ โโโ auth.js # JWT authentication
โ โ โ โโโ rateLimiter.js
โ โ โโโ config.js # Configuration loader
โ โ โโโ database.js # MongoDB connection
โ โ โโโ point.js # GeoJSON Point schema
โ โ โโโ router.js # Route aggregator
โ โโโ public/ # Static files
โ โ โโโ index.html # Landing page
โ โ โโโ privacyPolicy.html
โ โ โโโ termsOfService.html
โ โ โโโ images/
โ โ โโโ css/
โ โ โโโ fonts/
โ โโโ test/ # Jest tests
โ โโโ index.js # Server entry point
โ โโโ package.json
โ
โโโ README.md # This file
POST /api/users- User signup (IP rate limited)PUT /api/users- User signin (IP rate limited)POST /api/resetPassword- Request password reset email
PATCH /api/users- Search for users (auth required)PUT /api/user- Update user profile (auth required)POST /api/user- Increment user stat field (auth required)PATCH /api/user- Use level-up point (auth required)POST /api/leaderboard- Get leaderboard (auth required)POST /api/refreshCredits- Attempt credit refresh (auth required)
POST /api/argis- Place new curse (auth required)PUT /api/argis- Get curses near location (auth required)PATCH /api/argis- Destroy/kill a curse (auth required)POST /api/argisLocate- Get curses within radius (auth required)PUT /api/yourArgis- Get your placed curses (auth required)PATCH /api/yourArgis- Get curses placed against you (auth required)POST /api/argisLocations- Check curse existence at locations (auth required)POST /api/argisUsers- Check curses on users (auth required)
- (Activity routes exist - check
activity/routes/activity-routes.js)
GET /api/admin- Get server hostname (IP rate limited)POST /api/admin- Send test push notification (IP rate limited)POST /api/support- Submit support request (CORS enabled)POST /api/contact- Submit contact form (CORS enabled)POST /api/subscribe- Newsletter subscription (CORS enabled)
GET /- Landing pageGET /privacyPolicy.html- Privacy policyGET /termsOfService.html- Terms of service
subscribeUser- Subscribe to user-specific events (join room)unsubscribeUser- Unsubscribe from user events (leave room)
userCursed- Notification when a curse is placed on the user- Payload: ArGis entity object
creditRateChanged- Notification when credit rate changes- Payload:
{ newCreditRate: number }
- Payload:
{
_id: String (shortid),
username: String (3-20 chars, unique, lowercase),
email: String (optional, โค100 chars),
password: String (bcrypt hashed),
experience: Number (default: 0),
energyRegenerationFactor: Number (default: 1),
weaponRegenerationFactor: Number (default: 1),
totalEnergyFactor: Number (default: 1),
level: Number (default: 10),
levelUps: Number (default: 10),
energyTimeToTotal: Number,
curseCredits: Number (default: 35),
creditsEarnedSession: Number (default: 0),
lastCreditRefresh: Date,
deviceToken: String (for push notifications, โค150 chars),
lastLocation: Point (GeoJSON),
tutorialWatched: Boolean (default: false),
createdAt: Date,
updatedAt: Date
}{
_id: String (shortid),
type: String ('location' | 'user'), // Curse target type
arType: String, // Visual representation type
createdBy: String (User ref),
createdByUsername: String,
anonymous: Boolean (default: false),
locationName: String, // For location-based curses
locationId: String, // Location identifier
geometry: Point (GeoJSON), // GPS coordinates
targetUser: String (User ref), // For user-targeted curses
destroyedBy: String (User ref, nullable),
destroyedDate: Date (nullable),
createdAt: Date,
updatedAt: Date
}{
_id: String (shortid),
user: String (User ref, required), // Actor
targetUser: String (User ref), // Target (optional)
arGis: String (ArGis ref), // Related curse
type: String ('friend' | 'destroy' | 'attachlocation' | 'attachuser'),
createdAt: Date,
updatedAt: Date
}- Unique compound index on:
(user, targetUser, type, arGis)
- Player selects location on map OR targets specific user
- System checks if curse already exists at that location/target
- Player spends curse credits (cost varies by curse type)
- Curse entity created in database with GPS coordinates
- Target user receives real-time Socket.IO notification (if user-targeted)
- Creator's
creditsEarnedSessionincrements by 1
- Player selects enemy curse to destroy
- System calculates experience reward
- Experience added to player's total
- Level-up check:
XP >= (level^1.2) * 30 - If level up: XP resets to 0, level increments, levelUps += 1
- Curse marked as destroyed in database
- Creator's
creditsEarnedSessiondecrements by 1 - Push notification sent to curse creator (if device token exists)
- Curse Credits: Primary currency, used to place curses
- Energy: Time-based resource for actions (regeneration factor upgradeable)
- Weapons: Combat resource (regeneration factor upgradeable)
- Level-Up Points: Spent on permanent stat upgrades
- MongoDB GeoJSON Point schema for precise GPS storage
- Geospatial queries for "nearby" curse detection
- Radius-based curse retrieval
- Location-based curse uniqueness checks
Never commit to version control:
.envfiles containing credentials*.p8,*.p12,*.pemfiles (Apple certificates)- API keys or secrets
- Database credentials
- Redis passwords
Required Environment Variables (Backend):
# Server
PORT=2012
# Database
MONGODB_URI=mongodb://localhost:27017/possessed
# Redis
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_KEY=your-redis-password
# Authentication
JWT_SECRET=your-jwt-secret
# Email (Gmail)
GMAIL_USER=your-email@gmail.com
GMAIL_PASS=your-app-password
# Apple Push Notifications
APN_KEY_ID=your-apn-key-id
APN_TEAM_ID=your-apn-team-id
APN_KEY=path/to/AuthKey.p8Mobile App Configuration:
- Edit
packages/mobile-app/.envwith backend API base URL - Configure Redux store for persistence
- Set up Axios base URL in
setupAxios.ts
# Backend tests (with MongoDB Memory Server)
cd packages/backend
npm test
# Mobile app tests
cd packages/mobile-app
npm test# Backend
cd packages/backend
npm run pretty # Prettier formatting
# Mobile app
cd packages/mobile-app
npm run lint # ESLint
npm run pretty # Prettier formatting
npm run tsc # TypeScript type checkingBackend:
- Server logs include Socket.IO connection events
- Redis connection status logged on startup
- MongoDB connection status via Mongoose
Mobile:
- Redux DevTools integration (if configured)
- React Native Debugger compatible
- Console logs for API requests (Axios interceptors in
setupAxios.ts)
- Designed for Node.js 14.x environments
- Requires MongoDB and Redis instances
- Can be deployed to: Heroku, AWS EC2/Elastic Beanstalk, DigitalOcean, etc.
- Ensure all environment variables are set
- Static files served from
public/directory
- iOS: Build with Xcode, deploy via App Store Connect
- Android: Build APK/AAB, deploy via Google Play Console
- Configure production API endpoint before build
What makes this project interesting:
- Geospatial Gaming: MongoDB GeoJSON integration for real-world location-based gameplay
- Dual Curse Types: Innovative location AND user-targeted curse system
- Real-time Multiplayer: Socket.IO with Redis adapter for horizontal scaling
- Strategic Resource Management: Multi-layered progression (XP, levels, credits, energy, weapons)
- Rate Limiting: Redis-based IP and token rate limiting for API security
- Push Notification Integration: APN for real-time mobile alerts
- Persistent State: Redux Persist for offline capability
- Security: JWT auth + bcrypt password hashing + middleware protection
- Scalable Architecture: Redis pub/sub for Socket.IO across multiple servers
Private - All rights reserved
Note: This is a portfolio project showcasing full-stack mobile game development, real-time multiplayer systems, geospatial programming, and scalable backend architecture. The production deployment and API keys have been removed for security. The game's tagline "Possess The World" and branding "Brought to you by Beezlebuddy ๐" reflect its playful demonic theme.