Skip to content

Fighter Pack: AI pictures of members across the game - #8

Merged
EmotiveImpact merged 9 commits into
claude/mobile-app-build-nhob8rfrom
claude/project-thread-g9s6ow
Oct 16, 2026
Merged

EmotiveImpact merged 9 commits into
claude/mobile-app-build-nhob8rfrom
claude/project-thread-g9s6ow

Conversation

@EmotiveImpact

Copy link
Copy Markdown
Owner

Before: a member without a photo showed up as the shared stock fighter, so two of them in a 1v1 looked like the same person. There was no way to make your own pictures, and the versus headers used heavy blue and red tints.

After: Pro and Black members can make a Fighter Pack from a live face scan. Their pictures appear on their side of every 1v1, in the countdown, on swipe cards, in results (win pose or respect pose) and on their profile. Anyone without a pack or a photo shows a grey runner silhouette matching their runner choice (Man, Woman or Rather not say), which is asked in onboarding and in Settings. The versus header matches the approved mock: light tints, a red glow on the rival's side, a seam that fades with the photos, the centred VS, and names with blue and red bars.

Mock: https://claude.ai/artifact/V4xNmSEqR7ESv6N6k1Qmdr

How

  • App, in-game pictures.
    • The fallback order is in utils/fighter.js.
    • VersusSplit and its Skia parts are restyled, and VersusName is added.
    • Every stock fighter fallback now goes through fighterPhoto.
    • A "+ Make your pack" pill shows on the battle header and the profile.
  • App, pack flow. app/pack/ holds consent, get ready, a live front camera scan, verified, making, review and poses.
    • The scan captures looking ahead, left and right on its own.
    • Free members see the offer, and under 18s stop at the door.
  • Data.
    • The local engine has a twin, data/pack.js, and Supabase has remotePack.js, both with the same API.
    • The hooks are usePackState and usePackCredits.
    • runner, runnerFigure and fighter are on every player view.
  • Database. Migration 20261016100000_fighter_pack.sql adds the runner columns, a credits ledger with join grants and a monthly top-up, consents, verifications, packs, images, pose picks, RLS and RPCs, plus pgTAP tests.
  • Edge Function avatar-pack. It handles selfie upload URLs, scan checks, generation through fal (nano-banana/edit) with a signed webhook, delete, and a cleanup that removes selfies after 24 hours.

Defaults picked:

  • Free is locked.
  • A pack is 8 pictures for 8 credits.
  • Pro gets 12 credits on joining, then 4 a month up to 12.
  • Black gets 20 on joining, then 12 a month up to 30, and all 12 poses.
  • There's no paid top-up yet.

To go live, this needs:

  • the migration run;
  • the secrets FAL_KEY, R2_AVATAR_BUCKET, R2_PACK_BUCKET and AVATAR_WEBHOOK_SECRET;
  • EXPO_PUBLIC_AVATAR_URL set in the app.

Not done yet:

  • The scan checks that all three angles were captured but has no real liveness model yet. The function marks where it plugs in.
  • The review screen can't yet swap a slot back to your own photo.
  • The Rive VS card (Animated logo and 1v1 card in Rive, wired into the phone app #7) isn't wired in. Its image inputs follow the same fallback order.

Checks: jest passes (133 tests), tsc is clean, and both web exports (local data and Supabase mode) build. The live battle header was checked against the mock at 390x844.

🤖 Generated with Claude Code

https://claude.ai/code/session_015oE2zAkm15foN26zFA3prv


Generated by Claude Code

Constants for the pack (slots, pose sets, credit rules, runner choice and
scan steps), the fighterPhoto helper that picks pack picture, own photo or a
runner silhouette, and the bundled silhouettes and sample pictures.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015oE2zAkm15foN26zFA3prv
The versus split now matches the approved mock: light edge tints, a red
glow on the rival's side, a seam that fades with the photos, a centred VS
with its bloom, and names with blue and red bars (VersusName). Every place
that fell back to the stock fighter now uses fighterPhoto: pack picture,
then own photo, then a silhouette from the runner choice. The live battle
and the profile show a Make your pack pill until a pack exists; results
show the win or respect pose. Your runner (Man, Woman, Rather not say) is
asked in onboarding and in Settings, Your profile.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015oE2zAkm15foN26zFA3prv
…ew, poses

Built to the approved mock as a bank style ID check: a four step bar,
consent with one tick, three simple rules, then a live front camera scan
that captures looking ahead, left and right on its own while the ring
fills. Verified shows before any credits are spent. The pictures land one
by one, the review puts each in its place with a re-roll, and the poses
screen shows Black's locked poses. Free members see what the pack is and
how to get it; under 18s stop at the door. Settings gets a Fighter Pack row.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015oE2zAkm15foN26zFA3prv
Runner choice on profiles, the avatar_credits ledger with join grants on
the ring moving up and a monthly top-up (pg_cron), consent and scan
records, packs and pictures with refunds for failures, pose picks with
the Pro and Black rules, and fighter_of / profiles.fighter /
profile_cards.fighter / fighter_cards so player reads get the pictures.
RPCs: pack_state, pack_credits, record_pack_consent, start_pack,
reroll_pack_slot, set_pack_pose, delete_pack. Types regenerated.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015oE2zAkm15foN26zFA3prv
… cleanup

Actions selfie-url, verify, generate, webhook, delete and cleanup. Selfies go
to the private bucket and are removed within 24 hours; pictures land in the
public bucket. The fal webhook is checked by ED25519 signature and an optional
token. R2 gains head and put.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015oE2zAkm15foN26zFA3prv
makePack runs credits, consent, the scan, making, re-rolls and pose picks on
the phone; makeRemotePack does the same over the RPCs and avatar-pack.
setRunner, and runner, runnerFigure and fighter on the profile and every
player view. usePackState and usePackCredits hooks, and a pack upload helper.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015oE2zAkm15foN26zFA3prv
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015oE2zAkm15foN26zFA3prv
@vercel

vercel Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
outhere-site Ignored Ignored Preview Oct 16, 2026 10:26am UTC

The scan now takes each shot on a timer, so reduced motion still holds
every angle. The local pack uses the portrait sample for the profile and
swipe pictures, the profile slab frames a pack background lower down, the
pack door shows an error with a retry instead of loading forever, and the
runner segment fits.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015oE2zAkm15foN26zFA3prv
@EmotiveImpact
EmotiveImpact marked this pull request as ready for review October 16, 2026 10:36
@EmotiveImpact
EmotiveImpact merged commit 746124f into claude/mobile-app-build-nhob8r Oct 16, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants