From 621e632dce620028e0685728f24ee64a5a209c48 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 10 Nov 2025 04:43:32 +0000 Subject: [PATCH 1/2] feat: Rebrand to Fishy and add comprehensive modernization plan This commit transforms the project from "Fish Folk: Jumpy" to "Fishy" and includes a complete modernization roadmap for mobile/web and web3 integration. ## Rebranding Changes - **Package**: Renamed from "jumpy" to "fishy" in Cargo.toml (v1.0.0) - **Authors**: Updated to "8bit Games" - **Description**: "Dive into 8-bit Chaos - A tactical 2D shooter" - **Branding**: Updated title and subtitle in localization files - **Build**: Updated web build scripts and WASM references - **Desktop**: Added new fishy.desktop file for Linux - **Arcade**: Updated Arcadefile with new branding ## New Documentation Added MODERNIZATION_PLAN.md with comprehensive strategy: ### Mobile/Web Modernization - Native iOS/Android support with touch controls - Progressive Web App (PWA) enhancements - Cross-platform WebRTC networking - Responsive design system - Performance optimizations for mobile ### Web3 Integration - NFT cosmetics system (ERC-1155) - $FISHY token economy (ERC-20) - Decentralized tournaments and prize pools - Wallet integration (MetaMask, WalletConnect) - Polygon blockchain deployment ### Commercial Readiness - Free-to-play monetization model - Battle pass system - In-game cosmetic store - Multi-platform distribution (Steam, Epic, App Stores) - Backend infrastructure planning - Live operations strategy ### Timeline & Budget - 6-8 month implementation plan - Phased rollout approach - Team and resource requirements - Revenue projections: $200K-$1.2M Year 1 ## Attribution Original project credits preserved in CREDITS.md with proper attribution to Fish Folk: Jumpy developers and community. ## Technical Notes All core functionality remains intact. This is primarily a rebranding and planning commit. Implementation of mobile/web3 features will follow in subsequent phases. Breaking Changes: - Binary name changed from "jumpy" to "fishy" - Package name changed (affects build scripts) - WASM output now generates fishy.js instead of jumpy.js --- Arcadefile | 6 +- CREDITS.md | 8 + Cargo.toml | 10 +- MODERNIZATION_PLAN.md | 694 ++++++++++++++++++++++++++++++ README.md | 237 +++++++--- assets/locales/en-US/branding.ftl | 4 +- contrib/fishy.desktop | 7 + scripts/build-web.sh | 2 +- wasm_resources/index.html | 2 +- 9 files changed, 909 insertions(+), 61 deletions(-) create mode 100644 MODERNIZATION_PLAN.md create mode 100644 contrib/fishy.desktop 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/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/scripts/build-web.sh b/scripts/build-web.sh index 73098a6850..3dd71260c9 100755 --- a/scripts/build-web.sh +++ b/scripts/build-web.sh @@ -25,6 +25,6 @@ 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 cp wasm_resources/index.html $dist_dir/index.html cp -r assets $dist_dir diff --git a/wasm_resources/index.html b/wasm_resources/index.html index 2b2148a974..ef5005f7f9 100644 --- a/wasm_resources/index.html +++ b/wasm_resources/index.html @@ -131,7 +131,7 @@ })(); + + + diff --git a/wasm_resources/install-prompt.js b/wasm_resources/install-prompt.js new file mode 100644 index 0000000000..09dfcddfeb --- /dev/null +++ b/wasm_resources/install-prompt.js @@ -0,0 +1,260 @@ +// Fishy PWA Install Prompt +// Handles "Add to Home Screen" prompts and installation + +(function() { + 'use strict'; + + let deferredPrompt = null; + let isInstalled = false; + + // Check if already installed + if (window.matchMedia('(display-mode: standalone)').matches || + window.navigator.standalone === true) { + isInstalled = true; + console.log('[Fishy Install] App is already installed'); + } + + // Listen for beforeinstallprompt event + window.addEventListener('beforeinstallprompt', (e) => { + console.log('[Fishy Install] Install prompt available'); + + // Prevent the mini-infobar from appearing on mobile + e.preventDefault(); + + // Stash the event so it can be triggered later + deferredPrompt = e; + + // Show custom install button + showInstallUI(); + }); + + // Listen for app installed event + window.addEventListener('appinstalled', (e) => { + console.log('[Fishy Install] App installed successfully'); + isInstalled = true; + hideInstallUI(); + + // Track installation (analytics) + trackInstallation(); + }); + + function showInstallUI() { + // Create install button if it doesn't exist + let installButton = document.getElementById('install-button'); + + if (!installButton && !isInstalled) { + installButton = createInstallButton(); + document.body.appendChild(installButton); + } + + if (installButton) { + installButton.style.display = 'block'; + } + } + + function hideInstallUI() { + const installButton = document.getElementById('install-button'); + if (installButton) { + installButton.style.display = 'none'; + } + } + + function createInstallButton() { + const button = document.createElement('button'); + button.id = 'install-button'; + button.className = 'pwa-install-button'; + button.innerHTML = ` + + + + + + Install Fishy + `; + + button.addEventListener('click', handleInstallClick); + + return button; + } + + async function handleInstallClick() { + if (!deferredPrompt) { + console.log('[Fishy Install] No install prompt available'); + showManualInstructions(); + return; + } + + // Show the install prompt + deferredPrompt.prompt(); + + // Wait for the user to respond to the prompt + const { outcome } = await deferredPrompt.userChoice; + + console.log('[Fishy Install] User choice:', outcome); + + if (outcome === 'accepted') { + console.log('[Fishy Install] User accepted installation'); + } else { + console.log('[Fishy Install] User dismissed installation'); + } + + // Clear the deferred prompt + deferredPrompt = null; + + // Hide the install button + hideInstallUI(); + } + + function showManualInstructions() { + // Show platform-specific instructions + const platform = detectPlatform(); + let instructions = ''; + + switch (platform) { + case 'ios': + instructions = ` +
+

Install Fishy on iOS

+
    +
  1. Tap the Share button
  2. +
  3. Scroll down and tap "Add to Home Screen"
  4. +
  5. Tap "Add" to confirm
  6. +
+
+ `; + break; + + case 'android': + instructions = ` +
+

Install Fishy on Android

+
    +
  1. Tap the menu button (⋮)
  2. +
  3. Tap "Add to Home screen" or "Install app"
  4. +
  5. Follow the prompts to install
  6. +
+
+ `; + break; + + default: + instructions = ` +
+

Install Fishy

+

Look for the install icon in your browser's address bar or menu.

+
+ `; + } + + showModal(instructions); + } + + function detectPlatform() { + const ua = navigator.userAgent.toLowerCase(); + + if (/iphone|ipad|ipod/.test(ua)) { + return 'ios'; + } else if (/android/.test(ua)) { + return 'android'; + } else { + return 'desktop'; + } + } + + function showModal(content) { + const modal = document.createElement('div'); + modal.className = 'install-modal'; + modal.innerHTML = ` +
+ ${content} + +
+ `; + + modal.querySelector('.install-modal-close').addEventListener('click', () => { + modal.remove(); + }); + + document.body.appendChild(modal); + } + + function trackInstallation() { + // Send analytics event + if (window.gtag) { + window.gtag('event', 'pwa_install', { + event_category: 'engagement', + event_label: 'PWA Installation' + }); + } + + // Could also send to custom analytics endpoint + console.log('[Fishy Install] Installation tracked'); + } + + // Register service worker + if ('serviceWorker' in navigator) { + window.addEventListener('load', () => { + navigator.serviceWorker + .register('/service-worker.js') + .then((registration) => { + console.log('[Fishy SW] Service Worker registered:', registration.scope); + + // Check for updates periodically + setInterval(() => { + registration.update(); + }, 60 * 60 * 1000); // Check every hour + + // Listen for updates + registration.addEventListener('updatefound', () => { + const newWorker = registration.installing; + + newWorker.addEventListener('statechange', () => { + if (newWorker.state === 'installed' && navigator.serviceWorker.controller) { + // New service worker available + showUpdateNotification(); + } + }); + }); + }) + .catch((error) => { + console.error('[Fishy SW] Service Worker registration failed:', error); + }); + }); + } + + function showUpdateNotification() { + const notification = document.createElement('div'); + notification.className = 'update-notification'; + notification.innerHTML = ` +
+

A new version of Fishy is available!

+ + +
+ `; + + notification.querySelector('.update-button').addEventListener('click', () => { + // Tell the service worker to skip waiting + navigator.serviceWorker.controller.postMessage({ type: 'SKIP_WAITING' }); + + // Reload the page + window.location.reload(); + }); + + notification.querySelector('.update-dismiss').addEventListener('click', () => { + notification.remove(); + }); + + document.body.appendChild(notification); + } + + // Expose API for manual control + window.FishyInstall = { + isInstalled: () => isInstalled, + canInstall: () => deferredPrompt !== null, + install: handleInstallClick, + showInstructions: showManualInstructions + }; + + console.log('[Fishy Install] Install prompt handler loaded'); +})(); diff --git a/wasm_resources/manifest.json b/wasm_resources/manifest.json new file mode 100644 index 0000000000..095a1ef86d --- /dev/null +++ b/wasm_resources/manifest.json @@ -0,0 +1,111 @@ +{ + "name": "Fishy - Dive into 8-bit Chaos", + "short_name": "Fishy", + "description": "Tactical 2D shooter with retro 8-bit style. Play up to 4 players online or local, with Web3 NFT cosmetics and token rewards!", + "start_url": "/", + "scope": "/", + "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", "entertainment"], + "screenshots": [ + { + "src": "screenshots/gameplay-1.png", + "sizes": "1280x720", + "type": "image/png", + "label": "Intense 4-player underwater combat" + }, + { + "src": "screenshots/gameplay-2.png", + "sizes": "1280x720", + "type": "image/png", + "label": "Customize your fish with NFT hats and skins" + } + ], + "shortcuts": [ + { + "name": "Quick Match", + "short_name": "Play", + "description": "Jump into a quick match", + "url": "/?mode=quickmatch", + "icons": [ + { + "src": "icons/icon-96x96.png", + "sizes": "96x96" + } + ] + } + ], + "share_target": { + "action": "/share", + "method": "GET", + "params": { + "title": "title", + "text": "text", + "url": "url" + } + }, + "related_applications": [ + { + "platform": "play", + "url": "https://play.google.com/store/apps/details?id=io.8bitgames.fishy", + "id": "io.8bitgames.fishy" + }, + { + "platform": "itunes", + "url": "https://apps.apple.com/app/fishy/id123456789" + } + ], + "prefer_related_applications": false +} diff --git a/wasm_resources/pwa-styles.css b/wasm_resources/pwa-styles.css new file mode 100644 index 0000000000..f43c947c12 --- /dev/null +++ b/wasm_resources/pwa-styles.css @@ -0,0 +1,281 @@ +/* Fishy PWA UI Styles */ + +/* Install Button */ +.pwa-install-button { + position: fixed; + bottom: 20px; + right: 20px; + z-index: 9999; + + display: none; + align-items: center; + gap: 8px; + + padding: 12px 20px; + background: linear-gradient(135deg, #8bcfcf 0%, #34925e 100%); + border: 2px solid #fff; + border-radius: 8px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); + + color: white; + font-family: 'Arial', sans-serif; + font-size: 16px; + font-weight: bold; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); + + cursor: pointer; + transition: all 0.3s ease; + + animation: slideIn 0.5s ease-out; +} + +.pwa-install-button:hover { + transform: translateY(-2px); + box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4); + background: linear-gradient(135deg, #9edede 0%, #3fa36d 100%); +} + +.pwa-install-button:active { + transform: translateY(0); + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); +} + +.pwa-install-button svg { + width: 24px; + height: 24px; + stroke: white; +} + +@keyframes slideIn { + from { + transform: translateX(200px); + opacity: 0; + } + to { + transform: translateX(0); + opacity: 1; + } +} + +/* Install Modal */ +.install-modal { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 10000; + + display: flex; + align-items: center; + justify-content: center; + + background: rgba(0, 0, 0, 0.8); + backdrop-filter: blur(4px); + + animation: fadeIn 0.3s ease-out; +} + +.install-modal-content { + background: linear-gradient(135deg, #262B44 0%, #181425 100%); + border: 3px solid #8bcfcf; + border-radius: 12px; + padding: 32px; + max-width: 400px; + width: 90%; + + color: white; + font-family: 'Arial', sans-serif; + + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5); +} + +.install-instructions h3 { + margin: 0 0 16px 0; + color: #8bcfcf; + font-size: 24px; + text-align: center; +} + +.install-instructions ol { + margin: 16px 0; + padding-left: 24px; +} + +.install-instructions li { + margin: 12px 0; + font-size: 16px; + line-height: 1.5; +} + +.install-modal-close { + display: block; + width: 100%; + margin-top: 24px; + padding: 12px; + + background: #34925e; + border: 2px solid #fff; + border-radius: 6px; + + color: white; + font-size: 16px; + font-weight: bold; + + cursor: pointer; + transition: all 0.2s ease; +} + +.install-modal-close:hover { + background: #3fa36d; + transform: translateY(-1px); +} + +.install-modal-close:active { + transform: translateY(0); +} + +@keyframes fadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +/* Update Notification */ +.update-notification { + position: fixed; + top: 20px; + left: 50%; + transform: translateX(-50%); + z-index: 10000; + + background: linear-gradient(135deg, #262B44 0%, #181425 100%); + border: 2px solid #f3ee7a; + border-radius: 8px; + padding: 16px 24px; + + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4); + + animation: slideDown 0.5s ease-out; +} + +.update-content { + display: flex; + align-items: center; + gap: 16px; + color: white; + font-family: 'Arial', sans-serif; +} + +.update-content p { + margin: 0; + font-size: 16px; + font-weight: bold; +} + +.update-button, +.update-dismiss { + padding: 8px 16px; + border: 2px solid #fff; + border-radius: 4px; + + font-size: 14px; + font-weight: bold; + + cursor: pointer; + transition: all 0.2s ease; +} + +.update-button { + background: #34925e; + color: white; +} + +.update-button:hover { + background: #3fa36d; +} + +.update-dismiss { + background: transparent; + color: white; +} + +.update-dismiss:hover { + background: rgba(255, 255, 255, 0.1); +} + +@keyframes slideDown { + from { + transform: translateX(-50%) translateY(-100px); + opacity: 0; + } + to { + transform: translateX(-50%) translateY(0); + opacity: 1; + } +} + +/* Responsive adjustments */ +@media (max-width: 768px) { + .pwa-install-button { + bottom: 12px; + right: 12px; + padding: 10px 16px; + font-size: 14px; + } + + .pwa-install-button svg { + width: 20px; + height: 20px; + } + + .install-modal-content { + padding: 24px; + } + + .install-instructions h3 { + font-size: 20px; + } + + .install-instructions li { + font-size: 14px; + } + + .update-notification { + top: 12px; + left: 12px; + right: 12px; + transform: none; + } + + .update-content { + flex-direction: column; + gap: 12px; + } + + .update-button, + .update-dismiss { + width: 100%; + } +} + +/* Hide install button when in standalone mode */ +@media (display-mode: standalone) { + .pwa-install-button { + display: none !important; + } +} + +/* iOS specific adjustments */ +@supports (-webkit-touch-callout: none) { + .pwa-install-button { + bottom: calc(20px + env(safe-area-inset-bottom)); + } + + .update-notification { + top: calc(20px + env(safe-area-inset-top)); + } +} diff --git a/wasm_resources/screenshots/README.md b/wasm_resources/screenshots/README.md new file mode 100644 index 0000000000..f595c0dfe0 --- /dev/null +++ b/wasm_resources/screenshots/README.md @@ -0,0 +1,49 @@ +# PWA Screenshots + +This directory should contain screenshots for PWA app stores and installation prompts. + +## Required Screenshots + +1. **gameplay-1.png** (1280x720) + - Main gameplay screenshot showing 4-player action + - Highlight weapons and combat + +2. **gameplay-2.png** (1280x720) + - Character customization screen + - Show NFT hats and skins + +3. **gameplay-3.png** (1280x720) [Optional] + - Map selection screen + - Show variety of levels + +4. **gameplay-4.png** (1280x720) [Optional] + - Scoring/victory screen + - Show progression system + +## Screenshot Guidelines + +- **Resolution**: 1280x720 minimum (16:9 aspect ratio) +- **Format**: PNG for quality +- **Content**: Actual in-game screenshots (not mockups) +- **Annotations**: Optional text overlays highlighting features +- **Branding**: Include "Fishy" branding where appropriate + +## How to Capture + +1. **In-Game**: + - Play the game in browser + - Use browser's screenshot tool or F12 key + - Capture during exciting moments + +2. **Post-Processing**: + - Crop to 1280x720 + - Add annotations if desired + - Optimize file size (use tinypng.com) + +## Testing + +Screenshots appear in: +- PWA install prompts +- App store listings (future mobile apps) +- Social media sharing +- Marketing materials diff --git a/wasm_resources/service-worker.js b/wasm_resources/service-worker.js new file mode 100644 index 0000000000..8647845136 --- /dev/null +++ b/wasm_resources/service-worker.js @@ -0,0 +1,233 @@ +// Fishy Service Worker - PWA Offline Support +// Version: 1.0.0 + +const CACHE_VERSION = 'fishy-v1.0.0'; +const RUNTIME_CACHE = 'fishy-runtime-v1.0.0'; +const ASSET_CACHE = 'fishy-assets-v1.0.0'; + +// Core files to cache immediately on install +const PRECACHE_ASSETS = [ + '/', + '/index.html', + '/fishy.js', + '/fishy_bg.wasm', +]; + +// Asset patterns to cache on first access +const CACHE_PATTERNS = { + assets: /^\/assets\//, + images: /\.(png|jpg|jpeg|gif|webp|svg)$/, + audio: /\.(ogg|mp3|wav)$/, + fonts: /\.(woff|woff2|ttf|otf)$/, +}; + +// Install event - cache core assets +self.addEventListener('install', (event) => { + console.log('[Fishy SW] Installing service worker...'); + + event.waitUntil( + caches.open(CACHE_VERSION) + .then((cache) => { + console.log('[Fishy SW] Caching core assets'); + return cache.addAll(PRECACHE_ASSETS); + }) + .then(() => { + console.log('[Fishy SW] Core assets cached'); + // Activate immediately + return self.skipWaiting(); + }) + .catch((error) => { + console.error('[Fishy SW] Failed to cache core assets:', error); + }) + ); +}); + +// Activate event - clean up old caches +self.addEventListener('activate', (event) => { + console.log('[Fishy SW] Activating service worker...'); + + event.waitUntil( + caches.keys() + .then((cacheNames) => { + return Promise.all( + cacheNames + .filter((cacheName) => { + // Delete old cache versions + return cacheName.startsWith('fishy-') && + cacheName !== CACHE_VERSION && + cacheName !== RUNTIME_CACHE && + cacheName !== ASSET_CACHE; + }) + .map((cacheName) => { + console.log('[Fishy SW] Deleting old cache:', cacheName); + return caches.delete(cacheName); + }) + ); + }) + .then(() => { + console.log('[Fishy SW] Service worker activated'); + // Take control of all pages immediately + return self.clients.claim(); + }) + ); +}); + +// Fetch event - serve from cache, fallback to network +self.addEventListener('fetch', (event) => { + const { request } = event; + const url = new URL(request.url); + + // Skip non-GET requests + if (request.method !== 'GET') { + return; + } + + // Skip chrome-extension and other non-http(s) requests + if (!url.protocol.startsWith('http')) { + return; + } + + event.respondWith( + handleFetch(request) + ); +}); + +async function handleFetch(request) { + const url = new URL(request.url); + + // Strategy 1: Network-first for HTML (to get updates) + if (request.headers.get('accept').includes('text/html')) { + return networkFirst(request); + } + + // Strategy 2: Cache-first for WASM and JS (critical resources) + if (url.pathname.endsWith('.wasm') || url.pathname.endsWith('.js')) { + return cacheFirst(request, CACHE_VERSION); + } + + // Strategy 3: Cache-first for assets (images, audio, fonts) + if (matchesCachePattern(url.pathname)) { + return cacheFirst(request, ASSET_CACHE); + } + + // Strategy 4: Network-first with cache fallback for everything else + return networkFirst(request); +} + +// Network-first strategy (good for HTML and API calls) +async function networkFirst(request) { + try { + const networkResponse = await fetch(request); + + // Only cache successful responses + if (networkResponse && networkResponse.status === 200) { + const cache = await caches.open(RUNTIME_CACHE); + cache.put(request, networkResponse.clone()); + } + + return networkResponse; + } catch (error) { + // Network failed, try cache + const cachedResponse = await caches.match(request); + + if (cachedResponse) { + console.log('[Fishy SW] Serving from cache (offline):', request.url); + return cachedResponse; + } + + // No cache, return offline page or error + return new Response('Offline - Please check your connection', { + status: 503, + statusText: 'Service Unavailable', + headers: new Headers({ + 'Content-Type': 'text/plain', + }), + }); + } +} + +// Cache-first strategy (good for static assets) +async function cacheFirst(request, cacheName) { + const cachedResponse = await caches.match(request); + + if (cachedResponse) { + // Return cached version + return cachedResponse; + } + + // Not in cache, fetch from network + try { + const networkResponse = await fetch(request); + + // Cache the new resource + if (networkResponse && networkResponse.status === 200) { + const cache = await caches.open(cacheName); + cache.put(request, networkResponse.clone()); + } + + return networkResponse; + } catch (error) { + console.error('[Fishy SW] Failed to fetch:', request.url, error); + + // Could return a fallback image/audio here + return new Response('Resource not available offline', { + status: 404, + statusText: 'Not Found', + }); + } +} + +// Check if URL matches any cache pattern +function matchesCachePattern(pathname) { + return Object.values(CACHE_PATTERNS).some((pattern) => pattern.test(pathname)); +} + +// Listen for messages from the app +self.addEventListener('message', (event) => { + if (event.data && event.data.type === 'SKIP_WAITING') { + console.log('[Fishy SW] Received SKIP_WAITING message'); + self.skipWaiting(); + } + + if (event.data && event.data.type === 'CLEAR_CACHE') { + console.log('[Fishy SW] Clearing all caches...'); + event.waitUntil( + caches.keys().then((cacheNames) => { + return Promise.all( + cacheNames.map((cacheName) => caches.delete(cacheName)) + ); + }) + ); + } + + if (event.data && event.data.type === 'GET_VERSION') { + event.ports[0].postMessage({ version: CACHE_VERSION }); + } +}); + +// Background sync for future features (tournament results, etc.) +self.addEventListener('sync', (event) => { + if (event.tag === 'sync-game-data') { + event.waitUntil(syncGameData()); + } +}); + +async function syncGameData() { + // Placeholder for syncing game data when back online + console.log('[Fishy SW] Syncing game data...'); + // This could sync tournament results, player stats, etc. +} + +// Periodic background sync (for checking updates) +self.addEventListener('periodicsync', (event) => { + if (event.tag === 'check-updates') { + event.waitUntil(checkForUpdates()); + } +}); + +async function checkForUpdates() { + console.log('[Fishy SW] Checking for updates...'); + // Could check for new game version or content +} + +console.log('[Fishy SW] Service worker loaded successfully');