Skip to content

Arc Cripto Race – a Web3 arcade racing tournament on ARC Testnet. Players pay USDC to enter, race for the best daily score, and compete for on-chain rewards.

Notifications You must be signed in to change notification settings

brunoamuniz/arc-crypto-race

Repository files navigation

🏎️ ARC CRYPTO RACE

A retro pixel-art Web3 arcade racing game with daily tournaments, prize pools, and on-chain leaderboards. Built with Next.js, React, Solidity, and Supabase.

ARC CRYPTO RACE Next.js Solidity ARC Testnet

📋 Table of Contents

🎮 Overview

ARC CRYPTO RACE is a Web3 arcade racing game where players compete in daily tournaments. Players pay a 5 USDC entry fee to participate, race for 5 minutes, and compete for daily prizes distributed to the top 3 players.

Key Features

  • 🏁 Retro Pixel-Art Racing Game: Classic pseudo-3D racing experience
  • 💰 Daily Tournaments: 5 USDC entry fee, prize pool distribution
  • 🏆 On-Chain Leaderboards: Transparent, verifiable rankings
  • 🔐 Web3 Integration: MetaMask wallet connection via Wagmi
  • 📊 Real-Time Scoring: Distance, speed, and crash-based scoring system
  • 🎵 Game Music: Retro racing soundtrack with mute/unmute controls
  • ⏱️ 5-Minute Sessions: Timed gameplay with early stop option

✨ Features

Game Features

  • Progressive difficulty system (increases every minute)
  • Dynamic traffic with AI-controlled cars
  • Multiple billboard advertisements
  • Smooth pseudo-3D rendering
  • Responsive controls (arrow keys)

Web3 Features

  • EVM wallet connection (MetaMask)
  • USDC token approval and payment
  • Smart contract tournament entry
  • On-chain checkpoint commits
  • Transparent prize distribution

Backend Features

  • Supabase PostgreSQL database
  • Real-time leaderboard updates
  • Score submission API
  • Admin finalization endpoints
  • Worker script for blockchain commits

🛠️ Tech Stack

Frontend

  • Framework: Next.js 16.0.7 (App Router)
  • UI Library: React 19.2.0
  • Styling: Tailwind CSS 4.1.9
  • Components: shadcn/ui (Radix UI)
  • Web3: Wagmi 3.1.0, Viem 2.41.2
  • Icons: Lucide React

Smart Contracts

  • Language: Solidity 0.8.20
  • Framework: Hardhat 2.19.0
  • Libraries: OpenZeppelin Contracts 5.4.0
  • Network: ARC Testnet (Chain ID: 5042002)

Backend

  • Database: Supabase (PostgreSQL)
  • API: Next.js API Routes
  • Worker: TypeScript (tsx)

Game Engine

  • Language: Vanilla JavaScript
  • Rendering: HTML5 Canvas
  • Assets: Pixel-art sprites and music

📁 Project Structure

arc-crypto-race/
├── app/                          # Next.js App Router
│   ├── api/                      # API Routes
│   │   ├── admin/                # Admin endpoints
│   │   ├── leaderboard/          # Leaderboard API
│   │   └── submit-score/        # Score submission
│   ├── game/                     # Game page
│   ├── leaderboard/              # Leaderboard page
│   └── page.tsx                  # Landing page
│
├── components/                    # React Components
│   ├── ui/                       # shadcn/ui components
│   ├── GameCanvas.tsx            # Game wrapper
│   ├── HUDScore.tsx              # In-game HUD
│   ├── EnterTournamentButton.tsx # Tournament entry
│   └── WalletConnectButton.tsx   # Wallet connection
│
├── contracts/                    # Smart Contracts
│   ├── src/
│   │   └── Tournament.sol       # Main contract
│   ├── scripts/
│   │   └── deploy.js            # Deployment script
│   └── hardhat.config.js        # Hardhat config
│
├── lib/                          # Utilities
│   ├── contract.ts               # Contract interactions
│   ├── supabase.ts              # Supabase client
│   ├── scoring.ts                # Score calculation
│   ├── wallet.ts                 # Wagmi config
│   └── dayId.ts                  # Day ID utilities
│
├── game/                         # Game Engine (source)
│   ├── common.js                 # Core game logic
│   ├── game-wrapper.js          # React integration
│   ├── stats.js                  # FPS counter
│   └── assets/                   # Game assets
│       ├── images/               # Sprites
│       └── music/                # Audio files
│
├── public/                       # Static Assets
│   └── game/                     # Served game files
│
├── scripts/                      # Utility Scripts
│   ├── worker.ts                 # Blockchain worker
│   ├── check-tournament-entry.ts # Entry verification
│   └── test-contract-interaction.ts # Contract tests
│
└── docs/                         # Documentation
    ├── SUPABASE_SCHEMA.sql      # Database schema
    └── USDC_ADDRESS_UPDATE.md   # USDC address info

🚀 Getting Started

Prerequisites

  • Node.js 18+ and npm/pnpm
  • MetaMask or compatible EVM wallet
  • ARC Testnet USDC (for testing)
  • Supabase account (for database)

Installation

  1. Clone the repository

    git clone <repository-url>
    cd arc-crypto-race
  2. Install dependencies

    npm install
    cd contracts && npm install && cd ..
  3. Set up environment variables

    cp .env.example .env
    # Edit .env with your credentials
  4. Set up Supabase

    • Create a Supabase project
    • Run the schema: docs/SUPABASE_SCHEMA.sql
    • Get your project URL and keys
  5. Deploy smart contract (optional, for testing)

    cd contracts
    npm run deploy:arc
    # Update NEXT_PUBLIC_TOURNAMENT_CONTRACT_ADDRESS in .env
  6. Run development server

    npm run dev
  7. Start worker (in separate terminal)

    npm run worker

Visit http://localhost:3000 to see the application.

🔐 Environment Variables

Create a .env file in the root directory:

# Supabase
NEXT_PUBLIC_SUPABASE_URL=your_supabase_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key
SUPABASE_SERVICE_ROLE_KEY=your_service_role_key
SUPABASE_DB_PASSWORD=your_db_password

# Blockchain - ARC Testnet
NEXT_PUBLIC_ARC_TESTNET_RPC_URL=https://rpc.testnet.arc.network
NEXT_PUBLIC_TOURNAMENT_CONTRACT_ADDRESS=0x...
USDC_ADDRESS=0x3600000000000000000000000000000000000000

# Admin
ADMIN_API_KEY=your_admin_api_key

# Contract Owner (for deploy and transactions)
PRIVATE_KEY=0x...

⚠️ IMPORTANT: Never commit .env files. They contain sensitive information.

📜 Smart Contracts

Tournament Contract

The main contract (contracts/src/Tournament.sol) manages:

  • Entry Fees: 5 USDC per tournament entry
  • Prize Distribution: 60% / 25% / 15% for 1st / 2nd / 3rd place
  • Site Fee: 10% of total pool
  • Checkpoints: Periodic leaderboard hash commits
  • Finalization: Daily tournament closure and prize distribution

Key Functions

  • enterTournament(uint256 dayId): Enter a daily tournament
  • commitCheckpoint(uint256 dayId, bytes32 hash): Commit leaderboard state
  • finalizeDay(uint256 dayId, address[3], uint256[3]): Finalize and distribute prizes
  • getDayInfo(uint256 dayId): Query tournament information
  • hasEntered(uint256 dayId, address): Check if wallet entered

Deployment

cd contracts
npm run deploy:arc

The contract address will be printed. Update NEXT_PUBLIC_TOURNAMENT_CONTRACT_ADDRESS in .env.

🗄️ Database Schema

