Project Info
Inspiration
Humanoid robot sports are coming. Projects like Ultimate Bots and Ghost Trials make it possible to capture human movement and deploy it onto humanoid robots. But we noticed a missing step in the workflow: How do creators know whether a move is actually robot-ready before it reaches hardware? A punch combo might look amazing on camera but be unstable, inefficient, or difficult for a humanoid robot to execute safely. Today, most motion-capture workflows stop at visualization. We wanted to build the layer that evaluates, coaches, and stress-tests human-created movements before deployment. That's how Ghost Fighter was born. Our vision is simple: treat human movement like a draft pick for a robot athlete. Every move should be scored, analyzed, improved, and battle-tested before it ever reaches a real robot.
What it does
Ghost Fighter transforms human-created motions into structured robot skills. A creator can export a motion from Ultimate Bots Studio, and Ghost Fighter automatically: Ingests SONIC trajectory data Maps joints from IsaacLab ordering to MuJoCo / Unitree G1 ordering Generates a structured move card Scores robot readiness and deployability Provides AI coaching feedback Replays the motion on a simulated Unitree G1 Tests the move inside a robot-sports arena Instead of viewing motion as a video, we treat it as a reusable robot skill. Each move receives attributes such as: Speed Power Smoothness Balance Risk Recovery Deployability We also generate coach-style feedback such as: "Looks powerful, but widening your stance before commitment would improve balance and recovery." During the hackathon we shipped two fully functioning skills: Ghost Jab Combo Block (including full SONIC defensive animation replay)
How we built it
We built a complete end-to-end Physical AI pipeline: Human Motion → SONIC Export → Move Analysis → G1 Replay → Robot Sports Arena Motion Processing We ingest SONIC motion trajectories exported from UFB Studio and convert them into a format compatible with the Unitree G1 humanoid model. To achieve this, we implemented: Joint remapping between IsaacLab and MuJoCo conventions Motion playback systems Move-card generation and scoring Skill metadata extraction AI Agents We introduced specialized agents that each serve a distinct role: Coach Agent Provides actionable feedback Suggests improvements for robot safety and execution quality Judge Agent Evaluates whether a move is deployable Produces readiness assessments Announcer Agent Generates live fight commentary Creates the feeling of a robot-sports broadcast For voice commentary, we integrated Deepgram to bring matches to life. Arena Simulation We built a lightweight robot-sports arena where players can test moves in real gameplay scenarios. The arena includes: Health Stamina Balance Positioning Range checking Blocking mechanics Recovery windows Moves can be evaluated not just visually, but competitively. We also implemented multiplayer support so teammates can join the same arena and test move cards against one another.
Challenges we ran into
The hardest challenge was building a reliable bridge between motion-capture data and humanoid robot playback. Different robotics systems use different joint ordering conventions, so motion data could not simply be imported and replayed directly. We had to carefully map and validate trajectories between SONIC exports, simulation environments, and the Unitree G1 model. Another challenge was deciding where AI should actually add value. Rather than using LLMs everywhere, we focused on specialized agents that provide meaningful coaching, judging, and commentary while keeping gameplay deterministic and responsive. Finally, we had to balance two very different experiences: A serious Physical AI evaluation platform A fun robot-sports game Designing a system that could be both useful and entertaining within 48 hours was one of the most rewarding parts of the project.
Accomplishments we're proud of
Built a complete human-motion-to-robot pipeline Replayed real SONIC trajectories on a Unitree G1 model Generated structured robot skill cards Developed AI coaching and judging systems Created a multiplayer robot-sports arena Integrated live AI-powered commentary Delivered an end-to-end working demo in under 48 hours Most importantly, we transformed raw human motion into something measurable, coachable, and competitive.
What we learned
Building Ghost Fighter taught us that the future of Physical AI is not just about making robots move. It's about translating messy human creativity into structured robot behavior. A useful robot-sports ecosystem needs more than robots. It needs creators, coaches, evaluation tools, testing environments, and feedback loops. We believe Ghost Fighter represents an early version of that creator ecosystem.
What's next
This hackathon gave us the foundation for a much larger platform. Next steps include: Direct Coach and Judge integration into the move-builder workflow Custom fighter loadouts Persistent player progression and leaderboards Redis-powered move memory and analytics Automated highlight reel generation Larger-scale multiplayer tournaments Hardware validation workflows for real humanoid robots Long term, we envision Ghost Fighter becoming a creator platform for robot athletes. Anyone should be able to design a move, receive AI coaching, test it in competition, and eventually watch it perform on real humanoid hardware. One-line summary Ghost Fighter turns human movement into ranked, coachable, battle-tested robot skills—the layer between human creativity and the future of humanoid robot sports.
Ghost Fighter
Ghost Fighter is a Physical AI / robot-sports platform that turns human movement into structured robot skills.
The demo path is:
human motion → UFB Studio / SONIC export → scored move card → 3D G1 replay → robot-sports arena
We score whether a human-created move is clean, expressive, and robot-executable enough to become a reusable robot-athlete skill.
Run the app
cd web
npm install
npm run dev
Open:
- App: http://localhost:3000
- Move card / Skill Lab: http://localhost:3000/moves/ghost_jab_combo_sonic
- 3D Arena: http://localhost:3000/arena
Run Fetch.ai Judge/Coach agents
The live Judge panel calls a local bridge, which sends move stats to the Judge uAgent and asks the Coach uAgent for fixes when needed. Before using the live Judge panel, run these in separate terminals:
cd agents
conda activate ghost-fighter-agents
python coach_agent.py
cd agents
conda activate ghost-fighter-agents
python judge_agent.py
cd agents
conda activate ghost-fighter-agents
uvicorn web_bridge:app --port 8010 --reload
Then start the web app with the bridge URL:
cd web
JUDGE_BRIDGE_URL=http://localhost:8010 npm run dev
The agents read agents/.env. Make sure it includes COACH_ADDRESS,
JUDGE_ADDRESS, COACH_ENDPOINT, JUDGE_ENDPOINT, and BRIDGE_MODE=agent.
Optional: arena announcer voice
The arena can call fights with Deepgram TTS. Copy the example env file and add your key:
cp .env.local.example .env.local
# edit web/.env.local and set DEEPGRAM_API_KEY=...
Without a key, the app builds and runs normally — you just see “Announcer off” in the arena.
Production build
cd web
npm install
npm run build
npm start
If you see Can't resolve '@deepgram/sdk', run npm install in web/ first. The dependency is already listed in package.json.
What to demo
- Open
/moves/ghost_jab_combo_sonic. - Show the move card: speed, power, smoothness, balance risk, recovery, deployability, and coach feedback (hover the i icons for definitions).
- Show the 3D SONIC replay: G1 URDF driven by remapped
joint_pos.csvtrajectories. - Open
/arena. - Use each player’s move buttons to trigger a 3D robot duel with HP bars, balance bars, hit effects, and knockback.
- Toggle the announcer if
DEEPGRAM_API_KEYis configured. - Mention the Unitree G1 assets loaded from
web/public/models/g1_descriptionandweb/public/models/unitree_g1.
Routes
/— dashboard and move library/ingest— upload a SONIC.zipor source video/moves/[id]— skill card, 3D replay, verification ladder/fighters/build— create a fighter loadout from move cards/arena— 3D robot-sports duel with health bars and move playback/leaderboard— top moves and fighters by deployability
AI opponent ("the enemy")
The arena ships with a deterministic, seeded AI opponent. It satisfies the same per-frame controller contract as the human input handler, reuses the existing Move Card stats and arena loop/physics, and runs no LLM in the frame loop.
It thinks at three internal rates (mapped onto the arena tick by an adapter):
- Strategist (~3 Hz) — game-plan + online player-modeling (move-frequency,
anti-spam counter-bias, intent:
pressure/zone/counter/reset). - Tactician (~15 Hz) — Utility-AI scoring of every Move Card now from the existing stats (range fit, whiff-punish/interrupt timing, safety, intent match, payoff − stamina − balance_risk − recovery) with seeded noise.
- Executor (per frame) — footwork toward preferred range, else commit the move via the arena's move-commit API.
Difficulty knobs (reaction_delay, optimal_prob, mistake_rate,
adaptation, noise) are orthogonal to style (intent). Code lives in
web/lib/enemy/.
Personas
Rusher, Zoner, Counter-Puncher, Adapter-Boss (web/lib/enemy/personas.ts).
Select one in the UI: open /arena and use the Player 2 AI dropdown.
Choose a persona to let it pilot Player 2; "Manual (human)" returns control.
Headless: POST /api/arena/fight with { fighter_a, fighter_b, persona_b, seed } — when persona_b is set, that persona drives fighter_b. seed makes
the match replayable.
Evaluation harness (competition-readiness)
Run a fighter's deck against the full persona pool through the real arena and get a win-rate + why-it-loses profile (and a readiness score blended with the existing Deployability):
curl -X POST http://localhost:3000/api/arena/evaluate \
-H 'Content-Type: application/json' \
-d '{ "fighter": "<fighter_id>", "matches": 5, "seed": 1 }'
Tests
cd web
npm test # vitest, fully offline (seeded unit + real-arena integration)
Motion replay notes
SONIC zip exports store joints in IsaacLab/internal order (joint_0…joint_28). The web replay and trajectory API remap that to MuJoCo / Unitree SDK order before driving the G1 URDF (web/lib/g1Motion.ts).
Lafan CSV exports use a different layout (XYZ + QX QY QZ QW + 29 joints at 30fps). Use those for training pipelines like mjlab; the in-app replay expects the SONIC zip CSVs.
CLI scoring
python3 scripts/analyze_motion.py
This reads the extracted SONIC CSVs and writes:
move_cards/ghost_jab_combo.json
Assets
assets/motions/ghost_jab_combo_sonic.zip— Studio SONIC export for G1 deployassets/motions/ghost_jab_combo_extracted/— extracted SONIC CSVsassets/motions/block_sonic.zip— defensive block SONIC exportassets/motions/block_extracted/— extracted block motion CSVsweb/public/models/unitree_g1/— MuJoCo Menagerie Unitree G1 reference assetsweb/public/models/g1_description/— Unitree ROS G1 URDF + meshes for browser renderingscripts/verify_with_gear_sonic.sh— prepares the motion folder for official GEAR-SONIC/MuJoCo verification
Stack
- Next.js 15 + React 19
- Three.js + URDFLoader for 3D replay and arena
- TypeScript scoring engine ported from
scripts/analyze_motion.py - JSON file store in
web/data/during local dev - Optional Deepgram TTS for arena announcer (
/api/tts) - SONIC / G1 motion assets from UFB Studio
Pitch
Ghost Fighter turns human moves into ranked, coachable, deployable robot skills. Studio retargets the motion; Ghost Fighter scores it, visualizes it on a G1 model, turns it into a move card, and lets it fight in a robot-sports arena.
Analysis
View
Metric
- 18
- 17
- 6
- 5
- 4
- 2
Figures cover GitHub contributors during the hackathon window. A co-authored commit counts in full for each author, so per-member totals add up to more than the whole-team figures.
Technology
- CSSIn code
- FastAPIIn code
- HTMLIn code
- Next.jsIn code
- OpenAIIn code
- PythonIn code
- ReactIn code
- Tailwind CSSIn code
- TypeScriptIn code
- JavaScriptClaimed
9 of 10 appear in the indexed code. 1 claimed on Devpost could not be matched to code, which may simply mean the tool leaves no trace in the repository.
AI coding agents
- Claude CodeCommits
- CursorCommits
Detected from committed agent config files and commit authorship. Absence of a signal is not proof an agent was unused.
Codebase size
Source size
690 KB
Source files
98
Counts recognized source files only; vendored directories, binaries and lockfiles are excluded, so this is smaller than the repository on disk.
Repository
lyeric2022/aaa
390 files · 149.2 MB · @ 8c79b9d
Structure
Interface
18 files · 5%Screens, components and styles rendered to the user.
API & routing
15 files · 4%Request entry points: routes, handlers and controllers.
Application logic
36 files · 9%Domain rules, services and shared utilities.
Supporting
Layers are inferred from where files sit in the tree, not from reading the code. A project that names its directories unconventionally will read oddly here — open the file browser to check anything the diagram implies.
Languages
- XML52%
- TypeScript35%
- Python7%
- Markdown6%
- HTML1%
- Shell0%
- Other (2)0%
Share of indexed source by file size. Binary and vendored files are excluded.
Dependencies
web/package.json
npm · 22- @deepgram/sdk
- adm-zip
- next
- react
- react-dom
- three
- urdf-loader
- uuid
- +14 more
agents/requirements.txt
pypi · 6- fastapi
- openai
- python-dotenv
- uagents
- uagents-core
- uvicorn[standard]
Declared in the repository’s manifests at the indexed commit. A declared package is not proof it is used, and runtime dependencies are listed first.
Export this project's context (description, README, evidence, key source files) to chat with an AI agent elsewhere.