hackquest logo

kickoff

KickOff 3D is a 3D browser soccer game where you stake crypto, play 1v1 matches, win KO3D tokens, and mint or trade player NFTs.

视频

项目图片 1
项目图片 2
项目图片 3
项目图片 4

技术栈

Ethers
Node
Web3
Next
React
Solidity

描述

# KickOff 3D

KickOff 3D is a 3D browser-based soccer game with single-player AI mode and real-time 1v1 multiplayer, featuring on-chain economics and NFTs. The project is split into three packages: frontend/ (Next.js 16 + React 19 + React Three Fiber + Rapier physics + Convex), contracts/ (Foundry/Solidity), and ws/ (Bun WebSocket server).

Gameplay

A match lasts 90 minutes with teams of 8 players (one goalkeeper). The physics engine uses Rapier and rendering is done with Three.js. The SoccerEngine runs the gameTick (ball, collisions, goals, possession, difficulty) and renders inside a GameCanvas with an HUD for score, timer, goal flash, and possession stats. Screen flow is handled by a Zustand store with three phases: splash (menu), playing, and finished (post-match with confetti and rematch option).

Online mode

The Bun WebSocket server is server-authoritative: clients only send inputs and receive the full GameLoopState (16 players, ball, score, possession) at 20 Hz. Rooms are hard-capped at 2 players; when both join, the match starts. The winner takes the 0.002 ETH pot minus a 5% fee. ETH deposits are currently mocked in the frontend, and the stub server in ws/index.ts is pending full implementation.

Web3

The on-chain stack lives in contracts/ with three Foundry contracts:

- KickOffToken.sol — ERC-20 KO3D, 1B max supply, MINTER_ROLE for reward minting.

- KickOffPlayerNFT.sol — ERC-721 player cards (team, position, rating, stats) with mintPlayerCard and mintBatch.

- KickOffMatch.sol — 1v1 escrow with createMatch → joinMatch → reportResult (with ORACLE_ROLE so the WS server can submit outcomes) → claim. Includes cancelOpenMatch, feeBps config, and time-gate.

The frontend uses MetaMask (walletService.ts) to connect and sign; a WalletGuard blocks match access without a wallet. Default network is local Anvil (chainId 31337).

Extra features

- Market tab: mint NFTs and list them on a marketplace

- Leaderboard: Convex stores results via recordMatch and shows wins per player.

- i18n: i18next localization.

- MCP: the frontend exposes a Streamable HTTP MCP server at /api/mcp for external integrations.

本次黑客松进展

KickOff 3D was built from scratch during the hackathon. No code or assets were imported from a prior project — every file under frontend/, contracts/, ws/, and specs/ was written in this window.

Day-by-day progress

Day 1 — Bootstrap & specs

- Initialized the monorepo layout (frontend/, contracts/, ws/, specs/) and set up Next.js 16 + App Router + Bun.

- Wrote the four product specs in specs/spec{1..4}.md (Menu, Market, Entry Fee & Rewards, WebSocket Multiplayer) — they became the source of truth for everything built afterwards.

- Bootstrapped the SoccerEngine skeleton and Three.js scene-builder stub.

Day 2 — 3D engine & physics

- Implemented the core gameTick() in frontend/src/lib/game/engine.ts: ball physics, 8v8 player kinematics, goalkeeper logic, AI difficulty levels, goal detection, possession %, match timer.

- Integrated @dimforge/rapier3d-compat for collisions; the ball–player and ball–goal interactions were the hardest part to tune.

- Built the Three.js scene in lib/game/scene-builder.ts: pitch, goals, stadium, player meshes, ball trail.

Day 3 — UI shell & game flow

- Implemented the phase router in app/page.tsx (splash → playing → finished) backed by stores/useGameStore.ts.

- Built SplashScreen (main menu, difficulty selector, team display), NavBar (PLAY / LEADERBOARD / WALLET / PROFILE), and PostMatchScreen (confetti, score, rematch).

- Implemented the in-game HUD in GameCanvas.tsx: scoreboard, goal flash, countdown, possession bar, keyboard input.

Day 4 — Web3 wiring

- Connected MetaMask via lib/services/walletService.ts + useWalletStore (address, chainId, balance, wrong-chain detection).

- Added WalletGuard so match entry requires a connected wallet; entry fee (0.001 ETH) is mocked at the UI level for now.

- Hooked up Convex: users upsert on connect, recordMatch on PostMatchScreen, leaderboard query.

Day 5 — Polish, i18n, MCP

- Added i18next with en-US + zh-CN locales and a language switcher in the navbar.

- Exposed a Streamable HTTP MCP server at app/api/mcp/route.ts so external agents can introspect the game.

- Ran bun run lint and bun run build; trimmed every component under the 250-line hard limit defined in frontend/AGENTS.md.

What ships vs. what's next

- Shipped (frontend): playable 3D match vs AI, full menu/leaderboard/wallet UX, Convex-persisted profile & leaderboard, MCP introspection endpoint.

- Stubbed during hackathon, not yet finished: server-authoritative WebSocket multiplayer in ws/index.ts, on-chain KickOffMarket.sol listing flow, real ETH entry-fee settlement. Contracts compile and have 12 passing forge tests; the multiplayer transport is the last open gap.

Highlight

End-to-end 3D browser soccer with Rapier physics, Convex persistence, MetaMask, and an MCP server — all under one repo, all written during the hackathon.

融资状态

Not fundraising. Project was self-funded and built solo during the hackathon. No outside capital raised, no grants, no token sale, no VC conversations. Open to conversations with strategic partners after the hackathon.

队长
AAdrian Rivera
项目链接
部署生态
Arbitrum SepoliaArbitrum Sepolia
赛道
DeFiNFTGaming