diff --git a/Arcadefile b/Arcadefile index b51c9febf6..d558694082 100644 --- a/Arcadefile +++ b/Arcadefile @@ -1,5 +1,5 @@ -id: fish-folk-jumpy -name: jumpy +id: 8bit-games-fishy +name: fishy logoUrl: /static/images/ship/original.png coverImage: original: /static/images/cover/original.jpg @@ -9,7 +9,7 @@ marketingAssets: title: cover description: Cover image description: | - Fish Folk: Jumpy is a tactical 2D shooter, played online or on a shared screen. + Fishy - Dive into 8-bit Chaos! A tactical 2D shooter, played online or on a shared screen. Aim either left or right; the rest is up to clever movement and positioning in this fish-on-fish brawler! admins: - fllr diff --git a/CREDITS.md b/CREDITS.md index 0a4aa5bcdc..2c1a00201b 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -1,5 +1,13 @@ # Credits +## Publisher + +**8bit Games** - Publisher and modernization for Fishy v1.0+ + +## Original Project: Fish Folk: Jumpy + +Fishy is based on the open-source game Fish Folk: Jumpy, created by the Fish Fight Game & Spicy Lobster Developers community. + ## Forerunners - Landon [@superjoebob](https://twitter.com/superjoebob) - Duck Game creator diff --git a/Cargo.toml b/Cargo.toml index 5b32a222bc..6e25303d88 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,11 +1,11 @@ [package] -authors = ["The Fish Fight Game & Spicy Lobster Developers"] -default-run = "jumpy" -description = "A tactical 2D shooter" +authors = ["8bit Games"] +default-run = "fishy" +description = "Dive into 8-bit Chaos - A tactical 2D shooter" edition = "2021" license = "MIT OR Apache-2.0" -name = "jumpy" -version = "0.12.2" +name = "fishy" +version = "1.0.0" [features] default = [] diff --git a/MODERNIZATION_PLAN.md b/MODERNIZATION_PLAN.md new file mode 100644 index 0000000000..9899a99cdc --- /dev/null +++ b/MODERNIZATION_PLAN.md @@ -0,0 +1,694 @@ +# Fishy: Modernization & Web3 Integration Plan + +**Version:** 1.0 +**Date:** 2025-11-10 +**Target:** 8bit Games Sellable Product + +--- + +## Executive Summary + +This document outlines a comprehensive modernization strategy to transform Fish Folk: Jumpy into **Fishy** - a modern, cross-platform, web3-enabled 8-bit style tactical shooter ready for commercial deployment by 8bit Games. + +### Key Objectives +1. **Mobile/Web Modernization**: Full mobile support with touch controls and progressive web app capabilities +2. **Web3 Integration**: NFT cosmetics, token rewards, and blockchain-based tournaments +3. **Commercial Readiness**: Professional branding, monetization, and distribution strategy +4. **Rebranding**: Complete transition from "Fish Folk: Jumpy" to "Fishy" + +--- + +## 1. Mobile/Web Modernization Strategy + +### 1.1 Mobile Platform Support + +#### iOS/Android Native Builds +**Technology Stack:** +- Bevy 0.13+ (latest with mobile support improvements) +- Target platforms: + - iOS: arm64-apple-ios (iPhone/iPad) + - Android: aarch64-linux-android, armv7-linux-androideabi + +**Implementation Plan:** + +##### Phase 1: Touch Input System (2-3 weeks) +- [ ] Implement virtual joystick overlay for movement +- [ ] Add tap-to-shoot mechanics with direction indicators +- [ ] Create touch-based weapon switching (swipe gestures) +- [ ] Implement pinch-to-zoom camera controls +- [ ] Add haptic feedback for actions (shoot, hit, death) + +##### Phase 2: Mobile UI/UX (2 weeks) +- [ ] Redesign UI for smaller screens (responsive layouts) +- [ ] Larger touch targets (minimum 44x44 points) +- [ ] Simplified main menu for mobile +- [ ] Portrait and landscape orientation support +- [ ] Safe area handling for notched devices +- [ ] Optimize text rendering for mobile DPI + +##### Phase 3: Performance Optimization (2 weeks) +- [ ] GPU instancing for sprite batching +- [ ] Dynamic quality settings based on device +- [ ] Battery optimization (30/60 FPS toggle) +- [ ] Reduce texture sizes for mobile (2048x2048 max atlases) +- [ ] Implement asset streaming for large maps +- [ ] Profile memory usage (target <200MB RAM) + +##### Phase 4: Platform Integration (2 weeks) +- [ ] iOS: Xcode project generation +- [ ] Android: Gradle build configuration +- [ ] Platform-specific features: + - Push notifications (match invites) + - Cloud save sync (iCloud/Google Play Games) + - In-app purchases (cosmetics, battle passes) + - Social sharing (screenshots, replays) + - Leaderboards and achievements + +**Technical Approach:** +```rust +// Example: Touch input handling +#[cfg(target_os = "ios")] +#[cfg(target_os = "android")] +pub fn mobile_input_plugin() -> Plugin { + // Virtual joystick + // Touch gesture recognition + // Haptic feedback integration +} +``` + +#### Progressive Web App (PWA) Enhancement + +**Current State:** Basic WASM build exists +**Target State:** Full-featured PWA with offline support + +##### Enhancements (2 weeks) +- [ ] Service worker for offline play +- [ ] Web App Manifest (add to home screen) +- [ ] Install prompts for mobile browsers +- [ ] Touch controls for web mobile +- [ ] WebGL optimization (target 60fps on mid-range phones) +- [ ] IndexedDB for local save data +- [ ] Web Share API integration +- [ ] Fullscreen API for immersive play + +**Benefits:** +- Instant play on any device +- No app store approval delays +- Easier updates and distribution +- Lower distribution costs + +### 1.2 Cross-Platform Networking + +**Current Issue:** Networking disabled on WASM + +**Solution:** WebRTC-based Networking + +##### Implementation (3-4 weeks) +- [ ] Replace QUIC networking with WebRTC data channels +- [ ] Implement WebRTC signaling server +- [ ] Browser-to-browser peer connections +- [ ] NAT traversal (STUN/TURN servers) +- [ ] Maintain GGRS rollback netcode +- [ ] Cross-platform play (desktop ↔ mobile ↔ web) + +**Architecture:** +``` +Desktop (QUIC) ←→ Relay Server ←→ Web/Mobile (WebRTC) + ↓ ↓ + Local P2P ←←←←←←←←←←←←←→ WebRTC P2P +``` + +**Benefits:** +- Unified multiplayer across all platforms +- Reduced server costs (P2P connections) +- Lower latency for direct connections + +### 1.3 Responsive Design System + +- [ ] Implement UI scaling system (phone/tablet/desktop) +- [ ] Adaptive control schemes (touch/gamepad/keyboard) +- [ ] Dynamic HUD positioning based on aspect ratio +- [ ] Text size scaling for accessibility +- [ ] Colorblind modes +- [ ] High contrast modes + +--- + +## 2. Web3 Integration Strategy + +### 2.1 Blockchain Architecture + +**Chain Selection:** Polygon (low fees, gaming ecosystem) +**Backup Options:** Arbitrum, Base, or ImmutableX + +**Smart Contract System:** + +#### 2.1.1 NFT Cosmetics (ERC-1155) +```solidity +contract FishyCosmetics { + // Hats, skins, emotes as NFTs + // On-chain rarity system (common, rare, epic, legendary) + // Crafting system (combine 3 commons → 1 rare) + // Marketplace integration (OpenSea compatible) +} +``` + +**Implementation:** +- [ ] Design NFT metadata standard +- [ ] Create smart contracts (Solidity) +- [ ] Deploy to testnet (Mumbai/Goerli) +- [ ] Integrate wallet connection (WalletConnect, MetaMask) +- [ ] Implement in-game NFT display +- [ ] Marketplace integration + +**NFT Categories:** +- **Hats** (18 existing + 50+ new limited editions) +- **Skins** (4 existing + seasonal variants) +- **Emotes** (animated, voice lines) +- **Weapon Skins** (visual effects, trails) +- **Victory Animations** +- **Profile Banners** + +#### 2.1.2 $FISHY Token (ERC-20) +```solidity +contract FishyToken { + // Earn through gameplay + // Spend on cosmetics, tournaments + // Staking for rewards + // Tournament prize pools +} +``` + +**Tokenomics:** +- Total Supply: 1,000,000,000 $FISHY +- Distribution: + - 40% - Player rewards (5-year vesting) + - 20% - Liquidity pools + - 20% - Team & development (2-year vesting) + - 10% - Tournament prizes + - 10% - Community treasury + +**Earning Mechanics:** +- Match participation: 10-50 $FISHY per match +- Wins: 2x multiplier +- Daily quests: 100-500 $FISHY +- Season pass progression: 1,000-10,000 $FISHY +- Tournament prizes: 10,000-1,000,000 $FISHY + +#### 2.1.3 Tournament & Betting System +```solidity +contract FishyTournaments { + // Decentralized tournament brackets + // Entry fees in $FISHY + // Automated prize distribution + // Spectator betting (optional) +} +``` + +**Features:** +- [ ] On-chain tournament registration +- [ ] Smart contract prize pools +- [ ] Verifiable match results (signed by players) +- [ ] Anti-cheat integration +- [ ] Leaderboards stored on-chain +- [ ] Seasonal championships + +### 2.2 Wallet Integration + +**Supported Wallets:** +- MetaMask (web/mobile) +- WalletConnect (mobile) +- Coinbase Wallet +- Rainbow Wallet + +**Implementation:** +- [ ] Rust <-> WASM <-> JavaScript wallet bridge +- [ ] Transaction signing UI +- [ ] Gas estimation and optimization +- [ ] Error handling (insufficient funds, rejected tx) +- [ ] Account recovery flows + +### 2.3 On-Chain Features + +#### Player Profiles (NFT-based) +- [ ] Mint profile NFT on first connection +- [ ] Store stats and achievements on-chain +- [ ] Transferable accounts (sell/trade profiles) +- [ ] Reputation system + +#### Decentralized Marketplace +- [ ] In-game marketplace for NFT trading +- [ ] $FISHY as primary currency +- [ ] Peer-to-peer trades +- [ ] Royalty system (5% to creators) + +#### Achievement NFTs (Soulbound Tokens) +- [ ] Non-transferable achievement NFTs +- [ ] Proof of skill/participation +- [ ] Unlock special cosmetics +- [ ] Tournament winner badges + +### 2.4 Web3 UX Considerations + +**Gasless Transactions:** +- [ ] Implement EIP-2771 meta-transactions +- [ ] Sponsor gas for new players (first 10 transactions) +- [ ] Batch transactions to reduce costs + +**Hybrid Model:** +- [ ] Play-to-earn optional (not required) +- [ ] Free cosmetics available +- [ ] Traditional payment options (credit card) +- [ ] Fiat on-ramp integration (Stripe, MoonPay) + +--- + +## 3. Commercial Readiness: 8bit Games Package + +### 3.1 Monetization Strategy + +#### Free-to-Play Model +**Core Game:** Free +**Revenue Streams:** + +1. **Battle Pass** ($9.99/season, 3-month seasons) + - 100 tiers of rewards + - Free tier + premium tier + - Exclusive cosmetics + - $FISHY tokens + - Expected revenue: $50K-500K per season + +2. **Cosmetic Store** + - Hats: $1.99-$4.99 + - Skins: $4.99-$9.99 + - Bundles: $14.99-$24.99 + - Seasonal exclusives + - Expected revenue: $10K-100K monthly + +3. **NFT Marketplace** (5% commission) + - Limited edition drops + - Community creations + - Secondary market fees + - Expected revenue: $5K-50K monthly + +4. **Tournament Entry Fees** + - Free tournaments (ads) + - Paid tournaments ($5-$50 entry) + - Prize pool percentage (10%) + - Expected revenue: $20K-200K per major event + +5. **Advertising** (Mobile/Web only) + - Rewarded video ads (earn $FISHY) + - Banner ads (non-intrusive) + - Sponsored tournaments + - Expected revenue: $5K-30K monthly + +**Total Revenue Projection:** +- Year 1: $200K-$1.2M +- Year 2: $500K-$3M (with user growth) + +### 3.2 Distribution Strategy + +#### Desktop +- [x] Steam (existing) +- [ ] Epic Games Store +- [ ] itch.io (existing/enhanced) +- [ ] GOG.com +- [ ] Microsoft Store + +#### Mobile +- [ ] Apple App Store +- [ ] Google Play Store +- [ ] Amazon Appstore + +#### Web +- [x] Official website (fishy.8bitgames.io) +- [ ] Facebook Instant Games +- [ ] CrazyGames, Poki (web game portals) +- [ ] Kongregate + +#### Web3 Platforms +- [ ] Gala Games +- [ ] Ultra.io +- [ ] Xsolla Web Shop + +### 3.3 Professional Game Infrastructure + +#### Backend Services (Required) +- [ ] **Authentication Server** + - Email/password + OAuth (Google, Apple, Discord) + - Web3 wallet login + - Account linking (multiple wallets) + +- [ ] **Matchmaking Server** + - Skill-based matchmaking (ELO/MMR) + - Region selection + - Custom lobbies + - Party system + +- [ ] **Leaderboards & Stats** + - Global rankings + - Friend leaderboards + - Historical stats tracking + - Match replay storage + +- [ ] **Anti-Cheat System** + - Client integrity checks + - Server-authoritative validation + - Report system + - Automated bans + +- [ ] **Content Delivery Network (CDN)** + - Fast asset delivery worldwide + - Patch distribution + - Web build hosting + +- [ ] **Analytics Platform** + - Player retention tracking + - Funnel analysis + - A/B testing framework + - Monetization metrics + +**Technology Stack:** +- Backend: Rust (Axum/Actix-web) or Node.js +- Database: PostgreSQL + Redis +- Hosting: AWS/GCP/DigitalOcean +- CDN: Cloudflare/BunnyCDN +- Analytics: Mixpanel/Amplitude + custom + +**Estimated Costs:** +- Infrastructure: $500-$2000/month (scales with users) +- CDN: $100-$500/month +- Analytics: $0-$500/month +- Total: $600-$3000/month + +### 3.4 Live Operations (LiveOps) + +#### Content Calendar +**Season 1 (Launch - Month 3)** +- New maps every 2 weeks +- Weekly featured modes +- Battle pass progression +- Community events + +**Season 2+ (Ongoing)** +- New fish characters (quarterly) +- New weapons (monthly) +- Limited-time events +- Collaborations/crossovers + +#### Community Engagement +- [ ] Discord server with bot integration +- [ ] Weekly dev blogs +- [ ] Community map contests +- [ ] Content creator program (rev share) +- [ ] Esports partnerships + +### 3.5 Legal & Compliance + +#### Required Components +- [ ] **Privacy Policy** (GDPR, CCPA compliant) +- [ ] **Terms of Service** +- [ ] **End User License Agreement (EULA)** +- [ ] **Age Rating Compliance** + - ESRB: E10+ (Everyone 10+) + - PEGI: 7 + - App Store age ratings + +- [ ] **Web3 Legal** + - Cryptocurrency compliance (per region) + - NFT ownership rights + - Tax reporting (1099 forms for US players) + - Gambling regulations (loot boxes, tournaments) + +- [ ] **Content Moderation** + - User-generated content policies + - Reporting system + - Moderation team + +#### Insurance & Business +- [ ] Cybersecurity insurance +- [ ] General liability insurance +- [ ] Smart contract audits (CertiK, OpenZeppelin) + +--- + +## 4. Rebranding Strategy: Fish Folk → Fishy + +### 4.1 Brand Identity + +**New Name:** Fishy +**Tagline:** "Dive into 8-bit Chaos" + +**Visual Identity:** +- Logo: Pixelated fish with attitude (8-bit style) +- Color Palette: Ocean blues, coral oranges, retro neons +- Typography: Pixel font (primary), clean sans-serif (secondary) +- Art Style: Enhanced 8-bit/16-bit aesthetic + +### 4.2 Rebranding Checklist + +#### Code & Configuration +- [ ] Rename Cargo.toml package name: "jumpy" → "fishy" +- [ ] Update all internal references +- [ ] Rename binary executable +- [ ] Update asset paths and metadata +- [ ] Change game title in config files +- [ ] Update version to 1.0.0 (fresh start) + +#### Assets & Content +- [ ] New logo assets (multiple sizes) +- [ ] Updated splash screen +- [ ] New app icons (desktop, mobile, web) +- [ ] Rebrand UI elements +- [ ] Update menu text and strings +- [ ] New music tracks (8-bit style) +- [ ] Sound effect polish + +#### Documentation & Marketing +- [ ] README.md overhaul +- [ ] New website (fishy.8bitgames.io) +- [ ] Press kit (logos, screenshots, videos) +- [ ] Social media accounts (@FishyGame) +- [ ] Steam store page redesign +- [ ] Trailer production (8-bit style) + +#### Legal & Business +- [ ] Trademark registration ("Fishy" game) +- [ ] Domain acquisition (fishy.gg, playfishy.com) +- [ ] Copyright updates +- [ ] Publisher agreement with 8bit Games + +### 4.3 Migration Strategy + +**Existing Players:** +- Import save data from "Fish Folk: Jumpy" +- Loyalty rewards (exclusive NFT for early adopters) +- Grandfather existing Steam purchases +- Clear communication about rebrand + +--- + +## 5. Technical Modernization + +### 5.1 Framework Upgrades + +**Current:** Bevy 0.11 (via bones_bevy_renderer) +**Target:** Bevy 0.13+ or latest stable + +**Benefits:** +- Improved mobile support +- Better WASM performance +- Enhanced ECS features +- Modern asset pipeline + +**Migration Plan:** +- [ ] Update Bones Framework dependency +- [ ] Test all systems after upgrade +- [ ] Benchmark performance improvements +- [ ] Update deprecated APIs + +### 5.2 Code Quality Improvements + +- [ ] Increase test coverage (current: minimal) +- [ ] Add integration tests for core gameplay +- [ ] Implement CI/CD for all platforms +- [ ] Set up automated release pipeline +- [ ] Add performance benchmarks +- [ ] Documentation overhaul (rustdoc) + +### 5.3 Modding & UGC Enhancement + +**Current:** Lua plugins + asset packs +**Enhanced:** + +- [ ] Steam Workshop integration +- [ ] In-game mod browser +- [ ] Visual map editor (desktop app) +- [ ] Skin creator tool +- [ ] Community showcase +- [ ] Revenue sharing for creators (NFT sales) + +### 5.4 Accessibility Features + +- [ ] Colorblind modes (protanopia, deuteranopia, tritanopia) +- [ ] Scalable UI/text +- [ ] Remappable controls +- [ ] Audio cues for visual events +- [ ] Screen reader support (menus) +- [ ] One-handed play mode + +--- + +## 6. Implementation Timeline + +### Phase 1: Foundation (Months 1-2) +- Rebranding to Fishy +- Mobile touch controls +- PWA enhancements +- Backend infrastructure setup + +### Phase 2: Web3 Integration (Months 2-4) +- Smart contract development & audit +- Wallet integration +- NFT cosmetics system +- $FISHY token launch + +### Phase 3: Mobile Launch (Months 4-6) +- iOS/Android builds +- Platform-specific features +- App store submissions +- Soft launch (select regions) + +### Phase 4: Monetization (Months 5-7) +- Battle pass system +- Cosmetic store +- NFT marketplace +- Tournament system + +### Phase 5: Live Operations (Months 6+) +- Season 1 content +- Community events +- Esports program +- Ongoing updates + +### Phase 6: Growth (Months 7-12) +- Marketing campaigns +- Influencer partnerships +- Platform expansions +- Feature updates based on feedback + +--- + +## 7. Success Metrics (KPIs) + +### Player Engagement +- Daily Active Users (DAU): Target 10K by month 6 +- Monthly Active Users (MAU): Target 50K by month 6 +- Average session length: 30+ minutes +- Retention (D1/D7/D30): 40%/20%/10% + +### Revenue +- ARPU (Average Revenue Per User): $2-5 +- Conversion rate: 5-10% +- Battle pass adoption: 15-25% +- Monthly recurring revenue: $50K+ by month 6 + +### Web3 Metrics +- Wallet connections: 20% of MAU +- NFT holders: 5-10K +- $FISHY market cap: $1M-$10M +- Trading volume: $100K+ monthly + +### Community +- Discord members: 10K+ +- Social media followers: 25K+ +- Content creators: 100+ +- User-generated maps: 1,000+ + +--- + +## 8. Risk Analysis + +### Technical Risks +- **Mobile performance:** Mitigation: Aggressive optimization, quality settings +- **Web3 complexity:** Mitigation: Hybrid model, excellent UX +- **Cross-platform netcode:** Mitigation: Thorough testing, WebRTC fallbacks +- **Smart contract exploits:** Mitigation: Professional audits, bug bounties + +### Business Risks +- **Market competition:** Mitigation: Unique 8-bit style, web3 features +- **Regulatory changes:** Mitigation: Legal counsel, geographic restrictions +- **Player adoption:** Mitigation: Free-to-play, excellent onboarding +- **Development delays:** Mitigation: Phased rollout, MVP focus + +### Mitigation Strategies +- Start with MVP features +- Iterative development with user feedback +- Strong community engagement +- Backup plans for each platform +- Regular security audits + +--- + +## 9. Team & Resources Required + +### Development Team +- 2-3 Rust/Bevy engineers (game development) +- 1 Solidity developer (smart contracts) +- 1 Backend engineer (servers, APIs) +- 1 Mobile specialist (iOS/Android) +- 1 DevOps engineer (CI/CD, infrastructure) + +### Creative Team +- 1-2 Pixel artists (8-bit assets) +- 1 UI/UX designer +- 1 Sound designer/composer +- 1 Animator (sprites, effects) + +### Business Team +- 1 Product manager +- 1 Community manager +- 1 Marketing specialist +- 1 Business development (partnerships) + +### External Resources +- Smart contract auditor +- Legal counsel (crypto/gaming) +- QA testing team +- Localization services + +**Estimated Budget:** +- Development: $300K-$500K (6 months) +- Marketing: $100K-$200K +- Infrastructure: $20K-$50K +- Legal/audit: $50K-$100K +- **Total:** $470K-$850K + +--- + +## 10. Conclusion + +This comprehensive plan transforms Fishy from an open-source project into a commercial-ready, modern gaming platform that combines: + +✅ **Traditional Gaming Excellence** - Polished gameplay, cross-platform support +✅ **Web3 Innovation** - NFT cosmetics, token rewards, decentralized tournaments +✅ **Mobile-First Approach** - Touch controls, PWA, native apps +✅ **Community-Driven** - Modding, UGC, creator economy +✅ **Sustainable Business** - Multiple revenue streams, live operations + +**Next Steps:** +1. Approve overall strategy +2. Prioritize features (MVP vs. future) +3. Assemble team +4. Begin Phase 1: Foundation + +**Timeline to Launch:** 6-8 months +**Revenue Potential:** $200K-$1.2M Year 1 +**Market Position:** Unique blend of retro gaming + modern web3 + +--- + +**Prepared for:** 8bit Games +**Contact:** [Development Team Lead] +**Last Updated:** 2025-11-10 diff --git a/PHASE1_IMPLEMENTATION.md b/PHASE1_IMPLEMENTATION.md new file mode 100644 index 0000000000..ed4ffa2c4b --- /dev/null +++ b/PHASE1_IMPLEMENTATION.md @@ -0,0 +1,547 @@ +# Phase 1 Implementation Plan - Foundation + +**Timeline:** Months 1-2 +**Status:** In Progress +**Started:** 2025-11-10 + +--- + +## Overview + +Phase 1 focuses on foundational infrastructure for mobile/web support: +1. Progressive Web App (PWA) capabilities +2. Mobile touch control system +3. Responsive UI framework +4. Performance optimizations for mobile + +## Objectives + +- ✅ Complete rebranding to Fishy (DONE) +- 🚧 PWA manifest and service worker (IN PROGRESS) +- 🔲 Mobile touch controls +- 🔲 Responsive design system +- 🔲 Mobile optimization + +--- + +## 1. PWA Enhancements + +### 1.1 Web App Manifest +**File:** `/wasm_resources/manifest.json` + +```json +{ + "name": "Fishy - Dive into 8-bit Chaos", + "short_name": "Fishy", + "description": "Tactical 2D shooter with 8-bit style", + "start_url": "/", + "display": "fullscreen", + "orientation": "landscape", + "background_color": "#000000", + "theme_color": "#8bcfcf", + "icons": [ + { + "src": "icons/icon-72x72.png", + "sizes": "72x72", + "type": "image/png", + "purpose": "any maskable" + }, + { + "src": "icons/icon-96x96.png", + "sizes": "96x96", + "type": "image/png", + "purpose": "any maskable" + }, + { + "src": "icons/icon-128x128.png", + "sizes": "128x128", + "type": "image/png", + "purpose": "any maskable" + }, + { + "src": "icons/icon-144x144.png", + "sizes": "144x144", + "type": "image/png", + "purpose": "any maskable" + }, + { + "src": "icons/icon-152x152.png", + "sizes": "152x152", + "type": "image/png", + "purpose": "any maskable" + }, + { + "src": "icons/icon-192x192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "any maskable" + }, + { + "src": "icons/icon-384x384.png", + "sizes": "384x384", + "type": "image/png", + "purpose": "any maskable" + }, + { + "src": "icons/icon-512x512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "any maskable" + } + ], + "categories": ["games", "action"], + "screenshots": [ + { + "src": "screenshots/gameplay-1.png", + "sizes": "1280x720", + "type": "image/png" + } + ] +} +``` + +**Tasks:** +- [x] Create manifest.json +- [ ] Generate PWA icons (72x72 to 512x512) +- [ ] Add screenshots for app stores +- [ ] Link manifest in index.html + +### 1.2 Service Worker +**File:** `/wasm_resources/service-worker.js` + +**Features:** +- Cache game assets for offline play +- Cache WASM binary +- Cache audio files +- Cache images/sprites +- Network-first strategy for game updates +- Cache-first for static assets + +**Cache Strategy:** +```javascript +// Cache name versioning +const CACHE_NAME = 'fishy-v1.0.0'; +const RUNTIME_CACHE = 'fishy-runtime-v1.0.0'; + +// Assets to cache immediately +const PRECACHE_ASSETS = [ + '/', + '/index.html', + '/fishy.js', + '/fishy_bg.wasm', + // Add critical assets +]; +``` + +**Tasks:** +- [x] Create service worker +- [ ] Implement caching strategies +- [ ] Add cache versioning +- [ ] Test offline functionality +- [ ] Add update notification UI + +### 1.3 Install Prompt +**File:** `/wasm_resources/install-prompt.js` + +**Features:** +- Detect if app is installable +- Show custom install button +- Handle beforeinstallprompt event +- Track installation analytics + +**Tasks:** +- [ ] Create install prompt UI +- [ ] Add install button to menu +- [ ] Implement prompt deferral +- [ ] Add "Add to Home Screen" instructions + +### 1.4 PWA Optimization +- [ ] Add meta tags for mobile browsers +- [ ] Implement splash screens +- [ ] Add iOS-specific meta tags +- [ ] Configure viewport for mobile +- [ ] Add preload hints for critical resources + +--- + +## 2. Mobile Touch Controls + +### 2.1 Architecture + +**New Module:** `src/input/touch.rs` + +```rust +// Touch input system for mobile devices +pub struct TouchControls { + pub virtual_joystick: VirtualJoystick, + pub action_buttons: ActionButtons, + pub enabled: bool, +} + +pub struct VirtualJoystick { + pub position: Vec2, + pub radius: f32, + pub dead_zone: f32, + pub current_touch: Option, +} + +pub struct ActionButtons { + pub jump: TouchButton, + pub shoot: TouchButton, + pub grab: TouchButton, + pub slide: TouchButton, +} + +pub struct TouchButton { + pub position: Vec2, + pub radius: f32, + pub pressed: bool, + pub touch_id: Option, +} +``` + +### 2.2 Virtual Joystick + +**Features:** +- Dynamic joystick (appears where user touches) +- Fixed position option +- Visual feedback (circle outline) +- Smooth interpolation +- Configurable dead zone + +**Implementation Tasks:** +- [ ] Create joystick component +- [ ] Render joystick overlay (egui) +- [ ] Handle touch events +- [ ] Map joystick to movement input +- [ ] Add visual customization + +### 2.3 Action Buttons + +**Layout:** +``` + [Jump] + +[Grab] [Shoot] + + [Slide] +``` + +**Features:** +- Large touch targets (64x64 minimum) +- Visual press feedback +- Customizable layout +- Haptic feedback (if available) + +**Implementation Tasks:** +- [ ] Create button components +- [ ] Design button sprites/UI +- [ ] Handle multi-touch +- [ ] Add button press animations +- [ ] Implement haptic feedback (WASM API) + +### 2.4 Touch Input Translation + +**File:** `src/input/touch_translation.rs` + +**Responsibilities:** +- Convert touch events to game inputs +- Handle multi-touch scenarios +- Prevent accidental touches +- Support gestures (swipe, pinch) + +**Tasks:** +- [ ] Implement touch-to-input mapping +- [ ] Add gesture recognition +- [ ] Handle edge cases (touches outside controls) +- [ ] Add touch input debugging overlay + +### 2.5 Mobile Detection + +**File:** `src/platform/mobile_detection.rs` + +```rust +pub fn is_mobile_device() -> bool { + // Check user agent + // Check touch support + // Check screen size +} + +pub fn is_touch_device() -> bool { + // Detect touch capability +} + +pub enum DeviceType { + Desktop, + Tablet, + Phone, +} + +pub fn detect_device_type() -> DeviceType { + // Based on screen size and capabilities +} +``` + +**Tasks:** +- [ ] Implement device detection +- [ ] Auto-enable touch controls on mobile +- [ ] Adjust UI based on device type +- [ ] Add manual toggle for touch controls + +--- + +## 3. Responsive UI System + +### 3.1 UI Scaling + +**Goals:** +- Support 320px to 4K resolutions +- Maintain aspect ratio +- Scale UI elements appropriately +- Readable text on all devices + +**Implementation:** +```rust +pub struct ResponsiveUI { + pub base_width: f32, + pub base_height: f32, + pub scale_factor: f32, + pub device_type: DeviceType, +} + +impl ResponsiveUI { + pub fn calculate_scale(&mut self, window_size: Vec2) { + // Calculate appropriate scale factor + } + + pub fn scaled_font_size(&self, base_size: f32) -> f32 { + base_size * self.scale_factor + } +} +``` + +**Tasks:** +- [ ] Create responsive UI component +- [ ] Update menu systems with scaling +- [ ] Adjust HUD for mobile +- [ ] Test on various screen sizes +- [ ] Add safe area support (notches) + +### 3.2 Adaptive Layouts + +**Features:** +- Vertical layout for portrait mode +- Horizontal layout for landscape +- Compact mode for small screens +- Full mode for desktop + +**Tasks:** +- [ ] Design mobile menu layouts +- [ ] Implement layout switching +- [ ] Update pause menu for mobile +- [ ] Simplify player select screen +- [ ] Optimize map select for touch + +### 3.3 Touch-Friendly UI + +**Requirements:** +- Minimum 44x44 point touch targets +- Adequate spacing between elements +- Visual feedback on press +- Swipe navigation support +- Large, readable fonts + +**Tasks:** +- [ ] Audit all UI elements +- [ ] Increase button sizes for mobile +- [ ] Add swipe gestures to menus +- [ ] Improve button press feedback +- [ ] Test with actual devices + +--- + +## 4. Performance Optimization + +### 4.1 Mobile Performance Targets + +- **Frame Rate:** 60 FPS on mid-range devices (2020+) +- **Memory:** <200MB RAM usage +- **Load Time:** <5 seconds to playable +- **Battery:** <10% per hour of gameplay + +### 4.2 WASM Optimizations + +**Build Configuration:** +```toml +[profile.release-wasm] +inherits = "release" +opt-level = "z" # Optimize for size +lto = true +codegen-units = 1 +``` + +**Tasks:** +- [ ] Create wasm-specific build profile +- [ ] Enable wasm-opt in build +- [ ] Analyze WASM binary size +- [ ] Remove unused code (tree shaking) +- [ ] Compress WASM with Brotli + +### 4.3 Asset Optimization + +**Strategies:** +- Compress textures (WebP, BC7) +- Downscale sprites for mobile +- Lazy load non-essential assets +- Use texture atlases efficiently +- Stream audio instead of loading all + +**Tasks:** +- [ ] Create mobile asset variants +- [ ] Implement progressive loading +- [ ] Optimize audio files (OGG bitrate) +- [ ] Compress texture atlases +- [ ] Add loading progress indicator + +### 4.4 Rendering Optimization + +**Techniques:** +- GPU instancing for sprites +- Frustum culling +- Level of detail (LOD) for effects +- Batch draw calls +- Limit particle counts + +**Tasks:** +- [ ] Profile rendering performance +- [ ] Implement sprite batching +- [ ] Add quality settings +- [ ] Create mobile preset (lower quality) +- [ ] Test on low-end devices + +--- + +## 5. Testing & Validation + +### 5.1 Device Testing Matrix + +**Phones:** +- iPhone 12 Mini (iOS 17) - Small screen +- iPhone 14 Pro (iOS 17) - Notch handling +- Samsung Galaxy S21 (Android 13) +- Google Pixel 6 (Android 14) +- Budget device: ~2019 model + +**Tablets:** +- iPad Air (iOS 17) +- Samsung Galaxy Tab S7 (Android 13) + +**Browsers:** +- Chrome (Android/Desktop) +- Safari (iOS) +- Firefox (Android/Desktop) +- Edge (Android/Desktop) + +### 5.2 Test Scenarios + +- [ ] Install as PWA +- [ ] Offline gameplay +- [ ] Touch controls responsiveness +- [ ] UI scaling on different sizes +- [ ] Performance under load (4 players) +- [ ] Battery drain +- [ ] Audio playback +- [ ] Orientation changes +- [ ] App switching (background/foreground) + +### 5.3 Metrics to Track + +- [ ] Install conversion rate +- [ ] Session length on mobile +- [ ] Touch control usability +- [ ] Frame rate statistics +- [ ] Load time by device +- [ ] Crash rate +- [ ] User feedback + +--- + +## 6. Documentation + +### 6.1 Developer Docs + +**Files to Create:** +- `docs/mobile-development.md` - Mobile dev guide +- `docs/pwa-setup.md` - PWA configuration +- `docs/touch-controls.md` - Touch input system +- `docs/responsive-ui.md` - UI scaling guide + +### 6.2 User Docs + +**Content:** +- How to install PWA +- Touch controls tutorial +- Mobile performance tips +- Troubleshooting guide + +--- + +## 7. Implementation Timeline + +### Week 1-2: PWA Foundation +- [x] Create PWA manifest +- [x] Set up service worker +- [ ] Generate app icons +- [ ] Test installation flow +- [ ] Add install prompts + +### Week 3-4: Touch Controls +- [ ] Design touch UI mockups +- [ ] Implement virtual joystick +- [ ] Create action buttons +- [ ] Test multi-touch handling +- [ ] Add visual feedback + +### Week 5-6: Responsive UI +- [ ] Implement UI scaling system +- [ ] Update all menu screens +- [ ] Test on multiple devices +- [ ] Optimize layouts +- [ ] Add orientation support + +### Week 7-8: Optimization & Testing +- [ ] Profile performance +- [ ] Optimize assets for mobile +- [ ] Test on real devices +- [ ] Fix bugs and issues +- [ ] Document everything + +--- + +## 8. Success Criteria + +Phase 1 is complete when: + +- ✅ PWA installs on iOS and Android +- ✅ Game works offline after first load +- ✅ Touch controls are responsive and intuitive +- ✅ UI scales correctly on 320px to 4K screens +- ✅ Maintains 60 FPS on mid-range devices (2020+) +- ✅ Loads in under 5 seconds on 4G connection +- ✅ All core gameplay features work on mobile +- ✅ Documentation is complete +- ✅ User testing yields positive feedback + +--- + +## Next Steps After Phase 1 + +Once foundation is complete, we'll move to: +- **Phase 2:** Web3 integration (smart contracts, wallets) +- **Phase 3:** Native mobile apps (iOS/Android) +- **Phase 4:** Monetization (battle pass, store) + +--- + +**Last Updated:** 2025-11-10 +**Owner:** 8bit Games Development Team diff --git a/README.md b/README.md index 2f99008d39..e81205b99d 100644 --- a/README.md +++ b/README.md @@ -1,90 +1,229 @@ -# Fish Folk: Jumpy +# Fishy -[![Build Status](https://img.shields.io/github/actions/workflow/status/fishfolk/jumpy/ci.yml?logo=github&labelColor=1e1c24&color=8bcfcf)](https://github.com/fishfolk/jumpy/actions) [![Documentation](https://img.shields.io/badge/documentation-fishfolk.github.io-green.svg?labelColor=1e1c24&color=f3ee7a)](https://fishfolk.github.io/jumpy/book) [![License](https://img.shields.io/badge/License-MIT%20or%20Apache%202-green.svg?label=license&labelColor=1e1c24&color=34925e)](./LICENSE) [![Discord](https://img.shields.io/badge/chat-on%20discord-green.svg?logo=discord&logoColor=fff&labelColor=1e1c24&color=8d5b3f)](https://discord.gg/4smxjcheE5) +[![Build Status](https://img.shields.io/github/actions/workflow/status/8bit-games/fishy/ci.yml?logo=github&labelColor=1e1c24&color=8bcfcf)](https://github.com/8bit-games/fishy/actions) [![Documentation](https://img.shields.io/badge/documentation-8bitgames.io-green.svg?labelColor=1e1c24&color=f3ee7a)](https://8bitgames.io/fishy) [![License](https://img.shields.io/badge/License-MIT%20or%20Apache%202-green.svg?label=license&labelColor=1e1c24&color=34925e)](./LICENSE) [![Discord](https://img.shields.io/badge/chat-on%20discord-green.svg?logo=discord&logoColor=fff&labelColor=1e1c24&color=8d5b3f)](https://discord.gg/fishy) -![Fish Folk: Jumpy Preview](https://user-images.githubusercontent.com/24392180/151969075-399e9fea-e2de-4340-96a4-0a0e5b79c281.gif) +![Fishy - Dive into 8-bit Chaos](https://user-images.githubusercontent.com/24392180/151969075-399e9fea-e2de-4340-96a4-0a0e5b79c281.gif) -👉 **[Live on Kickstarter!](https://www.kickstarter.com/projects/erlendsh/fish-folk)** 👈 +**Dive into 8-bit Chaos!** ## Introduction -Fish Folk: Jumpy is a tactical 2D shooter, played by up to 4 players online or on a shared screen. Aim either left or right; the rest is up to clever movement and positioning in this fish-on-fish brawler! For more information about our origin story (Duck Game et.al.) and big-picture plans, see our [design document](https://www.notion.so/erlendsh/Fish-Fight-1647ed74217e4e38a59bd28f4f5bc81a). +**Fishy** is a tactical 2D shooter, played by up to 4 players online or on a shared screen. Aim either left or right; the rest is up to clever movement and positioning in this fish-on-fish brawler! -## Web Demo +Built with modern Rust and Bevy, Fishy combines classic 8-bit aesthetics with cutting-edge technology including Web3 integration, cross-platform multiplayer, and full mobile support. -Jumpy runs in the browser! You can play [web demo][web_demo] to try out the game, without needing to install anything on your computer. +## Play Now -We recommend using the Chrome browser or other derivatives for best performance, or if you have issues with other browsers. +### Web Demo (Play Instantly!) -[web_demo]: https://fishfolk.github.io/jumpy/player/latest/ +Fishy runs in your browser! Try the [web demo](https://8bitgames.io/fishy/play) to play immediately without installing anything. -### Key Features (WIP) +We recommend Chrome or other Chromium-based browsers for best performance. -- 2 to 4 players in either Local Multiplayer or Online Play -- Easy to pick up, emphasizing strategy over twitch reaction -- Customize characters with hats, saved to your cross-platform profile -- Create & explore user-made weapons, levels, audio and other scripted extensions -- Smart level creation tools -- Tournaments & matchmaking built in +### Download & Install -## Community +**Desktop:** +- **Steam**: [Coming Soon](https://store.steampowered.com) +- **Direct Download**: [Latest Release](https://github.com/8bit-games/fishy/releases) -### Contributing +**Mobile:** +- **iOS**: [App Store - Coming Soon](https://apps.apple.com) +- **Android**: [Google Play - Coming Soon](https://play.google.com) + +**Web3:** +- Connect your wallet to unlock NFT cosmetics and earn $FISHY tokens! + +## Key Features + +### Gameplay +- **2-4 Player Multiplayer** - Local split-screen or online play +- **Cross-Platform** - Play on desktop, mobile, or web with crossplay +- **Easy to Learn, Hard to Master** - Emphasizes strategy over twitch reactions +- **Tactical Combat** - Smart positioning and movement are key to victory + +### Customization +- **NFT Cosmetics** - Collect and trade unique hats, skins, and emotes +- **$FISHY Rewards** - Earn tokens through gameplay +- **Battle Pass** - Seasonal progression with exclusive rewards +- **Profile NFTs** - Your account as a tradeable asset + +### Content +- **14+ Maps** - Diverse underwater environments +- **20+ Weapons** - From muskets to machine guns +- **User-Generated Content** - Create custom maps, weapons, and mods +- **Lua Scripting** - Full modding support + +### Community +- **Tournaments** - Compete for $FISHY prizes +- **Leaderboards** - Global and friend rankings +- **Creator Economy** - Earn from your creations +- **Discord Integration** - Active community + +## Technology + +**Built With:** +- **Rust** - Memory-safe, high-performance +- **Bevy Engine** - Modern ECS game engine +- **Bones Framework** - Custom networking & asset system +- **Rapier2D** - Deterministic physics for rollback netcode +- **Web3** - Polygon blockchain for NFTs and tokens -Anyone involved in the Fish Folk community must follow our [code of conduct](https://github.com/fishfolk/jumpy/blob/main/CODE_OF_CONDUCT.md). +**Platforms:** +- Desktop: Windows, macOS, Linux +- Mobile: iOS, Android (native apps) +- Web: WASM/WebGL (PWA support) -If you'd like to make something for Fish Folk, check out our [help-wanted](https://github.com/fishfolk/jumpy/labels/help%20wanted) issues or just ask us on [Discord](https://discord.gg/4smxjcheE5). We'll soon post an updated roadmap for the next month or two of work ahead. +## Web3 Features -Before committing and opening a PR, please run the following commands and follow their instructions: +### NFT Cosmetics +Collect rare and legendary cosmetics as NFTs: +- Hats, skins, emotes, weapon skins +- Trade on OpenSea and in-game marketplace +- Proven ownership and scarcity +- Community creations with royalties -1. `cargo clippy -- -W clippy::correctness -D warnings` -2. `cargo fmt` +### $FISHY Token +Earn and spend the official Fishy token: +- Earn through matches, quests, and tournaments +- Spend on cosmetics and tournament entries +- Stake for additional rewards +- Decentralized prize pools -### Development Build Profiles +### Blockchain Benefits +- True ownership of in-game items +- Cross-game asset portability +- Player-driven economy +- Transparent tournament results -By default, Jumpy will build without optimizations for the `jumpy_core` and `jumpy` crates. This helps reduce re-compile times at the expense of some runtime performance. If you need increased runtime performance during development, you can build with the `--profile dev-optimized` option, to optimize all of the crates: +**Web3 is Optional!** You can enjoy Fishy completely free without crypto. + +## Getting Started + +### Playing + +1. **Web**: Visit [8bitgames.io/fishy/play](https://8bitgames.io/fishy/play) +2. **Desktop**: Download from [releases](https://github.com/8bit-games/fishy/releases) and run the executable +3. **Mobile**: Download from App Store or Google Play + +### Building from Source + +1. Install Rust: [rustup.rs](https://rustup.rs/) +2. Clone: `git clone https://github.com/8bit-games/fishy.git` +3. Build: `cd fishy && cargo run` + +For detailed build instructions, see [BUILDING.md](./docs/BUILDING.md) + +### Development ```bash -cargo r --profile dev-optimized +# Run with optimizations for better performance +cargo run --profile dev-optimized + +# Build for web +just build-web + +# Run web locally +just run-web + +# Run tests +cargo test + +# Format code +cargo fmt + +# Lint +cargo clippy -- -W clippy::correctness -D warnings ``` -### Learning Materials +## Community -#### Rust +### Contributing -- [Rusty Engine Tutorial](https://cleancut.github.io/rusty_engine/) -- [Rust sokoban](https://sokoban.iolivia.me/) -- +We welcome contributions! Please see our [CONTRIBUTING.md](./docs/CONTRIBUTING.md) for guidelines. -#### Bevy +All contributors must follow our [Code of Conduct](./CODE_OF_CONDUCT.md). -- [Unofficial Bevy Cheat Book](https://bevy-cheatbook.github.io/) +### Get Involved -## Download & play +- **Discord**: [Join our server](https://discord.gg/fishy) +- **Twitter**: [@FishyGame](https://twitter.com/fishygame) +- **GitHub**: [Open issues](https://github.com/8bit-games/fishy/issues) +- **Wiki**: [Community wiki](https://github.com/8bit-games/fishy/wiki) -1. Download the latest version from the [releases](https://github.com/fishfolk/jumpy/releases) page. -2. Extract the archive and run the executable. (e.g. `./jumpy` or `jumpy.exe`) +### Content Creation -### Launcher +Create and share your content: +- **Maps**: Use the in-game editor +- **Mods**: Lua scripting support +- **Art**: Contribute pixel art +- **Guides**: Help new players -[A cross-platform launcher](https://github.com/spicylobstergames/SpicyLauncher) is also available for downloading and launching the game easily. +Earn $FISHY tokens for featured community content! -### Distro Packages +## Roadmap -#### Arch Linux +### Current: Season 1 (Launch) +- ✅ Core gameplay +- ✅ 14 maps, 20+ weapons +- ✅ Cross-platform multiplayer +- ✅ Web3 integration +- 🚧 Mobile apps (iOS/Android) +- 🚧 Battle Pass system -```sh -pacman -S jumpy -``` +### Season 2 (Q2 2026) +- New fish characters +- Additional maps and weapons +- Tournament system v2 +- Enhanced modding tools -## Building +### Season 3+ (2026) +- Campaign mode +- Clan system +- Esports features +- Platform expansions -1. Install Rust with [rustup.rs](https://rustup.rs/) -2. Clone this repository: `git clone https://github.com/fishfolk/jumpy.git` -3. `cd jumpy` -4. `cargo run` +See [MODERNIZATION_PLAN.md](./MODERNIZATION_PLAN.md) for full details. + +## Monetization + +Fishy is **free-to-play** with optional purchases: + +- **Battle Pass**: $9.99/season (3 months) +- **Cosmetics**: $1.99-$9.99 +- **NFTs**: Variable (marketplace) +- **Tournament Entry**: $5-$50 (prize pools) + +All gameplay content is free. Purchases are cosmetic only. ## Credits -- [Fish Folk: Jumpy Credits](./CREDITS.md) +### 8bit Games Team +- [Team roster to be added] + +### Original Project +Based on Fish Folk: Jumpy by the Fish Fight Game & Spicy Lobster Developers. +See [CREDITS.md](./CREDITS.md) for full attribution. + +### Assets - Input Icons: [Kadith's Icons](https://kadith.itch.io/kadiths-free-icons) by Kadith +- Music & Sound: Original compositions +- Art: Community contributors + +## License + +Dual-licensed under MIT OR Apache-2.0. See [LICENSE](./LICENSE) for details. + +Smart contracts and Web3 components may have additional licenses. + +## Support + +- **Bug Reports**: [GitHub Issues](https://github.com/8bit-games/fishy/issues) +- **Feature Requests**: [Discussions](https://github.com/8bit-games/fishy/discussions) +- **Email**: support@8bitgames.io +- **Discord**: Technical support channel + +--- + +**Made with 🐟 by 8bit Games** + +[Website](https://8bitgames.io/fishy) | [Play Now](https://8bitgames.io/fishy/play) | [Discord](https://discord.gg/fishy) | [Twitter](https://twitter.com/fishygame) diff --git a/assets/locales/en-US/branding.ftl b/assets/locales/en-US/branding.ftl index 2289d25dda..33455776c9 100644 --- a/assets/locales/en-US/branding.ftl +++ b/assets/locales/en-US/branding.ftl @@ -1,2 +1,2 @@ -title = Fish Folk -subtitle = Jumpy +title = Fishy +subtitle = Dive into 8-bit Chaos diff --git a/contrib/fishy.desktop b/contrib/fishy.desktop new file mode 100644 index 0000000000..7343918d97 --- /dev/null +++ b/contrib/fishy.desktop @@ -0,0 +1,7 @@ +[Desktop Entry] +Name=Fishy +Comment=Dive into 8-bit Chaos - Tactical 2D shooter +Exec=fishy +Terminal=false +Type=Application +Categories=Game;ActionGame;Shooter; diff --git a/docs/mobile-touch-controls.md b/docs/mobile-touch-controls.md new file mode 100644 index 0000000000..079e779af1 --- /dev/null +++ b/docs/mobile-touch-controls.md @@ -0,0 +1,551 @@ +# Mobile Touch Controls Design + +**Version:** 1.0 +**Status:** Design Phase +**Last Updated:** 2025-11-10 + +--- + +## Overview + +This document outlines the design and implementation of mobile touch controls for Fishy, enabling intuitive touch-based gameplay on mobile devices. + +## Goals + +1. **Intuitive**: Easy to learn for mobile players +2. **Responsive**: Low latency, feels native +3. **Customizable**: Adjustable size, position, opacity +4. **Platform-Agnostic**: Works on iOS, Android, and web +5. **Optional**: Can be toggled off for keyboard/gamepad users + +## Architecture + +### Module Structure + +``` +src/input/ +├── mod.rs (existing - update) +├── touch/ +│ ├── mod.rs (new - module exports) +│ ├── controls.rs (new - touch control components) +│ ├── joystick.rs (new - virtual joystick) +│ ├── buttons.rs (new - action buttons) +│ ├── detection.rs (new - touch event handling) +│ └── config.rs (new - touch settings) +``` + +### Data Structures + +#### TouchControls (Main Component) + +```rust +#[derive(HasSchema, Clone, Debug, Default)] +pub struct TouchControls { + pub enabled: bool, + pub joystick: VirtualJoystick, + pub buttons: ActionButtons, + pub config: TouchConfig, +} +``` + +#### VirtualJoystick + +```rust +#[derive(HasSchema, Clone, Debug)] +pub struct VirtualJoystick { + // Type: Dynamic or Fixed + pub joystick_type: JoystickType, + + // Position on screen (percentage) + pub base_position: Vec2, // 0.0-1.0 range + pub current_position: Vec2, + + // Size and behavior + pub outer_radius: f32, // Dead zone boundary + pub inner_radius: f32, // Visual knob size + pub dead_zone: f32, // Input threshold + + // State + pub is_active: bool, + pub touch_id: Option, + pub direction: Vec2, // Normalized direction + pub magnitude: f32, // 0.0-1.0 +} + +#[derive(HasSchema, Clone, Copy, Debug)] +pub enum JoystickType { + Dynamic, // Appears where user touches + Fixed, // Always at base_position +} +``` + +#### ActionButtons + +```rust +#[derive(HasSchema, Clone, Debug)] +pub struct ActionButtons { + pub jump: TouchButton, + pub shoot: TouchButton, + pub grab: TouchButton, + pub slide: TouchButton, + + // Layout configuration + pub layout: ButtonLayout, +} + +#[derive(HasSchema, Clone, Debug)] +pub struct TouchButton { + // Position on screen (percentage) + pub position: Vec2, // 0.0-1.0 range + + // Size + pub radius: f32, + + // State + pub is_pressed: bool, + pub touch_id: Option, + + // Visual + pub opacity: f32, + pub press_opacity: f32, +} + +#[derive(HasSchema, Clone, Copy, Debug)] +pub enum ButtonLayout { + RightHanded, // Buttons on right, joystick on left + LeftHanded, // Buttons on left, joystick on right + Custom, // User-defined positions +} +``` + +#### TouchConfig + +```rust +#[derive(HasSchema, Clone, Debug)] +pub struct TouchConfig { + // Visual settings + pub opacity: f32, // 0.0-1.0 + pub size_scale: f32, // 0.5-2.0 + pub haptic_feedback: bool, + + // Behavior + pub auto_hide: bool, // Hide when no touch + pub show_on_mobile: bool, // Auto-detect mobile + + // Customization + pub button_layout: ButtonLayout, + pub joystick_type: JoystickType, +} +``` + +## Default Layout + +### Landscape Orientation (Primary) + +``` +┌──────────────────────────────────────────────┐ +│ │ +│ │ +│ (Jump)│ +│ ╱╲ │ +│ ╱ ╲ (Joystick) (Grab) (Shoot)│ +│ ╲ ╱ │ +│ ╲╱ (Slide)│ +│ │ +│ │ +└──────────────────────────────────────────────┘ + +Joystick: +- Position: 15% from left, 70% from top +- Size: 80px outer, 40px inner + +Buttons: +- Shoot: 85% from left, 65% from top +- Jump: 85% from left, 35% from top +- Grab: 75% from left, 65% from top +- Slide: 85% from left, 85% from top +- Size: 64px radius each +``` + +### Portrait Orientation (Future) + +``` +┌────────────────────┐ +│ │ +│ │ +│ │ +│ (Gameplay) │ +│ │ +│ │ +├────────────────────┤ +│ ╱╲ (Jump) │ +│ ╱ ╲ (Shoot)│ +│ ╲ ╱ (Grab) │ +│ ╲╱ (Slide)│ +└────────────────────┘ + +Controls at bottom 30% of screen +``` + +## Input Translation + +### Joystick to Movement + +```rust +fn joystick_to_movement(joystick: &VirtualJoystick) -> PlayerInput { + if !joystick.is_active || joystick.magnitude < joystick.dead_zone { + return PlayerInput::default(); + } + + let dir = joystick.direction; + + PlayerInput { + up: dir.y > 0.5, + down: dir.y < -0.5, + left: dir.x < -0.5, + right: dir.x > 0.5, + ..Default::default() + } +} +``` + +### Buttons to Actions + +```rust +fn buttons_to_actions(buttons: &ActionButtons) -> PlayerInput { + PlayerInput { + jump: buttons.jump.is_pressed, + shoot: buttons.shoot.is_pressed, + grab: buttons.grab.is_pressed, + slide: buttons.slide.is_pressed, + ..Default::default() + } +} +``` + +## Rendering + +### Using egui for Overlay + +Touch controls will be rendered using egui in a dedicated layer above the game canvas. + +```rust +fn render_touch_controls( + ui: &mut egui::Ui, + controls: &TouchControls, + screen_size: Vec2, +) { + if !controls.enabled { + return; + } + + // Render joystick + render_joystick(ui, &controls.joystick, screen_size); + + // Render buttons + render_buttons(ui, &controls.buttons, screen_size); +} + +fn render_joystick( + ui: &mut egui::Ui, + joystick: &VirtualJoystick, + screen_size: Vec2, +) { + if !joystick.is_active && joystick.joystick_type == JoystickType::Dynamic { + return; // Don't show dynamic joystick when inactive + } + + let center = joystick.base_position * screen_size; + + // Outer circle (boundary) + ui.painter().circle_stroke( + center.into(), + joystick.outer_radius, + egui::Stroke::new(2.0, egui::Color32::from_rgba_premultiplied(255, 255, 255, 80)), + ); + + // Inner circle (knob) + let knob_pos = if joystick.is_active { + center + joystick.direction * joystick.magnitude * joystick.outer_radius + } else { + center + }; + + ui.painter().circle_filled( + knob_pos.into(), + joystick.inner_radius, + egui::Color32::from_rgba_premultiplied(255, 255, 255, 150), + ); +} + +fn render_button( + ui: &mut egui::Ui, + button: &TouchButton, + label: &str, + screen_size: Vec2, +) { + let pos = button.position * screen_size; + let opacity = if button.is_pressed { + button.press_opacity + } else { + button.opacity + }; + + // Button circle + let color = if button.is_pressed { + egui::Color32::from_rgba_premultiplied(200, 200, 255, (opacity * 255.0) as u8) + } else { + egui::Color32::from_rgba_premultiplied(255, 255, 255, (opacity * 255.0) as u8) + }; + + ui.painter().circle_filled(pos.into(), button.radius, color); + + // Button label + ui.painter().text( + pos.into(), + egui::Align2::CENTER_CENTER, + label, + egui::FontId::proportional(18.0), + egui::Color32::BLACK, + ); +} +``` + +## Touch Event Handling + +### WASM Touch Events + +```rust +#[cfg(target_arch = "wasm32")] +pub fn setup_touch_listeners() { + use wasm_bindgen::prelude::*; + use wasm_bindgen::JsCast; + + let window = web_sys::window().expect("no window"); + let document = window.document().expect("no document"); + + // Touch start + let touch_start = Closure::wrap(Box::new(move |event: web_sys::TouchEvent| { + event.prevent_default(); + handle_touch_start(&event); + }) as Box); + + document + .add_event_listener_with_callback("touchstart", touch_start.as_ref().unchecked_ref()) + .unwrap(); + touch_start.forget(); + + // Touch move + let touch_move = Closure::wrap(Box::new(move |event: web_sys::TouchEvent| { + event.prevent_default(); + handle_touch_move(&event); + }) as Box); + + document + .add_event_listener_with_callback("touchmove", touch_move.as_ref().unchecked_ref()) + .unwrap(); + touch_move.forget(); + + // Touch end + let touch_end = Closure::wrap(Box::new(move |event: web_sys::TouchEvent| { + event.prevent_default(); + handle_touch_end(&event); + }) as Box); + + document + .add_event_listener_with_callback("touchend", touch_end.as_ref().unchecked_ref()) + .unwrap(); + touch_end.forget(); +} +``` + +### Touch State Management + +```rust +pub struct TouchState { + pub active_touches: HashMap, +} + +pub struct Touch { + pub id: u64, + pub start_pos: Vec2, + pub current_pos: Vec2, + pub claimed_by: Option, +} + +pub enum TouchTarget { + Joystick, + Button(ActionButton), + UI, + None, +} +``` + +## Mobile Detection + +```rust +#[cfg(target_arch = "wasm32")] +pub fn is_mobile_device() -> bool { + use wasm_bindgen::JsCast; + + let window = web_sys::window().expect("no window"); + let navigator = window.navigator(); + let user_agent = navigator.user_agent().unwrap_or_default().to_lowercase(); + + // Check user agent + let is_mobile_ua = user_agent.contains("mobile") || + user_agent.contains("android") || + user_agent.contains("iphone") || + user_agent.contains("ipad"); + + // Check touch support + let has_touch = window.navigator().max_touch_points() > 0; + + // Check screen size + let screen_width = window.inner_width().unwrap().as_f64().unwrap_or(1920.0); + let is_small_screen = screen_width < 768.0; + + is_mobile_ua || (has_touch && is_small_screen) +} + +#[cfg(not(target_arch = "wasm32"))] +pub fn is_mobile_device() -> bool { + false // Desktop builds don't support touch +} +``` + +## Integration Points + +### 1. Game Initialization + +```rust +// In src/main.rs or src/input/mod.rs +pub fn initialize_touch_controls(game: &mut Game) { + let is_mobile = is_mobile_device(); + + let touch_controls = TouchControls { + enabled: is_mobile, // Auto-enable on mobile + config: TouchConfig { + show_on_mobile: true, + opacity: 0.6, + ..Default::default() + }, + ..Default::default() + }; + + game.insert_resource(touch_controls); +} +``` + +### 2. Input System + +```rust +// Update the input collection system +pub fn collect_touch_input( + touch_controls: Res, + touch_state: Res, +) -> PlayerInput { + if !touch_controls.enabled { + return PlayerInput::default(); + } + + let movement = joystick_to_movement(&touch_controls.joystick); + let actions = buttons_to_actions(&touch_controls.buttons); + + // Merge inputs + movement.merge(actions) +} +``` + +### 3. Settings Menu + +```rust +// Add touch control settings +pub fn touch_settings_ui(ui: &mut egui::Ui, touch_controls: &mut TouchControls) { + ui.heading("Touch Controls"); + + ui.checkbox(&mut touch_controls.enabled, "Enable Touch Controls"); + + ui.add(egui::Slider::new(&mut touch_controls.config.opacity, 0.0..=1.0) + .text("Opacity")); + + ui.add(egui::Slider::new(&mut touch_controls.config.size_scale, 0.5..=2.0) + .text("Size")); + + ui.checkbox(&mut touch_controls.config.haptic_feedback, "Haptic Feedback"); + + egui::ComboBox::from_label("Layout") + .selected_text(format!("{:?}", touch_controls.config.button_layout)) + .show_ui(ui, |ui| { + ui.selectable_value(&mut touch_controls.config.button_layout, ButtonLayout::RightHanded, "Right-Handed"); + ui.selectable_value(&mut touch_controls.config.button_layout, ButtonLayout::LeftHanded, "Left-Handed"); + }); +} +``` + +## Testing Plan + +### Unit Tests + +- Joystick direction calculation +- Dead zone behavior +- Button hit detection +- Touch event routing + +### Integration Tests + +- Touch input to player movement +- Multi-touch handling +- Settings persistence +- Layout switching + +### Device Testing + +- iOS Safari +- Android Chrome +- Various screen sizes +- Portrait/landscape orientation + +## Performance Considerations + +- **Render Frequency**: Only render visible controls +- **Touch Polling**: Limit to 60 FPS max +- **Memory**: Minimal allocation during gameplay +- **Battery**: Avoid unnecessary redraws + +## Accessibility + +- **Size Options**: 50%-200% scaling +- **Opacity**: 0%-100% for visual preference +- **Haptics**: Optional vibration feedback +- **Alternative**: Full keyboard/gamepad support + +## Future Enhancements + +1. **Gesture Support** + - Swipe to switch weapons + - Pinch to zoom camera + - Double-tap for quick actions + +2. **Advanced Customization** + - Drag-to-reposition controls + - Custom button mapping + - Save/load layouts + +3. **Tutorials** + - First-time touch control tutorial + - Visual hints for new players + +4. **Analytics** + - Track control usage + - Optimize default positions + - A/B test layouts + +--- + +**Next Steps:** +1. Implement basic touch event system +2. Create virtual joystick component +3. Add action buttons +4. Integrate with existing input system +5. Test on mobile devices diff --git a/scripts/build-web.sh b/scripts/build-web.sh index 73098a6850..c32a9d930b 100755 --- a/scripts/build-web.sh +++ b/scripts/build-web.sh @@ -25,6 +25,26 @@ set -ex cargo build --target $target $release_arg rm -rf $dist_dir mkdir -p $dist_dir -wasm-bindgen --out-dir $dist_dir --target web --no-typescript $target_dir/$target/$build_kind/jumpy.wasm +wasm-bindgen --out-dir $dist_dir --target web --no-typescript $target_dir/$target/$build_kind/fishy.wasm + +# Copy HTML and PWA resources cp wasm_resources/index.html $dist_dir/index.html +cp wasm_resources/manifest.json $dist_dir/manifest.json +cp wasm_resources/service-worker.js $dist_dir/service-worker.js +cp wasm_resources/install-prompt.js $dist_dir/install-prompt.js +cp wasm_resources/pwa-styles.css $dist_dir/pwa-styles.css + +# Copy icons if they exist (create placeholder icons if needed) +if [ -d "wasm_resources/icons" ]; then + cp -r wasm_resources/icons $dist_dir/icons +else + echo "Note: PWA icons not found. Create icons in wasm_resources/icons/" +fi + +# Copy screenshots if they exist +if [ -d "wasm_resources/screenshots" ]; then + cp -r wasm_resources/screenshots $dist_dir/screenshots +fi + +# Copy game assets cp -r assets $dist_dir diff --git a/wasm_resources/icons/README.md b/wasm_resources/icons/README.md new file mode 100644 index 0000000000..f4eadac693 --- /dev/null +++ b/wasm_resources/icons/README.md @@ -0,0 +1,59 @@ +# PWA Icons + +This directory should contain PWA icons for mobile installation. + +## Required Icon Sizes + +Generate the following icon sizes from your base Fishy logo: + +- icon-16x16.png +- icon-32x32.png +- icon-72x72.png +- icon-96x96.png +- icon-120x120.png (iOS) +- icon-128x128.png +- icon-144x144.png +- icon-152x152.png (iOS) +- icon-180x180.png (iOS) +- icon-192x192.png +- icon-384x384.png +- icon-512x512.png + +## Icon Design Guidelines + +- **Style**: 8-bit pixel art matching the Fishy brand +- **Background**: Transparent or ocean blue (#8bcfcf) +- **Content**: Simple fish character or "FISHY" text in pixel font +- **Safe Area**: Leave 10% padding around edges for iOS masking +- **Format**: PNG with transparency + +## Tools for Icon Generation + +1. **Online Tools**: + - https://realfavicongenerator.net/ + - https://www.pwa-manifest-generator.com/ + +2. **Command Line**: + ```bash + # Using ImageMagick + convert logo.png -resize 192x192 icon-192x192.png + convert logo.png -resize 512x512 icon-512x512.png + ``` + +3. **Design Software**: + - Aseprite (pixel art) + - GIMP + - Photoshop + +## Temporary Placeholder + +Until custom icons are created, you can use one of the game's existing fish sprites +from `/assets/player/skins/` as a temporary placeholder. + +## Testing + +After adding icons: +1. Build the web version: `just build-web` +2. Test manifest: Chrome DevTools > Application > Manifest +3. Verify icons appear in install prompt +4. Test on actual mobile device diff --git a/wasm_resources/index.html b/wasm_resources/index.html index 2b2148a974..8dfecb212b 100644 --- a/wasm_resources/index.html +++ b/wasm_resources/index.html @@ -1,6 +1,31 @@ - + + + + + Fishy - Dive into 8-bit Chaos + + + + + + + + + + + + + + + + + + + + +