# Flappy Cuz: FLAP Mini App handoff

Rebuilt 2026-08-21 from flap-vault-ui-template **0.1.29**, synced to origin/main.
The 0.1.28 build is superseded: it shipped the pre-ramp engine, which no longer
matched the website.

## Upload this

    miniapp/flappy-cuz.zip
    SHA-256: b60fd6109a672b8645effaaf98ae5e2f5b972a0acf4d5be1b977e32a876c3701
    Size:    132739 bytes

Upload the zip to the Flap Artifact Workbench. Do not hand-assemble a zip; the
Workbench rejects packages without the `flap-vault-package.json` marker.

## Package status

| Command | Result |
|---|---|
| `yarn vault:check flappy-cuz`  | PASSED, 0 blocking, 1 manual-review warning |
| `yarn vault:e2e flappy-cuz`    | PASSED, 17 checks, 0 issues |
| `yarn vault:package flappy-cuz`| PASSED |
| `yarn vault:verify-package`    | PASSED (marker, file list, metadata, hashes) |

All four ran in one pass with no source edits between them.

E2E covered PC / iPad / H5 across default, internal-market, dex-listed,
wrong-network, WebGL2-fallback, reduced-motion and context-loss.

Expected manual-review warning: `manual-review/mini-app-3d`, the standard
three-r3f-v1 review of performance tiers, asset provenance and fallback. It is
expected for any package that ships local 3D art.

## What it is

- Mode: `mini-app`, capability `three-r3f-v1`, artifact
  `vaultui_flappy-cuz_01M0FZ58WBC17PJ2QHR9RY6FKT`
- Display title: 中文 "Flappy 大表哥" / EN "Flappy Cuz"
- Locales en + zh, 中文 primary

The simulation is the **same pure engine the website runs** (`game/engine.ts`,
`game/constants.ts`), copied unchanged and verified byte-identical after
packaging. Only the renderer differs. That is why the physics are identical on
both surfaces and why the run proof stays valid.

This is checked rather than assumed, because it had already drifted once. The
difficulty ramp and the removal of the per-run cap landed on the website while
this package still carried the old flat-curve engine, so for a while the two
surfaces played different games and the claim above was false. Re-verify the
diff whenever either side changes.

Rendering is React Three Fiber with an **orthographic camera mapped 1:1 to the
logical canvas**, so one world unit is one logical pixel and every Flappy Bird
constant stays literally correct. Meshes are pooled and driven imperatively from
`useFrame`; React is not re-rendered at 30Hz.

R3F is used because a Mini App may only ship local art under the
`three-r3f-v1` capability. A plain 2D canvas package cannot statically import
the mascot sprites.

## Binding: audit-stage, must be rebound before production

    chainId 56
    tokenAddresses: 0x9adc2f9dbc4578808f0cdb30d51b5199ff4b8888   ("TEST ONLY" / TEST)

**$大表哥 has no contract address yet.** The manifest binds to a real deployed
TEST token purely as Workbench/E2E proof, because
`tokenAddresses` must be a real deployed ERC20 ending in 7777/8888 and the
contract explicitly forbids substituting a plausible-looking placeholder.

Once the real $大表哥 token exists, **Flap must apply the final production
binding in Workbench**, or regenerate this package with the real token and rerun
the same four commands. Suggested `caRestrictionMode`: `reserved`.

## Deliberate behaviour differences from the website

- **No wallet, no contract calls.** The Mini App only plays the game. It reads
  no Vault state and submits no transactions, so it needs no ABI surface.
- **Best score is session-only.** Browser storage APIs are not on a Vault
  package's allowed surface, so the best score resets when the frame reloads.
- **Keyboard input goes through React's own `onKeyDown`** on the focusable
  play surface. `window.addEventListener` is blocked inside Vault components.
- **The 2D fallback genuinely plays.** If WebGL2 is unavailable the same engine
  drives a plain 2D canvas that draws the mascot and candles from primitives,
  with no image assets, rather than showing a "not supported" panel.
- **Context loss sets `data-flap-3d-state="error"`** via a one-shot listener on
  `gl.domElement`, which is what the E2E harness asserts.

## Host-chrome handling

Two fixes, both required:

1. A zero-width `h-[100dvh]` sentinel measures the true viewport, and the
   control stack is lifted by `root.bottom - viewportH`. The Flap host places
   the Mini App container below its own header/title/tab, so the bottom of the
   app is off-screen on load and sticky cannot fix it.
2. `pr-11 sm:pr-12` on the header clears the host's own fullscreen button in
   the top-right of the frame.

The overlay is `pointer-events-none` with pointer events re-enabled per
control, so every tap reaches the play surface underneath.

## Source

`miniapp/vault-source/` is a copy of `src/vaults/flappy-cuz` from a clean
flap-vault-ui-template checkout. To rebuild, from that checkout:

    
    git pull --ff-only
    yarn vault:register flappy-cuz
    yarn vault:check flappy-cuz && yarn vault:e2e flappy-cuz \
      && yarn vault:package flappy-cuz && yarn vault:verify-package dist/flappy-cuz.zip
