← Novità

v0.21-dev

2026-07-16 → 2026-07-19 · 7 voce/i di changelog

U1: fix da playtest device (HUD panel, icone stat, testo menu)2026-07-19

Feedback di Ivan sui primi screenshot in-game.

  • [fix] Pannello stats HUD più capiente. HUD.tscn: il Panel da 200×244 → 224×254, contenuti estesi a destra (StatsBox/MoneyLabel offset_right 192→212, DayLabel 195→214) così "Giorno 1" e la riga ora/giorno non toccano più il bordo strappato del cartone (prima ~5px, dentro la cornice da 12px). La dimensione è nella scena; la posizione resta gestita da _apply_safe_area().
  • [change] Rimosse le icone stat nuove a sinistra delle barre. Erano un doppione: l'HUD ha già le icone accanto alle etichette (_insert_stat_icon: bread/sleep/shower/siren). Ripristinato _create_pixel_bar senza la colonna icona; gli asset stat_*.png restano in assets/ui/ per usi futuri.
  • [fix] Testo game over leggibile sul cartone. ReasonLabel (tutto il corpo game over via _build_gameover_body): da bianco+contorno nero a inchiostro quasi-nero in grassettofont_color/font_outline_color Color(0.11,0.06,0.02) con outline_size=1 (contorno stesso colore = tratto più spesso, da feedback "troppo sottile"), font 17→18. Legge come pennarello grosso su cartone invece di "staccare" col bianco freddo o sparire troppo fine. Stesso trattamento da estendere agli altri menu (main/opzioni/baracca) nella pass MainMenu.
  • [test] Compile-check HUD.tscn + HUD.gd: 2/2 OK.

U1: asset cartone generati → importati e collegati (tema texture + HUD)2026-07-19

Ivan ha generato il kit da UI_AI_PROMPTS.md; qui viene importato e messo in gioco.

  • [feat] Asset UI cartone importati in assets/ui/ (chroma-key magenta→trasparente, soglia distanza <120; zero fringe perché downscalati nearest): panel_cardboard, panel_cardboard_dark, tape_strip, tape_corner_a, tape_corner_b, bar_frame, bar_fill, btn_sign_normal/pressed/focus (dal foglio 3 stati), stat_hunger/energy/hygiene/wanted (dal foglio 4×16), card_levelup, banner_event, perk_icons (foglio 4×4, tenuto per R2). Sorgenti magenta originali (incl. varianti tape v2) archiviati in sprites_raw/UI/ (LFS, non committati).
  • [feat] Tema: placeholder → texture vere. default_theme.tres: StyleBoxFlat graybox sostituiti da StyleBoxTexture 9-patch con texture_margin dai valori di UI_AI_PROMPTS.mdCardboardPanel/CardboardPanelDark (12), CardboardButton (normal/pressed/focus 12·9, hover=focus, disabled=normal), StatBar (bar_frame 6·5 + bar_fill 2, tinto via self_modulate), PerkCard (14), BigNotifyBanner (24·8). Ogni UI che già dichiara le type variation (HUD, level-up, pausa, game over, countdown ondata) mostra ora il cartone vero senza altre modifiche.
  • [feat] HUD: scotch e icone stat veri. _make_tape() usa tape_corner_a/b.png (TextureRect, alpha 0.78, nearest) al posto dei ColorRect placeholder di SU-45; _create_pixel_bar() antepone a ogni barra stat l'icona 16px (panino/zzz/saponetta/stella) via _make_icon_rect. Solo presentazione, zero logica.
  • [test] Compile-check mirato: HUD.gd + HUD.tscn + LevelUpScreen .tscn/.gd → 4/4 OK. Tema caricato: le 9 StyleBoxTexture risolvono tutte con texture non-null. Simulazione 9-patch (stretch a misure reali, PIL): corner integri, centro uniforme, bar_fill tinto verde/blu/turchese → docs/ui_restyle/00_theme_applied_sim.png.
  • [docs] Filtro texture di progetto default_texture_filter=0 (nearest) → UI croccante senza config per-file. In assets/ui/ restano inutilizzati btn_sign.png/stat_icons.png (fogli interi: il gioco usa gli slice) e tape_*-v2.png (scelta scotch = v1) — eliminabili (delete file bloccato in sandbox). Non committato (index bloccato); LFS non toccato; resa su device da confermare.

U1: `UI_AI_PROMPTS.md` + tema cartone completo + level-up stilizzato2026-07-19

Sprint U1 (restyle "cartone, scotch e pennarello"), scope sessione concordato: U1.1 + refactor sicuro — MainMenu (168 add_theme_) NON toccato, rinviato.

  • [docs] UI_AI_PROMPTS.md (U1.1) — il manifest asset per Ivan. Stesso formato di BUILDINGS/NPC_AI_PROMPTS.md: protocollo ChatGPT, STYLE ANCHOR con ABSOLUTE RULE sfondo magenta, regole 9-patch e fogli multi-icona, blocchi (A) prompt / (B) avoid, OUTPUT SPEC con px sorgente+finale. Kit completo: pannello cartone chiaro/scuro, 3 scotch, cornice+riempimento barra, 4 icone stat 16×16, carta perk 96×128, bottone-cartello 3 stati, striscione, 16 icone perk. Grana misurata sugli sprite reali (item 16×16 1:1, personaggi 32×32) → UI alla stessa densità. 2 palette proposte (A ocra calda / B grigia fredda), Ivan sceglie generando. Mappa asset→type variation + note import (nearest, mipmaps off, self_modulate coi colori stat di HUD.gd).
  • [feat] Generato 1.1panel_cardboard.png. Primo asset reale del kit U1 in palette A ocra: texture RGB 48×48, sfondo chroma-key magenta puro, outline pixel netto, margini 9-patch 12 px e centro 24×24 uniforme; salvata in assets/ui/ senza ancora collegarla al tema placeholder.
  • [feat] Generato 1.2panel_cardboard_dark.png. Variante scura coordinata per pannelli secondari/game-over: stessa sagoma pixel della 1.1, corpo cardboard mid + shadow, hi-edge chiaro, tape invariato e tre minuscole macchie confinate agli angoli; anche questa resta scollegata dal tema placeholder finché il kit non è completo.
  • [feat] Generato set 2 — scotch decorativo. Aggiunti tape_strip.png (64×20) e i due angoli tape_corner_a.png / tape_corner_b.png (28×28): palette A, corpo pieno su chroma-key magenta, outline marker da 1 px, strappi distinti e pose diagonali opposte. L'opacità resta demandata al modulate runtime come previsto dal manifest.
  • [feat] Seconda variante del set 2. Il comando ripetuto ha prodotto tape_strip-v2.png e tape_corner_a-v2.png / tape_corner_b-v2.png, preservando gli asset canonici: strappi più profondi, sagome alternative e diagonali degli angoli più marcate, con le stesse dimensioni e palette.
  • [feat] Generato set 3 — barra stat. Aggiunti bar_frame.png (64×18, 9-patch 6 px orizzontali / 5 px verticali) con cornice marker e recesso scuro, più bar_fill.png (8×8, margini 2 px) near-white e tinteggiabile via self_modulate. Nessun colore stat è incorporato nel fill.
  • [feat] Generato set 4 — icone stat. Aggiunto stat_icons.png, atlas 64×16 in quattro celle 16×16: panino, tre Z, saponetta con tre bolle e stella da sceriffo a cinque punte. Palette A uniforme, simboli centrati e pronti per quattro AtlasTexture.
  • [feat] Generato set 5 — carta level-up. Aggiunto card_levelup.png (96×128 RGB) in palette A: sagoma di cartone strappato, tape minuscolo in alto a sinistra, angolo ripiegato in alto a destra, recesso icona vuoto 40×40 e area testo inferiore piatta. Sfondo chroma-key magenta puro; asset non ancora collegato alla variation PerkCard.
  • [feat] Generato set 6 — bottone-cartello. Aggiunto btn_sign.png, atlas orizzontale 144×32 RGB in tre celle 48×32 (normal / pressed / focus): stessa sagoma strappata, facce senza testo, tape d'angolo, stato premuto più scuro e piatto, focus con doppio highlight e due tacche di selezione. Margini per cella: 12 px orizzontali / 9 px verticali; non ancora collegato a CardboardButton.
  • [feat] Generato set 7 — striscione eventi. Aggiunto banner_event.png (128×32 RGB) in palette A: fascia di cartone leggermente incurvata, estremità strappate e fissate con due piccoli tape, scuff confinati ai lati e centro pulito per il testo runtime. Margini 9-patch: 24 px orizzontali / 8 px verticali; non ancora collegato a BigNotifyBanner.
  • [feat] Generato set 8 — icone perk. Aggiunto perk_icons.png, atlas 64×64 RGB in griglia 4×4 con le 16 icone del pool R2, nell'ordine del manifest: stomaco/sonno/pelle/carisma, kazoo/gatto magnetico/braccio/sesto senso, suola/patata/ombrello/bravo ragazzo, topo/coperta/furti/nove vite. Ogni simbolo è un doodle marker da 16×16 in palette A, senza label né separatori; non ancora affettato in AtlasTexture.
  • [chore] Bundle handoff UI per Claude. Creato Homeless_UI_assets_1.1-8.zip con i 15 PNG finali del kit, rinominati internamente col numero della richiesta (1.1_8_); incluse entrambe le versioni del set 2 (2_ e 2_v2_), escluse tutte le bozze Imagegen.
  • [feat] Tema: completato lo scaffolding delle type variation. default_theme.tres esteso con le 3 variazioni placeholder mancanti richieste dal brief — CardboardPanelDark, PerkCard, BigNotifyBanner (StyleBoxFlat graybox marroni, stessi nomi degli asset finali → swap = solo ricollegare le texture). Set ora completo: CardboardPanel/CardboardPanelDark/CardboardButton/StatBar(+fill)/PerkCard/BigNotifyBanner/BigNotify.
  • [feat] Level-up stilizzato (stadio successivo del refactor U1.2). LevelUpScreen.tscn: il Panel usa CardboardPanel, la carta CardTemplate usa CardboardButton, inclinazione fissa −1,2° (pivot centrato). Solo presentazione, zero logica (lo script non ha né override né StyleBox inline). Le carte vere di R2 si vestiranno con PerkCard quando esisteranno.
  • [test] Compile-check mirato pulito. check_files.sh su LevelUpScreen.tscn/.gd + HUD.tscn: 4 controllati, 0 falliti. Tema validato a parte (.tres è ignorato da check_files by design): load() OK come Theme, tutte e 6 le type variation registrate (Panel: CardboardPanel/CardboardPanelDark/PerkCard/BigNotifyBanner; Button: CardboardButton; ProgressBar: StatBar). Solo il rumore EOS/GLIBC noto.
  • [test] Asset 1.1 validato. Dimensioni/mode/palette controllati via Pillow (48×48 RGB, 7 colori totali inclusi magenta e tape), quattro angoli magenta esatti, centro 24×24 piatto e prova di stiramento 9-patch 240×120 senza deformazioni o discontinuità. run_check.sh non eseguibile su questo host macOS: nel workspace è disponibile solo il binario Godot Linux ARM64 e non c'è un Godot locale alternativo; nessun file di codice o scena è stato modificato dalla generazione.
  • [test] Asset 1.2 validato. 48×48 RGB, 6 colori, maschera/sagoma identica pixel-per-pixel alla 1.1, centro 24×24 uniforme, quattro angoli magenta esatti e prova 9-patch 240×120 pulita.
  • [test] Set 2 validato. Tutti i PNG sono RGB senza alfa, usano esattamente 4 colori della palette A incluso #FF00FF, hanno angoli/bordo canvas magenta e un'unica componente di tape; corner_b non coincide né con corner_a né col suo semplice mirror.
  • [test] Set 2 variante -v2 validato. Dimensioni 64×20 / 28×28 / 28×28, quattro colori esatti, una componente connessa e bordo magenta continuo; ogni maschera differisce dalla corrispondente v1 e i due nuovi corner non sono mirror fra loro.
  • [test] Set 3 validato. PNG RGB e dimensioni esatte; centro bar_frame 52×8 uniforme in cardboard shadow, centro bar_fill 4×4 uniforme in #F2EEE2, quattro bande estensibili senza variazioni lungo l'asse di stretch. Simulazioni 9-patch verso 240×30 e fill 180×8 pulite.
  • [test] Set 4 validato per cella. 64×16 RGB, 6 colori, ogni icona resta nel proprio tile con 1 px di respiro. Componenti connesse attese: panino 1, ZZZ 3, saponetta+bolle 4, stella 1; nessun separatore o bleed fra celle.
  • [test] Set 5 validato. 96×128 RGB, 7 colori esatti della palette A, quattro angoli magenta, un’unica componente, slot esterno 40×40 con interno piatto e area testo 68×50 uniforme. Piega e tape restano nei corner da 14 px. Nota di integrazione: la richiesta del manifest di tenere anche lo slot da 40 px fuori dal centro estensibile è geometricamente incompatibile con patch_margin = 14; usare la carta alla misura nativa oppure separare lo slot in un overlay prima di ridimensionarla.
  • [test] Set 6 validato per stato e 9-patch. 144×32 RGB, 7 colori della palette A; tre celle esatte 48×32, quattro angoli magenta e centro 24×14 uniforme (light / mid / light). Normal e pressed hanno maschera identica; focus aggiunge soltanto le sei pixel-tacche previste. Le bande estensibili 12/9 sono uniformi lungo il proprio asse in tutti e tre gli stati.
  • [test] Set 7 validato per 9-patch. 128×32 RGB, 7 colori della palette A, quattro angoli magenta e un’unica componente. Centro 80×16 interamente cardboard light, senza decorazioni; tutte le righe/colonne delle bande estensibili 24/8 sono uniformi lungo il rispettivo asse. Bbox soggetto (3,1)–(125,27).
  • [test] Set 8 validato per cella. 64×64 RGB, 7 colori della palette A; sedici tile esatti 16×16 con maschere tutte diverse e almeno 1 px di magenta su ogni bordo, quindi zero bleed. Ispezione nearest 8× superata per ordine e leggibilità; Nove vite contiene un gatto più esattamente nove punti 4-disconnessi.
  • [test] Bundle ZIP validato. unzip -t senza errori, 15/15 entry presenti; tutti i file interni riaperti con Pillow come PNG RGB e confrontati con le dimensioni attese. SHA-256 archivio: 303f18639f8b4943bf48b0839e13129759078df7bfb28727c62642be15f46e6d.
  • [docs] docs/ui_restyle/ creata col piano dei 4 scatti before/after (criterio #4); cattura headless della UI non affidabile in sandbox → before/after da device (fallback U1.3).

Modifiche nel working tree, non committate (in coda al test device del resto dello sprint; index git bloccato in sandbox). Asset LFS non toccati. Rinviato: refactor MainMenu+Opzioni+Baracca (168 add_theme_), pannello game-over/retata, MapOverlay.

Sprint 1 Jira: 13 ticket (notte, FX arresto, UI cartone, rebinding, ghost MP, pulizia arena)2026-07-19

  • [change] Ciclo giorno/notte tarato sulla run V2 (SU-17). GAME_MINUTES_PER_SECOND 2.0→2.4: giorno completo di gioco = 10 min reali (run 30' = 3 giorni), notte 22-06 ≈33% del ciclo. Effetto collaterale noto: il decay stat (per minuto di gioco) è ~20% più rapido in tempo reale, non ribilanciato — da valutare in playtest.
  • [feat] Notte finalmente visibile ma leggibile (SU-16). Tint notturno blu marcato (mai nero pieno) in World.gd + alone di luce additivo che segue il player e si accende gradualmente di notte (la città non ha lampioni: usato il fallback previsto dal ticket).
  • [feat] FX soldi che volano via all'arresto (SU-58). All'arresto completato, 7 banconote/monete pixel art sopra la testa seguono il player, si disperdono e svaniscono (~0.8s, poi queue_free). Effetto locale per-player, nessun RPC nuovo. Nuovo sprite assets/sprites/banknote.png (PIL); monete da coin.png esistente.
  • [feat] Calzino vero dai bidoni (SU-51). Nuovo sprite assets/sprites/sock.png 16×16 (PIL), spawn con la stessa logica degli hot dog da Interactable._use_bin(), emoji 🧦 sostituita dall'immagine ([img]) nel messaggio "CALZINO VECCHIO".
  • [feat] Modalità debug esclusa dalle release (SU-56). DebugPanel (F1 e affini) attivo solo se DEBUG_TOOLS_ENABLED (const in DebugPanel.gd, flippabile pre-build) AND OS.is_debug_build(): nelle export release non esiste. TestBot/autotest invariati (girano in debug).
  • [feat] HUD "cartone, scotch e pennarello", primo step U1.2 (SU-45). default_theme.tres esteso con le type variations CardboardPanel/CardboardButton/StatBar/BigNotify (StyleBox placeholder in attesa degli asset U1.1); dieta di HUD.gd: add_theme_* 65→53, pannelli con rotazione fissa ±1.2-1.4° e scotch placeholder agli angoli, big_notify che entra "sbattuta" (-5°→0°). Non convertiti (leggibilità col placeholder): badge gatto/vino 32px e cornice barra pixel-segmentata.
  • [feat] Rebinding tastiera in Opzioni > Controlli (SU-50). Elenco delle 10 azioni di gioco col tasto attuale, selezione → attesa tasto → assegnazione; conflitto: il tasto viene tolto all'altro comando con warning; SALVA attivo solo a mappatura completa; RIPRISTINA predefiniti da project.godot; persistenza user://keybinds.cfg (pattern Settings), ricarica all'avvio. ESC annulla l'attesa. Solo tastiera (pad/touch fuori scope).
  • [feat] Pausa con soli comandi touch (SU-52). Pulsante pausa nell'HUD (bordo sinistro, _safe_insets() rispettati) visibile solo coi controlli virtuali attivi: richiama esattamente i rami del tasto fisico pausa, stesso menu, semantica MP invariata.
  • [feat] Online: stato "Attendere..." (SU-55). Il MainMenu mostra "Attendere..." dall'attivazione dell'online finché EOS non è pronto (o errore), al posto dell'ambiguo "ONLINE PRONTO". Solo consumo di stato/segnali esistenti, NetworkManager/EOSBridge intatti.
  • [feat] Menu "Note di rilascio" in-game (SU-57). Nuova voce nel MainMenu → schermata scrollabile (CardboardPanel) alimentata da assets/release_notes_it.txt, v0.21 già popolata dal changelog in linguaggio da giocatore. Se il file manca mostra un placeholder. Rischio noto: verificare che il .txt entri nell'export (include_filter, stesso tema di eos_credentials.cfg).
  • [change] Prototipo arena in _arena_stash/ (SU-59). 33 file spostati conservativamente (Arena, WaveManager, RunPlayer+scena, enemies/, weapons/, CoinPickup, RunEndScreen — MoneyCoin intatto); rimossi gli hook arena da NetworkManager (RunManager.run_ended_on_local_session_over), un tipo Weapon destrutturato in LevelUpScreen. Tenuti per R1/R2: RunManager, XPSystem, LevelUpScreen, RunHUD, GameState.arena_mode e gate.
  • [change] Export macOS: permessi ridotti (SU-53). apple_events era true senza alcun uso nel progetto → false; resta il solo disable_library_validation (necessario per la dylib EOS firmata Epic). Annotato: se un giorno si abilita l'App Sandbox servono network_client+server. Da verificare su Mac: build, login EOS, host+join.
  • [feat] MP: fantasmino spettatore pilotabile (SU-31). Alla morte con almeno un altro vivo, il barbone diventa ghost semitrasparente che vola col proprio input e attraversa i muri; due modalità ciclate con interact: LIBERA e SEGUI (plana verso il vivo inquadrato). Non interagisce col mondo e NPC/polizia/loot lo ignorano (fuori dai gruppi player/mp_puppet, collisioni off, filtro in PoliceOfficer); visibile agli altri via canale posizione esistente (≤1170B, zero RPC nuovi); banner HUD coi comandi. SP/tutorial invariati; classifica/REMATCH/punteggio online intatti. Fix post-collaudo: _net_last_alive_is_me() dichiarava l'host "ultimo sopravvissuto" alla morte dell'altro → pausa+pannello globali; ora guard players.size()>1.
  • [docs] ORCHESTRAZIONE.md: nuova sezione "Velocità di esecuzione" (vincolante), dal post-mortem di questo sprint (3h10 per 13 ticket, ~1h persa su interruzione+fix doppio): capsula di contesto nel brief al posto delle letture doc per-agente, mappa di proprietà file → max 2 onde di builder, fixer unico con diagnosi+repro e check "fix già su disco" dopo interruzioni, pattern nohup per il tetto bash 45s e riuso SU_TMP importato, nota economica delega vs inline.
  • [test] Collaudo unico di sprint (sandbox). Compile-check 47 script + 16 scene: 0 falliti reali (solo rumore EOS/GLIBC noto); run SP 30s pulita (49 NPC, calamità ok, orphans=0, quit 0); MP ENet: sync 49/49, ghost verificato dopo il fix (client spectating:true senza pannello, host prosegue). Esiti in TESTLOG.md. NIENTE COMMIT: modifiche in working tree in attesa del test di Ivan. Su device restano: notte/luci e ciclo 10', tutta la UI nuova (cartone, rebind, pausa touch, note rilascio), gate debug su build release vera, entitlements Mac, ghost su 2 dispositivi reali.

Terzo giro Jira: 4 ticket KO sistemati (rifugio serale, monete gatto, hint per-run)2026-07-18

  • [fix] Rifugio SP: dopo l'uso si riattiva SEMPRE alle 19:00 (SU-18, 3° giro). L'uso del rifugio in single player a run attiva non arma più il cooldown reale da 600s: chiude con l'animazione e resta chiuso per ORARIO fino alla prossima apertura serale, countdown incluso (nuovo GameState.minutes_until_next_shelter_open(), corretto anche se chiamato dentro la fascia 19:00–07:00 → target il giorno dopo). Il salto orologio a 07:00 post-nanna fa già da guardia anti re-uso. MP (cooldown 5' di SU-30) e tutorial invariati.
  • [change] Il gatto paga sempre (SU-34, 3° giro). Eliminato il cooldown globale 30s sul drop monete (World.try_consume_cat_coin_drop rimossa): OGNI colpo su civile o poliziotto fa cadere 5 monete da 1$; resta solo la guardia anti-spam sul singolo bersaglio già in zuffa/stordito. Verificato senza modifiche: respawn già lontano da TUTTI i barboni (locale+remoti, 800px) e relay MP client→host già funzionante da SU-13 — a bloccare le monete dei client era proprio il cooldown globale condiviso.
  • [change] Hint onboarding: una volta per RUN, in ogni run (SU-39/SU-41, 3° giro). Rimossa tutta la persistenza "a vita" degli hint (busk_hint_shown_count, clothes_hint_shown via da Settings): busking e negozio vestiti escono al massimo 1 volta a run e si ripresentano in ogni run nuova; il RESET STATISTICHE non c'entra più nulla con gli hint. Trovata anche la causa del trigger folla muto: contava i passanti con l'area dell'elemosina (raggio 48px, bisogna starci addosso) — ora raggio dedicato da 100px sul gruppo "npcs", il trigger "fermo 3s" resta su BegArea.
  • [feat] Nuova voce OPZIONI «SUGGERIMENTI: ON/OFF» (SU-39/SU-41). Toggle unico persistito (Settings.hints_enabled, default ON) che spegne tutti gli hint di onboarding, stesso pattern e stessa pagina delle voci esistenti (tutorial/musica/d-pad).
  • [test] Collaudo sandbox: compile-check 60 script + 25 scene 0 falliti, run SP col bot pulita (49 NPC, zero errori di gioco), grep anti-orfani ok. Smoke MP ENet: handshake e sync iniziale ok, ma il client della sandbox si stacca ~10s dopo il join (host ignaro) — 3/3, nessun errore dai file toccati, NetworkManager intatto: quasi certamente limite ambientale, ma da riverificare in MP live prima di escludere. Su device: transizione rifugio 19:00 dal vivo, monete da lancio client, hint su iPhone.

Secondo giro Jira: 9 ticket KO sistemati + bug monetine2026-07-17

  • [fix] Mappa preclusa durante il game over (SU-11). Il gate su _toggle_map() (unico ingresso: TAB/pad/pulsante touch) scatta dall'inizio del flusso game over, prima del pannello: mappa chiusa e non riapribile finché non si torna a menu/nuova run/rematch. Da spettatore MP resta consentita fino al pannello definitivo.
  • [feat] MP: sync NPC adattivo contro il lag dei client (SU-14). Area-of-interest host-side a 3 tier di rate (10/3.3/1.1 Hz per distanza dal player più vicino, fase sfalsata per NPC), invio solo dei cambiati (delta + heartbeat 2s), payload binario quantizzato (12 B/NPC in int16, chunk ≤48 NPC = 576 B, ben sotto il limite EOS 1170); interpolazione puppet adattiva sull'intervallo misurato (EMA asimmetrica, cap all'estrapolazione, teleport velocity-aware). Stima: −65% pacchetti e −75/80% byte per client; diagnostica F1 arricchita (B/pkt medi, split AoI pieno/ridotto). Collaudo ENet: 49/49 NPC sul client, zero errori di decode.
  • [feat] Rifugio visivamente chiuso fuori orario (SU-18). La stessa state machine visiva del cooldown ora è pilotata anche dall'orario: il rifugio nasce chiuso (fin dal primo frame della run delle 8:00), si anima aprendosi alle 19:00, si richiude quando viene usato e alle 07:00; cartello CLOSED e countdown sincronizzati con lo stato. MP (cooldown 5' di SU-30) e tutorial invariati.
  • [fix] Marker mappa, giro due (SU-28). Marker personale di nuovo CERCHIO pieno e fermo (28 px: via di mezzo tra il vecchio 20 e la goccia bocciata da 38), niente vibrazione, restano aura pulsante ed etichetta "TU"; avversari a 14 px col nome finalmente leggibile (font minimo garantito 13 px: su schermi piccoli scendeva a ~9, era quello il "nome invisibile").
  • [fix] Classifica MP dentro la zona record (SU-32). Rimossa la riga "Record online" dalla UI di fine partita (i dati restano salvati), la classifica coi titoli prende il suo posto nel corpo del pannello con lo stesso font/colore/sfondo; si aggiorna all'arrivo dei punteggi senza duplicarsi, anche se l'host sparisce in attesa della rivincita. SP invariato.
  • [fix] Cooldown monete da gatto ora inviolabile (SU-34). Riscritto su timestamp assoluto (Time.get_ticks_msec) al posto del float decrementato per-frame dietro gate di rete; aggiunta guardia anti-rientranza su NPC.hit_by_cat (ricolpire lo stesso civile durante la zuffa rieseguiva overlay/SFX/broadcast). Un drop ogni 30 s globale, civili e polizia condividono lo stesso timer.
  • [change] Hint busking anche in movimento (SU-39). Nuovo trigger cumulativo: ~4,5 s totali nella run passati con ≥2 passanti nel raggio, fermo o camminando (non si azzera); convive col vecchio "fermo 3 s", stessi tetti (1/run, 2/vita).
  • [fix] Hint negozio vestiti: trovato il vero colpevole (SU-41). Il trigger era sano (poll per-frame, reagisce anche ai valori del DebugPanel): il flag one-shot era già consumato dai run precedenti E il bottone RESET STATISTICHE non azzerava gli hint (chiamava solo HighScore.reset_all() + tutorial). Ora il reset azzera anche gli hint busking/vestiti: dopo un reset gli onboarding si ripresentano.
  • [change] make_dmg.sh: dmg accanto alla .app e pulizia (SU-42). Senza output esplicito il dmg nasce nella stessa cartella della .app; a fine processo hdiutil verify e la .app originale viene eliminata (tanto è nel dmg).
  • [fix] Monetine dell'elemosina sempre a dimensione piena (SU-49). La colpa non era dello scatter monete ma dell'ottimizzazione SU-14 del 1° giro: la cache di scala dello SpeechCanvas restava al valore iniziale −1 alla prima reazione di un NPC → moneta a scala 1.0 invece dello zoom reale. Ora _spawn_coin_fx() legge lo zoom fresco dal viewport.
  • [test] Collaudo sandbox: run SP, run SP dedicata al rifugio e MP ENet host+client tutti puliti (nessun errore script di gioco; 49/49 NPC sul client col nuovo formato binario). Dettagli in TESTLOG; rese visive e lag EOS reale da provare su device.

Sprint 1 Jira: 20 ticket lavorati (gameplay SP, sync MP, UI/mappa, controlli, packaging)2026-07-16

  • [fix] Il giorno ora avanza dormendo al rifugio (SU-10). L'orologio naturale era già corretto; il bug era in Interactable._use_shelter() che resettava l'ora alle 7:00 senza mai toccare day. Ora usa la stessa logica di DebugPanel._jump_morning(): risveglio con ora ≥7 = giorno dopo.
  • [feat] Rifugio aperto solo la sera in single player (SU-18). Fascia 19:00–07:00 (GameState.is_shelter_open_now()); sul rifugio cartello CLOSED + countdown HH:MM all'apertura (riusa gli asset del cooldown Sprint 2); fuori orario ingresso bloccato con «🚪 IL RIFUGIO APRE ALLE 19:00 — MICA È UN HOTEL!». Solo SP a run attiva: MP e tutorial esclusi.
  • [change] Busking: cooldown 120s → 60s (SU-38). Solo il cooldown (BUSK_COOLDOWN in Player.gd), guadagni intatti; l'indicatore "Pronta tra…" è dinamico e si adegua da solo.
  • [feat] Valvola anti-softlock economia: colpire un NPC col gatto fa cadere 5 monete da 1$ (SU-34). Riusa MoneyCoin/World.net_scatter_coins; il civile colpito sparisce a fine zuffa e ricompare lontano (mirror del pattern polizia pick_police_respawn_point(800)); cooldown anti-farm globale 30s (World.try_consume_cat_coin_drop); in MP monete e respawn li decide l'host (guardia is_net_puppet anti-raddoppio).
  • [feat] Nuovo loot bidoni: CALZINO VECCHIO (SU-35). 15% (ricavato dal bucket "niente": 50%→35%), +10 igiene con suono lavata, notifica «🧦 CALZINO VECCHIO! Puzza meno di te: +10 IGIENE».
  • [docs] Ubriaco più lento (SU-46): già implementato, verificato senza doppioni (−30% velocità in _handle_movement per tutta la durata della sbronza). Nessuna modifica.
  • [fix] MP: le scorregge ora si vedono e si sentono anche sugli altri schermi (SU-12). Relay World.net_fart_cl_fart_fx sul puppet: nuvola + bolla + audio posizionale (stesso pattern della trombetta busking); fix collaterale: la bolla ora scorre e sparisce anche sui puppet.
  • [fix] MP: il gatto che colpisce un passante è replicato sui peer (SU-13). net_npc_cat_hitNPC.show_puppet_cat_hit() (nuvola animata via _net_puppet_process, sprite nascosto, audio posizionale); il panico di massa scatta anche per i lanci dei client; respawn del civile coerente sui puppet (snap >200px). Fix: la nuvola sul puppet colpito in locale prima restava congelata.
  • [feat] La scoreggia rallenta anche i barboni avversari vicini (SU-21). Host-authoritative su raggio FART_SLOW_RADIUS=150: 45% per 2.6s come la polizia, lanciatore escluso, vittima avvisata con flash verde + notifica comica. Sempre attivo (niente perk per ora).
  • [change] Lag percepito dai client MP (SU-14, primo giro): ottimizzato NPC._process sui puppet (niente ricalcolo del SpeechCanvas senza bolla/FX — con ~50 puppet era lavoro sprecato ogni frame) + nuova sezione RETE nel pannello F1 (pacchetti/s, KB/s in/out, conteggio npc/puppet, solo in MP) per misurare su device prima di toccare rate/interpolazione.
  • [fix] Game over con la mappa aperta: stato incoerente risolto (SU-11). La mappa fullscreen viene chiusa in entrambi i flussi (game over immediato e post-spettatore), la musica torna pausabile e il pannello parte pulito.
  • [fix] Niente più «stai morendo di fame» sopra il game over (SU-48). Gate centralizzato HUD._is_run_over_for_me() (pannello finale visibile o spettatore) su avvisi periodici di sopravvivenza e hint; le notifiche globali dello spettatore MP restano.
  • [feat] Numero di versione in gioco (SU-43). application/config/version = "0.21-dev" in project.godot + label discreta in basso a sinistra nel menu principale (safe-area iPhone), letta da ProjectSettings: le prossime release cambiano solo il setting.
  • [change] Mappa: marker rifatti (SU-28 — priorità #1 del playtest). Marker personale inconfondibile: goccia pixel-art 7×7 rossa con bordo scuro, doppio anello "radar" giallo pulsante e etichetta TU sempre visibile (mai spento, in SP e MP); rombi avversari più piccoli (2.8 vs 5.5) col nome a font clampato; scala dei marker relativa al viewport per leggibilità su iPhone.
  • [feat] Onboarding busking (SU-39). Fermo ≥3s vicino a passanti senza aver mai suonato → «💡 Psst! Premi [B] e suona la trombetta: i passanti PAGANO!» (glifo dalla piattaforma corrente); max 2 volte a vita (persistito in Settings, sezione hints), max 1 a run, mai nel tutorial.
  • [feat] Negozio vestiti finalmente capibile (SU-41). Prompt esplicito «[E] Vestiti puliti: +IGIENE ($20)»; hint una-tantum quando igiene <30 e soldi ≥20 («🤢 PUZZI COME UNA DISCARICA…») + lampeggio d'attenzione della freccia verde del negozio (Interactable.pulse_attention).
  • [feat] Tasti comodi vicino a WASD (SU-40). F = scoreggia/lancio gatto, B = busking, aggiunti come PRIMI eventi senza rimuovere G/M; InputManager.KEYBOARD_LABELS, prompt in-game, tutorial e schermata COMANDI aggiornati. Remap configurabile nelle Opzioni: follow-up.
  • [feat] Opzione D-PAD DIGITALE (SU-36). Toggle in Opzioni accanto a DIMENSIONE CONTROLLI (default OFF, persistito): InputManager.quantize_8dir() (snap a 45°, deadzone 0.3) applicato allo stick touch (pressione piena, zero gradazione) e allo stick analogico del pad fisico in Player._handle_movement; il d-pad fisico era già mappato.
  • [change] Pad virtuale ridisegnato in pixel-art via codice (SU-37). Ottagoni "chunky" con bordo scuro spesso al posto dei cerchi lisci (_ChunkyShape in VirtualControls, niente PNG nuovi/import); frecce a croce sulla base se D-PAD DIGITALE è ON; aree di tocco, safe-area e DIMENSIONE CONTROLLI invariate. Gli asset veri arriveranno con l'epic P1.
  • [feat] Warm-up EOS all'avvio (SU-27). NetworkManager.warm_up_online() fire-and-forget chiamato (deferred) dal MainMenu: riusa EOSBridge.setup() senza toccare il plugin, fallisce in silenzio se mancano credenziali/lib, l'init-on-demand resta come fallback/retry; se il login riesce, prefetch una-tantum della lista lobby (cache TTL 12s) così CERCA PARTITA/PARTITA RAPIDA partono subito; riga stato online aggiornata via ready_changed.
  • [feat] Rifugio MP: cooldown 10 → 5 minuti + feedback chiaro (SU-30). In sessione MP use_cooldown=300s (allineato al countdown del cartello via WorldGenerator); all'uso «🛌 HAI RIPRISTINATO TUTTO! Fame, igiene e sonno al top». In SP restano 10 min + fascia serale SU-18.
  • [feat] Classifica di fine partita con titoli (SU-32). Ogni peer conta gatti a segno, scorregge, $ di elemosina, $ totali (ScoreSystem/CatProjectile/Player) e li invia con lo score finale (+4 int su _cl_final_score, default sicuri); il pannello classifica assegna 🐱 MIGLIOR LANCIAGATTI, 💨 RE DELLA SCOREGGIA, 🙏 PIÙ ELEMOSINE, 💰 PAPERONE DEI BASSIFONDI (max di categoria, parimerito → più punti totali, niente titolo a 0). Solo MP.
  • [docs] Script dmg con scorciatoia Applications (SU-42). Nuovo tools/release/make_dmg.sh (da lanciare sul Mac): impacchetta la .app esportata in un dmg UDZO con symlink /Applications accanto, drag&drop immediato per chi scarica.
  • [test] Compile-check mirato 58/58 script + 25/25 scene OK (unici errori: cascata EOS nota della sandbox); run SP col bot OK (calamità, game over pulito, orphans=0); run MP ENet host+client OK (49 NPC sincronizzati su entrambi, ultimo-vivo, score esteso senza errori RPC). Dettagli in TESTLOG. Da provare su device: warm-up EOS reale e prefetch lobby, replica live scorregge/colpo gatto/slow, resa visiva dei controlli touch ridisegnati e D-pad col pad fisico, marker mappa su iPhone, dmg generato con make_dmg.sh. Nota sandbox: check_scripts.gd oggi crasha (Opcode 31) — usati check mirati equivalenti.