The Supabase database uses the following tables:

  • scores: All raw score submissions
  • best_scores: Best score per wallet per day (auto-updated via trigger)
  • pending_commits: Queue for blockchain operations
  • commit_logs: Logs of completed blockchain transactions

See docs/SUPABASE_SCHEMA.sql for the complete schema.

🔌 API Routes

Public APIs

  • POST /api/submit-score: Submit a game score

    {
      "wallet": "0x...",
      "dayId": 20251211,
      "score": 12345
    }
  • GET /api/leaderboard?dayId=20251211: Get leaderboard for a day

    {
      "dayId": 20251211,
      "leaderboard": [...],
      "checkpoints": [...],
      "onChainWinners": {...}
    }

Admin APIs

  • POST /api/admin/finalize-day: Finalize a day's tournament
    • Requires x-admin-api-key header
    • Body: { "dayId": 20251211 }

🎮 Game Mechanics

Scoring Formula

Score = (distance × 10) + (maxSpeed × 2) - (elapsedTime × 5) - (crashes × 100)

Game Rules

  • Duration: 5 minutes (300 seconds)
  • Entry Fee: 5 USDC per day
  • Difficulty: Increases every minute
  • Controls: Arrow keys (left/right/up/down)
  • Early Stop: "Stop Playing" button saves current score

Progressive Difficulty

  • Level 1 (0-60s): Base difficulty
  • Level 2 (60-120s): +20% more cars, +15% speed
  • Level 3+: Further increases per minute

🚢 Deployment

Vercel Deployment

  1. Push to GitHub
  2. Import project in Vercel
  3. Add environment variables
  4. Deploy

Environment Variables for Production

Ensure all .env variables are set in Vercel dashboard.

Worker Deployment

The worker script (scripts/worker.ts) should run as a cron job or background service:

npm run worker

Or use a service like:

  • Vercel Cron Jobs
  • Railway
  • Render Cron Jobs

🧪 Testing

Contract Testing

cd contracts
npm test

Contract Interaction Testing

npx tsx scripts/test-contract-interaction.ts

Tournament Entry Verification

npx tsx scripts/check-tournament-entry.ts [wallet_address]

Transaction Verification

npx tsx scripts/check-transaction.ts [tx_hash]

Payment and Prize Distribution Testing

Comprehensive test for payment flow and prize distribution:

npx tsx scripts/test-payment-and-prize-distribution.ts [dayId]

This script tests:

  • Tournament entry payments (3 wallets)
  • Prize pool accumulation
  • Prize distribution (finalizeDay)
  • Balance verification before/after
  • Site fee distribution

See docs/TESTING_PAYMENT_AND_PRIZES.md for detailed guide.

📚 Documentation

All documentation is available in the /docs directory:

🔒 Security

Data Protection

  • Never commit .env files
  • Use .env.example as a template
  • Store private keys securely
  • Use service role keys only on the server

Smart Contract Security

  • Contracts are audited (recommended before mainnet)
  • Use OpenZeppelin contracts for security
  • Owner-only functions are protected

🤝 Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Test thoroughly
  5. Submit a pull request

🙏 Credits & Acknowledgments

This project uses the game engine from javascript-racer by jakesgordon, an excellent Outrun-style pseudo-3D racing game implementation in HTML5 and JavaScript.

The original game engine has been adapted and integrated into this Web3 application with:

  • React/Next.js integration
  • Web3 wallet connectivity
  • On-chain tournament system
  • Real-time leaderboards
  • Prize pool distribution

Special thanks to jakesgordon for creating and open-sourcing the original racing game engine under the MIT license.

Original Project:

📄 License

See docs/LICENSE for license information.

🔗 Links

📞 Support

For issues and questions:

  • Open an issue on GitHub
  • Check the documentation in /docs
  • Review the test scripts in /scripts

Built with ❤️ for the Web3 gaming community

About

Arc Cripto Race – a Web3 arcade racing tournament on ARC Testnet. Players pay USDC to enter, race for the best daily score, and compete for on-chain rewards.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •