GOALHEAD — Effect House (2026-06-28) — mecânica ALVOS + tracking NATIVO (Face Binding) + áudio
Montagem no Effect House — 2026-06-28
Sessão via Claude Eyes. Efeito jogável, compilando limpo, salvo. Tracking da cabeça AGORA é nativo
(Face Binding) — abandonado o mapeamento manual de coordenadas.
Projeto
~/Desktop/goalhead/(effect.ehproj). DesafioSports effect challenge→Game sub challenge.- Código também em
~/goalhead/scripts/GoalheadGame.ts(sincronizado viacp; ambosGoalheadGame). - Áudios-fonte em
~/Desktop/goalhead-audio/.
🎮 MECÂNICA — ALVOS (não é embaixadinha; sem nomes de time / sem bandeiras)
- Cabeça = superfície de colisão (círculo) com física real (dá p/ equilibrar). Mover a cabeça
transfere velocidade à bola (mira). Alvos (emoji 🎯, objeto "Target") aparecem ACIMA da cabeça;
acertar = +1 e novo alvo. Bola cai abaixo do chão = fim. Som: bola ao quicar, torcida ao acertar. - Física: gravidade em sub-passos, colisão círculo-círculo (restituição + correção de posição +
transferência da velocidade da cabeça), quica em paredes/teto.
🎯 TRACKING DA CABEÇA — NATIVO via FACE BINDING (a solução que funcionou)
O mapeamento manual rosto-normalizado→canvas era device-específico e SEMPRE quebrava no celular
(bola "extremamente acima"), apesar de perfeito no desktop. Trocado por tracking nativo do EH:
- Face Sticker (botão da barra) cria grupo "Face Binding" → "Image" = imagem grudada no rosto
pelo tracking nativo do EH (funciona igual em qualquer aparelho). Renomear falhou na GUI; usei o
nome padrão "Image" e liguei no script via@serializeProperty headAnchorObj+ dropdown do
Inspector (Scene picker → busca "Image" → Ok). Placeholder cinza escondido poraimg.opacity = 0. - Script lê a posição 3D da âncora e PROJETA pela câmera → posição de tela correta em qualquer
device, SEM cálculo manual:wp = headAnchorObj.getComponent("Transform").getWorldPosition() // Vector3f world vp = cameraComp.worldToViewportPoint(wp) // [0,1], origem embaixo-esq headX = (vp.x-0.5)*720 ; headY = (vp.y-0.5)*1280 + ANCHOR_OFFY_K*HEAD_RcameraComp=scn.findSceneObject("Camera").getComponent("Camera")(a câmera 3D "Camera").- Confirmado que RASTREIA: trocar o preview p/ entrada "Nodding (Person 1)" (dropdown de
entrada x1145,y181 → categoria Face) mostra a cabeça mexendo e a âncora seguindo (wp muda). ANCHOR_OFFY_K(frações do RAIO; negativo = desce) ajusta o centro de colisão. A projeção da
âncora cai no alto da testa →ANCHOR_OFFY_K=-1.0baixa ~1 raio p/ a bola "bater na cabeça".
Como é proporcional ao raio (que escala com distância), fica consistente entre aparelhos.
- Tamanho (
HEAD_R) AO VIVO:HEAD_R_FACTOR(0.55) * altura do rosto(AlgorithmManager ...getFaceBaseInfo(0).rect.height*1280), clamp [90,320], suavizado. Fator 0.95 deixava ~2x a cabeça;
0.55 → diâmetro ~1.1x o rosto. - Marcador 🟢 de DEBUG (objeto "HeadMarker", 2D) é posicionado em
headX/headYe escala p/ mostrar
o diâmetro da colisão. REMOVER quando aprovado (cobre o rosto no jogo). - Calibração agora é só contagem "CALIBRANDO 2..1" + captura do repouso (
headBaseX/Y = headX/Yjá
projetado) e do tamanho; NÃO usa maismapFace/SX_REST por fórmula.mapFacefica só de fallback.
🔑 ÁUDIO POR SCRIPT
IAudioComponentda API é vazio, MAS o runtimeAudioComponent(DynamicComponent) templay()/stop()userPublicAPI:obj.getComponent("AudioComponent").play()(cast any).
Audio Players com Autoplay=OFF; script dispara. ❌ toggle deenabledNÃO redispara Autoplay.
3 players: StadiumSound (torcida, loop, autoplay ON), BallSound (bola, once), CheerSound (cheer, once).
bola amplificada via ffmpeg (volume=12dB+alimiter).
⚠️ GOTCHAs de automação no EH
- Valores @serializeProperty ficam "presos" no main.scene e sobrescrevem o código → geometria/física
são camposprivatesimples (sem @serializeProperty); só os OBJETOS são serializeProperty. - Objetos por NOME via
scene.findSceneObject(...).findSceneObjectacha aninhados (recursivo). - Renomear/cor na GUI é instável (double-click no nome do Inspector, HEX da cor) — falhou várias
vezes. Atribuir serializeProperty é mais confiável via o dropdown/Scene picker do Inspector. - Cmd+S é interceptado pela janela do Claude Eyes → usar menu File → Save (x168,y11 → x172,y118).
EH some da frente:osascript -e 'tell application "Effect House" to activate'. Clicar perto da janela
Claude Eyes a ativa e fecha popovers do EH → minimizar (botão amarelo) quando atrapalhar. - Compile:
/tmp/eh.log→[%%USER$$COMPILE]ts project compiled successvserror TSxxxx.
console.log NÃO vai pro eh.log → debugar escrevendo em Text/hint e lendo no screenshot (foi assim que
liwp/vpp/ achar o offset). API:/Applications/Effect House.app/.../UserAPI/APJS.d.ts. - Preview: "Preview in TikTok" (x1472,y49) → "Resend link" (x1473,y186). Entrada do preview no
dropdown x1145,y181 (tem "Idle/Nodding/Mouth Open Person 1..4" p/ testar tracking no desktop).
Falta
- Confirmar no celular: bola gruda/acompanha (✅ esperado agora) e posição vertical
(ANCHOR_OFFY_K, hoje -1.0). Ajustar fino se preciso. - Remover o marcador verde "HeadMarker" quando a colisão estiver aprovada.
- Publicar/Submit (Avatar & Transformation) até 2026-07-09 — só com OK explícito.
Relacionado: projects/goalhead/overview