UPENDI

JuggleBoard Game

Gioco arcade reaction & chaining per dispositivi mobili (orizzontale), realizzato in Godot 4.7 (GDScript), ispirato al prodotto riabilitativo "Juggle Board" by Craig Quat / Play Juggling.

Prodotto per la Cooperativa Sociale UPENDI (Gravina in Puglia) — Pedagogia del Circo e Circo Sociale. Target: bambini, anche neurodivergenti (autismo, ADHD, iperreattività sensoriale): suoni morbidi (sine, niente onde quadre/sega), palette tenue, modalità Zen e errori gentili.


Gameplay

  • 5 corsie orizzontali in legno (plancia a tutta larghezza), ognuna con una pallina colorata glossy (corallo, blu, verde, giallo, viola) a riposo sull'alloggiamento destro.
  • Un bersaglio in alto (HUD a cartiglio) indica quale pallina toccare; la pallina rotola a sinistra e torna (con rotazione realistica attorno all'asse perpendicolare al moto).
  • Devi concatenare i lanci prima che scada il timeout. Difficoltà crescente legata SOLO al punteggio (score_ramp = 8000 → velocità massima).
  • Punteggio per lancio = combo × valore punto (points_per_combo, default 1; combo max 5).
  • Suoni generati proceduralmente in 8-bit (sine morbide); BGM circense AI (Lyria) in OGG.

Modalità di gioco (dialog all'avvio)

Modalità Descrizione
Target (Classica) Raggiungi il punteggio target_score (default 1000) → VITTORIA
Target (Zen) Come Target ma senza countdown né decay combo
Infinita (Survival) A vite: 4 cuori; errore o timeout = 1 cuore; 0 cuori → GAME OVER (ignora il target)

Le modalità sono mutuamente esclusive; lo Zen è disponibile solo per la modalità Target.

Protezione adulti (lock)

Il menù Opzioni è protetto: va sbloccato premendo la sequenza giallo → verde → blu → rosso tra le 5 biglie (pallini che mostrano i colori premuti; reset dopo feedback rosso 2s se la sequenza di 4 è errata).


Requisiti

  • Godot 4.7.x (testato con 4.7.1), renderer GL Compatibility.
  • Per l'APK Android: JDK 17, Android SDK (vedi sotto), template Android.

Eseguire

godot --path .                       # gioco
godot -e .                           # editor
godot --headless --path . --quit-after 120   # smoke test (errori)

Struttura

project.godot                         # viewport 1280×720 orizzontale, GL Compatibility, ETC2/ASTC
export_presets.cfg                    # preset Web e Android
app/
  scenes/app_shell.tscn               # scena iniziale configurata in project.godot
  scripts/app_shell.gd                # coordina menu, selettore modalità e gioco attivo
menus/
  scenes/                             # shell menu e schermate P1, P2a, P3a
  scripts/main_menu_controller.gd     # navigazione e transizioni tra le schermate
  scripts/screens/                    # costruzione delle schermate Home, Juggle e Palestra
  scripts/components/                 # UI e audio condivisi dei menu
  assets/                             # fondali, tendoni, pulsanti e shader dei menu
games/
  juggleboard/
    scenes/                           # scena di gioco, opzioni, lock adulto e fine partita
    scripts/game_controller.gd        # regole, punteggio, combo, timer e modalità
    scripts/components/               # plancia, biglie e bersaglio
    scripts/ui/                       # HUD, cuori, opzioni e overlay
    scripts/audio/                    # BGM e feedback sonori
    assets/                           # texture e BGM di JuggleBoard
  juggling_gym/                       # asset provvisori della futura Palestra di giocoleria
shared/
  settings/settings.gd                # AUTOLOAD Settings: parametri e user://settings.cfg
  audio/                              # fabbrica dei suoni procedurali
  ui/                                 # tema, cornici e decorazioni circensi riusabili
  assets/                             # font e texture condivise
  branding/                           # logo UPENDI e boot splash
docs/                                 # mockup, materiali di design e ARCHITECTURE.md
build/                                # directory ignorata per gli export Web e Android

Il flusso e le responsabilità dei componenti sono descritti in docs/ARCHITECTURE.md.

Impostazioni (shared/settings/settings.gduser://settings.cfg)

Parametri modificabili dal menù Opzioni: tempi (start/min), score_ramp, points_per_combo, target_score, max_combo, decay combo (threshold/rate), difficulty_decay_rate, gentle_errors, game_mode (0 Classica, 1 Zen, 2 Survival).

CRITICO: shared/settings/settings.gd ha const VERSION. Quando si cambiano i default, incrementare VERSION: i file settings.cfg salvati con versione più vecchia vengono resettati ai nuovi default (altrimenti i vecchi valori salvati sovrascrivono i nuovi default).


Build Web

godot --headless --path . --export-release "Web" build/web/index.html

Pubblicare il Web (enne2.net)

cd build/web
scp -r . debian@enne2.net:/home/debian/public_html/autgame/

→ URL: https://enne2.net/pub/autgame/ (Nginx: location /pub/ alias /home/debian/public_html/, autoindex on). Nota: troppe connessioni SSH rapide attivano fail2ban → raggruppa i comandi.

Build APK Android

Setup una tantum (macchina di sviluppo, senza sudo):

# 1) JDK portatile (Temurin 17)
#    ~/.local/opt/jdk-17.0.20+8  (scarica da api.adoptium.net)
# 2) Android SDK in ~/Android/Sdk:
#    cmdline-tools/latest/bin/sdkmanager  (scaricare commandlinetools)
#    sdkmanager "platform-tools" "platforms;android-35" "platforms;android-36" \
#               "build-tools;35.0.0" "build-tools;36.0.0"   (con JAVA_HOME esportato)
# 3) Impostazioni editor Godot (~/.config/godot/editor_settings-4.7.tres):
#    export/android/android_sdk_path = "~/Android/Sdk"
#    export/android/java_sdk_path    = "~/.local/opt/jdk-17.0.20+8"
# 4) Debug keystore (alias androiddebugkey, pass android):
#    ~/.local/share/godot/keystores/debug.keystore
#    (usato anche come release keystore nel preset export_presets.cfg)
# 5) project.godot deve avere rendering/textures/vram_compression/import_etc2_astc=true

Build + firma:

export JAVA_HOME=~/.local/opt/jdk-17.0.20+8
export ANDROID_HOME=~/Android/Sdk
export PATH="$JAVA_HOME/bin:$ANDROID_HOME/build-tools/36.0.0:$PATH"
godot --headless --path . --export-release "Android" build/android/autgame.apk
# output: APK firmato v2/v3 (apksigner) in build/android/autgame.apk

Il preset usa l'export classico (gradle_build/use_gradle_build=false), che richiede i template Android in ~/.local/share/godot/export_templates/4.7.1.stable/ (da Godot_v4.7.1-stable_export_templates.tpz: android_release.apk, android_debug.apk, android_source.zip).

Pubblicare la release su git.enne2.net (API)

TOKEN=$(python3 -c "import yaml;d=yaml.safe_load(open('$HOME/.config/tea/config.yml'));print([l['token'] for l in d['logins'] if l['name']=='enne2'][0])")
# nuova release (o riusa l'id esistente, es. 15 per v0.1):
curl -s -X POST https://git.enne2.net/api/v1/repos/enne2/autgame/releases \
  -H "Authorization: token $TOKEN" -H "Content-Type: application/json" \
  -d '{"tag_name":"v0.2","name":"0.2","body":"..."}'   # -> id RELEASE_ID
# sostituire l'asset APK:
AID=$(curl -s https://git.enne2.net/api/v1/repos/enne2/autgame/releases/$RELEASE_ID \
  -H "Authorization: token $TOKEN" | python3 -c "import sys,json;print(json.load(sys.stdin)['assets'][0]['id'])")
curl -s -X DELETE .../releases/$RELEASE_ID/assets/$AID -H "Authorization: token $TOKEN"
curl -s -X POST .../releases/$RELEASE_ID/assets?name=autgame.apk -H "Authorization: token $TOKEN" \
  -F "attachment=@build/android/autgame.apk"

Note: il CLI tea repos create ha un bug ("GetOrgByName") con owner utente → creare repo via POST /api/v1/user/repos. Avatar repo: POST /api/v1/repos/{owner}/{repo}/avatar con body JSON {"image": "<base64 puro>"}.

Cattura screenshot interna Godot

Per il debugging grafico usare il Viewport Capture interno, non KDE/Spectacle come metodo primario. Il controller menu include flag di verifica:

# P1 (default), P2a, P3a o dialog modalità:
godot --path . -- --capture-menus
godot --path . -- --capture-menus --capture-p2a
godot --path . -- --capture-menus --capture-p3a
godot --path . -- --capture-menus --capture-mode-dialog

Gli screenshot vengono salvati in /tmp/autgame_menu_*.png dopo await RenderingServer.frame_post_draw, quindi includono il Viewport completo senza bordi della finestra.

Workflow sviluppo (pi/Codex)

  • La logica va implementata e verificata direttamente in Godot (test headless + screenshot).
  • Per il polish visivo (tema legno/ottone/circo), mandare gli screenshot dello stato attuale a Codex CLI con prompt chiaro:
    codex exec -C /home/enne2/Dev/autgame --dangerously-bypass-approvals-and-sandbox \
      -i shot1.png -i shot2.png < prompt.txt
    
  • Chiudere sempre il processo godot dopo gli screenshot (altrimenti interferisce).

Asset generati con AI

  • Texture legno e sfondo circo: modello immagini Antigravity.
  • BGM circense: API Gemini Lyria (lyria-3-pro-preview), convertita in OGG Vorbis (Godot non importa .opus) con loop attivo nell'import.
  • Logo UPENDI (boot splash, avatar repo, README): Gemini image / immagine da upendi.it.

© Cooperativa Sociale UPENDI — Gravina in Puglia

S
Description
JuggleBoard Game - Godot 4.7 arcade (reaction & chaining)
Readme
134 MiB
0.3
Latest
2026-09-07 16:35:31 +00:00
Languages
GDScript 80.4%
GDShader 10.7%
Python 8.9%