6ef4c40e29
Two-repo monorepo for an offline FUT backend inspired by SPT. openfut-core: game-independent REST API backend (Axum, SQLite, SQLx) - 19 API endpoints: auth, profiles, clubs, cards, packs, squads, objectives, SBCs, match rewards, NPC market, statistics - JSON-driven card/pack/objective/SBC data (fully moddable) - SQLx migrations, weighted pack generator, SBC validation engine - 5 integration tests passing openfut-bridge: FIFA 23 traffic proxy + reverse-engineering scaffold - Catch-all HTTP proxy with request capture to captures/ - Known-route mapper (FUT paths → Core API calls) - Placeholder responses for unknown endpoints - Admin endpoints: captures, unknown endpoint list - 4 unit tests passing cargo fmt ✓ cargo clippy -D warnings ✓ cargo test ✓ Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
136 lines
3.5 KiB
Markdown
136 lines
3.5 KiB
Markdown
# OpenFUT Core
|
|
|
|
**Offline Ultimate Team backend — game-independent.**
|
|
|
|
OpenFUT Core is the heart of the OpenFUT project: a fully offline, single-player FUT-style backend written in Rust. It is deliberately decoupled from any specific game, though it is designed to power a FIFA 23 offline experience.
|
|
|
|
---
|
|
|
|
## What it does
|
|
|
|
- Creates and manages local player profiles and clubs
|
|
- Manages coins, XP, and progression
|
|
- Generates packs from weighted JSON definitions
|
|
- Tracks your full card collection
|
|
- Squad builder with formations and chemistry (chemistry calculations: WIP)
|
|
- Objectives engine (daily, weekly, lifetime, milestone)
|
|
- SBC (Squad Building Challenge) engine with JSON-defined challenges
|
|
- Match result processing with coin and XP rewards
|
|
- NPC transfer market with daily refreshes
|
|
- Statistics tracking
|
|
- Fully moddable via JSON data files
|
|
|
|
---
|
|
|
|
## Tech Stack
|
|
|
|
- **Rust** + **Axum** (HTTP framework)
|
|
- **Tokio** (async runtime)
|
|
- **SQLite** + **SQLx** (database + migrations)
|
|
- **Serde** (JSON data layer)
|
|
- **tower-http** (middleware: CORS, tracing)
|
|
|
|
---
|
|
|
|
## Quick Start
|
|
|
|
```bash
|
|
# Build
|
|
cargo build --release
|
|
|
|
# Run (creates openfut.db in current directory)
|
|
./target/release/openfut-core
|
|
|
|
# Or with custom config
|
|
DATABASE_URL=sqlite://./myclub.db LISTEN_ADDR=127.0.0.1:8080 ./target/release/openfut-core
|
|
```
|
|
|
|
### Environment Variables
|
|
|
|
| Variable | Default | Description |
|
|
|---|---|---|
|
|
| `LISTEN_ADDR` | `127.0.0.1:8080` | Address to listen on |
|
|
| `DATABASE_URL` | `sqlite://openfut.db` | SQLite database path |
|
|
| `DATA_DIR` | `data` | Path to JSON data files |
|
|
|
|
---
|
|
|
|
## API Routes
|
|
|
|
| Method | Path | Description |
|
|
|---|---|---|
|
|
| `GET` | `/health` | Health check |
|
|
| `POST` | `/auth/local` | Create first-run profile + club |
|
|
| `GET` | `/profile` | Get active profile |
|
|
| `GET` | `/club` | Get active club with coins |
|
|
| `GET` | `/cards` | Browse all card definitions |
|
|
| `GET` | `/collection` | Get owned cards |
|
|
| `GET` | `/packs` | List unopened packs |
|
|
| `POST` | `/packs/open/:pack_id` | Open a pack |
|
|
| `GET` | `/squad` | Get active squad |
|
|
| `POST` | `/squad` | Save squad |
|
|
| `GET` | `/objectives` | List objectives with progress |
|
|
| `POST` | `/matches/result` | Submit match result + receive rewards |
|
|
| `GET` | `/sbc` | List SBC definitions |
|
|
| `POST` | `/sbc/submit` | Submit SBC solution |
|
|
| `GET` | `/market` | Browse NPC transfer market |
|
|
| `POST` | `/market/buy` | Buy listing |
|
|
| `POST` | `/market/sell` | Quick-sell card |
|
|
| `POST` | `/market/refresh` | Refresh NPC listings |
|
|
| `GET` | `/statistics` | Get match/pack/SBC stats |
|
|
|
|
---
|
|
|
|
## First Run
|
|
|
|
```bash
|
|
# Create your profile
|
|
curl -X POST http://localhost:8080/auth/local \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"username": "Player 1"}'
|
|
|
|
# Check your club (5000 coins + a gold pack waiting)
|
|
curl http://localhost:8080/club
|
|
|
|
# Open your starter pack
|
|
curl -X POST http://localhost:8080/packs/open/<pack_id>
|
|
|
|
# Submit a match win
|
|
curl -X POST http://localhost:8080/matches/result \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"squad_id":"any","opponent_name":"Beginner AI","goals_for":3,"goals_against":0,"mode":"squad_battles"}'
|
|
```
|
|
|
|
---
|
|
|
|
## Modding
|
|
|
|
All game content lives in `data/`. Drop JSON files into the appropriate folder and restart.
|
|
|
|
```
|
|
data/
|
|
cards/ ← CardDefinition[]
|
|
packs/ ← PackDefinition[]
|
|
objectives/ ← ObjectiveDefinition[]
|
|
sbcs/ ← SbcDefinition[]
|
|
events/ ← (future)
|
|
```
|
|
|
|
See `docs/modding.md` for schema reference.
|
|
|
|
---
|
|
|
|
## Development
|
|
|
|
```bash
|
|
cargo fmt
|
|
cargo clippy -- -D warnings
|
|
cargo test
|
|
```
|
|
|
|
---
|
|
|
|
## License
|
|
|
|
MIT — see LICENSE
|