# Forsaken Arena ## About This App A retro 2D top-down asymmetric arena game where one player hunts survivors or fights for survival against an AI killer ## Specification # Retro 2D Top-Down 1 vs All Arena Game — with Critical Pathfinding Fix Create a retro-styled 2D top-down arena game rendered on HTML5 Canvas, inspired by asymmetric multiplayer games like Forsaken. The game features a **Survivor vs Killer** dynamic where one Killer hunts multiple AI Survivors, or the player can choose to play as a Survivor trying to outlast the clock against an AI Killer. The entire experience runs client-side with a full game loop: **Lobby → Match → Results → Lobby**. --- ## App Type: HTML5 Canvas App This is a real-time 2D game with pixel-art aesthetics, smooth camera scrolling, particle effects, floating damage numbers, and AI state machines. HTML5 Canvas is the ideal rendering target for this type of experience. --- ## Visual Style & Color Palette - **Retro pixel-art aesthetic** — chunky pixels, simple shapes, minimal detail for clarity and performance. - **Primary palette:** - **Dark Red** (`#8B0000`, `#A52A2A`) — Killer elements, danger indicators, bleeding effects - **Dark Blue** (`#00008B`, `#1A1A5E`) — Survivor elements, objectives, safe zones - **Purple** (`#4B0082`, `#6A0DAD`) — UI accents, ability effects, special states - **Background:** Very dark navy/charcoal (`#0D0D1A`) with subtle grid lines for the map floor. - **Walls and obstacles:** Dark gray pixel blocks with slight purple tint. - **All characters are colored circles** with small pixel accessories: - Courier: Blue circle with a small package/hat accessory - Skipper: Green circle with goggles - Chief: Yellow circle with a headband - Parasite: Red circle with tendrils (disguises as map objects via Mimic passive) - **Font:** Pixel/monospace font (use a web-safe monospace or embed a pixel font via Google Fonts like "Press Start 2P"). - **Resolution:** Max canvas size **1200×800**, scaled to fit the browser window while maintaining aspect ratio. --- ## UI Layout & Elements ### Title Screen - Retro-styled game logo with pixel animation (pulsing/glowing text). - "PLAY" button prominently centered. - Brief tagline: *"Survive. Outsmart. Outlast."* - Dark background with subtle animated pixel particles. ### Lobby Screen (1600×1200 world, camera follows player) - The player's character spawns in a simple rectangular room with pixel-art decorations. - Player can walk around the lobby freely using WASD. - **HUD Overlay (HTML/CSS on top of canvas):** - **Top-left:** Money display with a coin icon and amount (e.g., `🪙 250`). - **Top-right:** Settings gear icon button. - **Bottom-center:** Action buttons — "Ready Up" / "Start Match" button. - **Left panel (toggleable):** **Shop** — grid of character cards (Survivors & Killers) with: - Character circle preview with accessory - Name, role tag (Support/Survivalist/Sentinel/Chaser) - Difficulty stars (★★★☆☆ style) - Cost or "OWNED" badge - "Buy" / "Equip" button - **Right panel (toggleable):** **Inventory** — list of owned characters, currently equipped highlighted. - **Role selector:** Toggle between "Play as Survivor" and "Play as Killer" with character sub-selection. - **New players** automatically receive Courier (Survivor) and Parasite (Killer) for free. - Purchases and inventory persist via **localStorage**. ### Settings Panel (Modal overlay) - Sound volume slider (for future SFX). - Control reference card showing WASD, Q, E, R, T, F, LMB mappings. - "Reset Data" button with confirmation dialog. - Close button (X) in top-right corner. --- ## In-Match HUD ### Top Center - **Round Timer** — Large retro-styled countdown clock (starts at `4:00`). Pulses red when under 1:00. Flashes during Last Man Standing transition. - **Survivor Count** — Small icons showing alive/dead survivors (colored circles, X over dead ones). ### Bottom Center - **Ability Bar** — Horizontal row of ability slots: - **Q**, **E**, **R**, **T** keybind labels above each slot. - Cooldown shown as a sweeping radial overlay (dark overlay that recedes clockwise). - Ability icon/name inside each slot. - Greyed out when on cooldown, glowing border when ready. - Passive ability shown as a smaller slot to the left with a "P" label. - **Interact Prompt** — When near an objective, show `[F] Hold to Interact` with a progress bar that fills as the player holds F. ### Top Left - **Health Bar** — Horizontal bar with pixel-art styling. - Green fill for Survivors (turns yellow at 50%, red at 25%). - Dark red fill for Killer (massive bar, 5000 HP). - Numeric HP value displayed inside the bar. - Character name above the bar. ### Right Side - **Active Effects Panel** — Vertical list of currently active status effects on the player: - Effect icon + name + duration remaining. - Stack count in Roman numerals (e.g., "Bleeding III"). - Color-coded: - Speed: Light blue - Slowness: Gray - Bleeding: Red with drip animation - Regeneration: Green with pulse - Stunned: Yellow with stars - Exhausted: Orange - Revealed: White with eye icon ### Floating Elements (rendered on canvas) - **Nameplates** above each character — small pixel text with the character name. - **Health bars** above each character — thin colored bar. - **Floating damage numbers** — pop up and float upward when damage is dealt, red for damage, green for healing, with slight randomized horizontal drift. - **ESP Arrows** — When "Revealed" effect is active or Sensor is placed, render directional arrows at the edge of the screen pointing toward the detected entity. ### Objectives - Rendered as glowing blue diamond shapes on the map. - Pulsate gently to attract attention. - Show interaction progress ring when a survivor is holding F nearby. - Disappear with a satisfying pixel-burst particle effect when completed. - Timer briefly flashes and shows "-5s" floating text when an objective is completed. - "+40s" floating text in red when a survivor is killed. --- ## Match Flow & Functionality ### Pre-Match - 3-second countdown overlay ("3... 2... 1... HUNT!") with dramatic pixel text. - Players spawn at designated positions on the map. ### During Match - **Camera** smoothly follows the player character with slight lerp/easing. - **Map:** Procedurally arranged rooms and corridors with walls (simple rectangular collision geometry). Dark-themed with purple-tinted walls. Map is larger than the viewport (scrolling world). - **Collision:** Characters collide with walls. Projectiles collide with walls and stop. - **AI Survivors** (when player is Killer): Wander, complete objectives, flee from killer when spotted, use abilities contextually, Support types heal nearby allies. - **AI Killer** (when player is Survivor): Wanders, chases visible survivors, uses abilities intelligently, prioritizes injured survivors when timer is low. - **Combat:** - Killer basic attack (LMB): Shows a swipe arc animation in front of the killer, 0.4s windup, 20 damage + Bleeding I. - Survivors cannot basic attack — only use Q/E/R abilities. - Endlag shown as a brief "dizzy stars" effect on the character. ### Death - **Death animation:** Character shrinks, flashes, and bursts into pixels. - **Spectator mode:** Camera can cycle between remaining alive players. Grey-tinted overlay with "SPECTATING" label. ### Last Man Standing - When 1 survivor remains: Screen briefly flashes, timer snaps to `1:13`, dramatic text overlay "LAST MAN STANDING" fades in and out. - Killer permanently chases the last survivor (AI override). - Survivor gets ESP arrow updating every 2 seconds. - UI border pulses red. ### Win/Lose Screen - Full-screen overlay with results: - **"SURVIVORS WIN"** (blue) or **"KILLER WINS"** (red) in large pixel text. - Stats panel: - Survival time - Objectives completed - Kills (for Killer) - Damage dealt/taken - **"Return to Lobby"** button. - Award money based on performance (displayed with coin animation). --- ## Character Ability Details (Functional Implementation) ### Survivors - **Courier (Support, Free):** - Passive: Speed I buff when near teammate while being chased (40s CD). - Q — Supply Box: Place a crate on the ground. Survivors touching it get Regen I (5s), Killers get Slowness I (5s). 60s CD. - E — Sensor: Place a sensor. Detects nearby killers every 2s, shows arrow. Only one at a time. 40s CD. - **Skipper (Survivalist, Free):** - Q — Burst: Speed V for 1 second. 40s CD. - E — Pass: Instantly complete a nearby objective, causes heavy endlag. 80s CD. - **Chief (Sentinel, 120 coins):** - Passive: Stun duration becomes 2s when timer < 1:30. - Q — Fist: 0.4s windup punch, stuns killer 4s. Miss = 1s endlag. 30s CD. - E — Lunge: Short dash. 30s CD. - R — Gambit: Charge forward, pushes killer. Miss = Slowness III for 3s. 45s CD. ### Killer - **Parasite (Chaser, Free):** - Passive: Mimic — disguised as a map object until first attack (rendered as a crate/rock until revealed). - LMB — Swipe: 0.4s windup, 20 dmg + Bleeding I. 1.8s CD. - Q — Spawn: Summon a small red slime that slowly chases nearest survivor, deals 10 dmg on contact, lasts 15s. 30s CD. - E — Melt: Become a slime puddle for 10s, move faster, deal 5 dmg on touch. Heavy endlag on exit. 30s CD. - R — Slime Throw: Projectile, 5 dmg + Bleeding II. 40s CD. --- ## 🔧 CRITICAL: Robust AI Pathfinding System This section describes the **core pathfinding architecture** that ALL AI bots (Survivors and Killers) must use. This system must be rock-solid to prevent bots from getting stuck on walls, walking into obstacles, or freezing in place. ### Pathfinding Grid & World-Position-Based Path Origin - The pathfinding grid is derived from the map's wall tile data. Each grid cell is classified as **walkable** or **blocked**. - **CRITICAL RULE:** When generating a path for any bot, the path origin must ALWAYS be the bot's **actual world position** (its `x, y` pixel coordinates), NOT simply the grid cell the bot occupies. - Convert the bot's world position to a grid coordinate, then **validate** that this grid cell is walkable: - If the grid cell at the bot's exact position IS walkable → use it as the path start. - If the grid cell at the bot's exact position is BLOCKED (e.g., bot is partially overlapping a wall edge) → perform a **nearest walkable node search**: - Search in a spiral or BFS pattern outward from the bot's grid position. - Find the closest walkable grid cell. - Use that cell as the path start. - This ensures the path never begins inside a wall. ### Path Destination Validation - Before calculating a path, validate the **destination** node as well: - If the destination grid cell is blocked, search for the nearest walkable cell to the intended destination. - Never attempt to pathfind TO a blocked cell. ### A* Pathfinding Algorithm - Use A* (or a simplified BFS/Dijkstra if performance is a concern) over the walkable grid. - Only expand into walkable neighbor cells (4-directional or 8-directional, but if 8-directional, ensure diagonal movement doesn't cut through wall corners — validate that both adjacent orthogonal cells are also walkable before allowing a diagonal step). - Return a list of waypoints (world-position coordinates at the center of each grid cell along the path). ### Full Path Validation (Post-Generation) After a path is generated, **validate every single waypoint** before the bot begins following it: 1. For each waypoint in the path: - Convert it to its grid cell. - Check if that grid cell is walkable. 2. If ANY waypoint is inside a blocked/wall tile: - **Option A (preferred):** Skip that waypoint entirely and connect the previous valid waypoint to the next valid waypoint. - **Option B:** Discard the entire path and immediately recalculate a new one. 3. If the path is empty or all waypoints are invalid, the bot should enter a **recovery mode** (see Stuck Detection below). ### Waypoint Following - Bots move toward their current waypoint at their movement speed. - When the bot is within a small threshold distance (e.g., 4–8 pixels) of the current waypoint, advance to the next waypoint. - **Before moving toward a waypoint each frame**, do a quick sanity check: - Is the next waypoint's grid cell still walkable? (Map doesn't change in this game, but this is a safety net.) - If not, skip to the next valid waypoint or recalculate the path. ### Stuck Detection & Recovery System Implement a **stuck detection timer** on every AI bot. This system runs every frame during movement: 1. **Track position history:** Every ~0.5 seconds, record the bot's world position. 2. **Stuck condition:** If the bot has moved less than **8 pixels of total distance** over the last **1.0 seconds** (2 consecutive samples), the bot is considered **stuck**. 3. **Wall-bumping detection:** If the bot's velocity is non-zero (it's trying to move) but its position hasn't changed meaningfully, it's bumping into a wall. 4. **On stuck detected:** - Immediately **cancel the current path**. - Clear all waypoints. - Find the **nearest valid walkable node** from the bot's current actual world position (using the spiral/BFS search). - If the bot's current cell is blocked, **nudge** the bot's position to the center of the nearest walkable cell (a small teleport correction to get them unstuck). - Generate a **completely new path** to the bot's current goal (objective, flee target, chase target, or a random wander point). - If the new path also fails, pick a **random nearby walkable cell** as a temporary goal and path to it, then resume normal AI behavior. 5. **Stuck counter escalation:** If a bot gets stuck 3+ times in rapid succession (within 5 seconds), force it to teleport to the nearest valid walkable cell center and pick a completely new random destination. This is a last-resort failsafe. ### Applies To All AI Behaviors This robust pathfinding system must be used consistently across **every AI behavior mode**: - **Wander pathfinding:** Bot picks a random walkable cell as a destination, generates a validated path, follows it. On arrival, waits briefly, picks a new random destination. - **Objective pathfinding (Survivors):** Bot targets the nearest incomplete objective's world position, validates the destination cell, generates a path. If the objective is unreachable, pick the next closest one. - **Chase pathfinding (Killer):** Bot targets a visible survivor's current position. Re-path every ~0.5–1.0 seconds to track moving targets. Always validate the new path ## About Berrry Berrry transforms your social media content into interactive web applications. Share a Twitter/X post or Reddit comment, and our AI creates a custom web app hosted at your own subdomain. **Visit**: https://berrry.app Transform your social media ideas into real web applications today.