Sprint, dodicesimo giro2026-08-08
- [feat] SU-314 — la cifra dei soldi è ora l'informazione più leggibile dell'HUD.
font_size dedicato 34 su MoneyLabel (non ereditato dal tema, come chiedeva il ticket), Panel allungato da 276 a 326 e orologio, giorno e timer della run spostati sotto di conseguenza: il pannello cresce, non si accavalla. 📌 L'icona del sacchetto passa da 22×22 a 44×44, cioè cresce *insieme* alla cifra invece di restarle accanto minuscola — è il criterio che il ticket chiedeva esplicitamente. Numeri del provino (shot_su314_money.gd, 2556×1179, cifra a quattro zeri): le distanze sono misurate sui rettangoli veri (get_global_rect, non i numeri sorgente) — stats→money 2,8, money→time/day 6,5, time→run_timer 3,6, tutte positive, nessuna sovrapposizione; e uno scan a inchiostro sull'immagine catturata dà cifra alta 77 px e icona 67 px, cioè l'icona sta all'87% della cifra. Guardato: $1234 si legge a colpo d'occhio, il sacchetto è proporzionato, il pannello non sfora. - [fix] SU-320 — la schermata del nome a fine partita non si sbaglia più. Lettere da 42 a 56 e passo degli slot da 52 a 84; frecce da 46×34 a 64×52 (sopra il minimo di 48 px logici per lato); CONFERMA da 180×46 a 240×60; il box del game over su touch da 250 a 350 per far posto. 📌 La difesa è spaziale, e non c'è un secondo passo di conferma: ▲ e ▼ restano vicine fra loro — sbagliare l'una per l'altra è innocuo, si corregge con un tocco — mentre l'aria vera sta fra le frecce e CONFERMA, che è il tasto che chiude la partita e da cui non si torna indietro. ⚠️ Il punto che il primo giro aveva sbagliato, ed è istruttivo:
TOUCH_OK_Y era 204 perché il conto sorgente 204 − (104 + 52) dà 48 tondi, esattamente la soglia del ticket. Ma il pannello del game over è inclinato di qualche grado, e la distanza misurata sui rettangoli reali era 44,4 — sotto soglia. Corretto a 214, che misura 54,4. Su questi numeri non si fa aritmetica a mente: si legge il provino, e ora il commento nel codice lo dice a chiare lettere. Provino su tre scenari (telefono orizzontale, telefono verticale, tablet): lato minimo bersaglio 52 in tutti e tre, distanza freccia→CONFERMA 54,4 in tutti e tre, margini sopra e sotto del box sempre positivi. Guardato: la schermata è leggibile a distanza di braccio, CONFERMA è nettamente staccato e resta dentro il pannello sia in orizzontale sia in verticale. Non toccati GameState.money, money_changed, il salvataggio del punteggio e la classifica; la scrittura diretta delle lettere da tastiera resta rimossa (SU-135). ⚠️ Come è finito questo lotto: l'agente che lo lavorava si è impiantato dopo aver scritto il codice — ultima scrittura alle 18:21, poi due ore e un quarto di silenzio, con l'ultimo passo dichiarato «stash temporaneo dei 3 file per scattare la versione originale». È stato fermato dall'orchestratore, che ha verificato nessuno stash lasciato in giro e index pulito, e ha poi eseguito di persona compile-check, provini e la correzione dei 44,4 px. Il codice era tutto su disco: niente è andato perso. 📌 Lezione operativa: un git stash per fare il confronto «prima/dopo» è pericoloso quando gli altri lotti dello stesso sprint sono già committati — il confronto va fatto scattando prima di modificare, o da un git show HEAD:<file> in una copia separata. - [feat] SU-315 — su telefono la carta perk selezionata cresce, le altre due restano piccole ai lati. Strada B, la preferenza esplicita di Ivan: su telefono (
VirtualControls.is_phone_screen(), la soglia fisica preesistente di SU-225) la carta selezionata cresce al centro fino a ~88% dell'altezza disponibile, le altre due si stringono a scala fissa 0,62× e restano dritte ai lati, in base alla posizione relativa alla selezionata. 📌 Su desktop e tablet la prova che nulla è cambiato non è «a occhio»: i PNG sono identici bit-a-bit prima e dopo, confrontati con sha256 e riverificati dall'orchestratore — è il criterio del ticket dimostrato nel modo più forte disponibile, e vale più di qualunque lettura del diff. Numeri: la carta selezionata passa da scala 1,15 a 2,143 (+86% lineare), il nome da ~26,5 px a ~49,3 px, effetto e pips da ~22,9 px a ~42,7 px; le laterali restano visibili al 100% (0 px di occlusione) in tutti e cinque gli scenari provati, la selezionata resta dentro lo schermo (margine ~86 px su 768) e l'etichetta «auto» sta 18 unità sopra il bordo carta, mai fuori. 📌 Due aggiustamenti che il ticket non elencava ma senza i quali il layout si rompeva: la y dei bottoni RIPESCA/VETO, che sarebbero finiti sopra la carta gigante, e la compensazione dell'offset dell'etichetta «auto», che sarebbe uscita dal bordo. ⚠️ Il punto da giudicare, ed è il candidato numero uno a un KO: il ticket poneva una condizione — «*purché resti facile confrontare le tre carte fra loro*» — e con la selezionata a 2,143 contro laterali a ~0,71 il rapporto è circa 3 a 1. Guardando lo scatto, delle laterali si leggono icona e nome, ma la riga dell'effetto è al limite: confrontare davvero i tre effetti richiede di selezionarli uno per uno. Le carte non sono nascoste e il criterio scritto è rispettato, ma se per Ivan «confrontare» vuol dire leggere i tre effetti insieme, la taratura va rivista (la manopola è la scala 0,62× delle laterali). Non verificato: device o simulatore reale; il caso con 1-2 carte pescate; un fotogramma a metà animazione d'ingresso; RIPESCA/VETO su telefono con scatto dedicato; e il notch vero di un iPhone — qui la safe-area legge la barra dei menu del Mac, quindi il margine misurato è un limite *inferiore* e su un telefono vero la carta crescerebbe un filo di più. - [fix] SU-318 — il quaderno si scorre col dito, e si scopre che la rotellina era rotta pure lei. ⚠️ La causa vera non è nessuna delle due sospettate dal ticket, ed è stata trovata *prima* di scrivere il rimedio, con un provino che inietta eventi veri e legge
scroll_vertical. Non era il root che consuma l'input: _input() escludeva già esplicitamente touch, drag e mouse dal set_input_as_handled(). Il colpevole era _text, il RichTextLabel dentro _scroll: non aveva mai avuto un mouse_filter assegnato, quindi restava al default STOP, e da figlio «sopra» nell'ordine di hit-test intercettava lui tap, trascinamento e rotellina prima che arrivassero allo ScrollContainer. 📌 Cioè il quaderno non si scorreva col dito, ma non si scorreva nemmeno con la rotellina: il ticket aveva visto metà del difetto — e chi avesse applicato solo il rimedio suggerito avrebbe lasciato l'altra metà in piedi. Sbloccare _text però non basta, perché uno ScrollContainer nudo non traduce da solo InputEventScreenDrag in scorrimento: servono due mosse, _text.mouse_filter = MOUSE_FILTER_IGNORE più il trascinamento diretto portato da MenuScrollList._on_scroll_gui_input — stessa soglia DRAG_SLOP di 12 px e stesso schema a stati, perché due gesti leggermente diversi nello stesso gioco si sentono. _scroll_by() e i suoi chiamanti (frecce, pad) non toccati, solo affiancati: diff di sole aggiunte, +78 righe. Numeri del provino rilanciato dall'orchestratore (sezione STATISTICHE, 1200×540): trascinamento di 240 px 0 → 34 (era 0 → 0), rotellina 0 → 34 (era 0 → 0), _scroll_by(64) 0 → 34 invariato, micro-tocco di 3 px sotto soglia resta 0 — cioè cambiando linguetta non si scorre per sbaglio. Il 34 è il fondo: il contenuto è 463 su una box da 428. Guardato, non solo misurato: nello scatto in cima l'ultima riga leggibile è «Carte nel mazzo: 9/16» tagliata a metà, e dopo il trascinamento il titolo di testa è scorso via e in fondo compare «Fermate aperte: 7/7», che prima stava fuori dal riquadro. 📌 Il percorso «quaderno aperto dall'HUD in partita», che il ticket chiedeva di verificare, non esiste: il Quaderno si apre solo da MainMenu._open_quaderno() — verificato col grep anche sul sinonimo inglese. Non ripetuto su CARTE/IMPRESE (il meccanismo è generico) né a risoluzione tablet dedicata. - [feat] SU-316 — i controlli virtuali svaniscono da soli e tornano al tocco, ma i pulsanti di sistema restano. Tutti i nodi disegnati (joystick e diamante dei tasti) sono diventati figli di un nuovo
_fade_root, e a sfumare è solo il suo modulate.a. 📌 Il perché di quella struttura è tutto qui: il booleano visible del CanvasLayer — quello che HUD.gd legge per decidere di pausa touch e pulsante mappa — resta calcolato esattamente come prima e non viene mai toccato dal fade, ed è così che i due pulsanti di sistema restano sempre visibili senza modificare HUD.gd, che in questo sprint era di un altro lotto. Timing: 2,0 s di inattività → dissolvenza 0,4 s → alpha 0,15. ⚠️ Scelto l'alone tenue e non la sparizione totale (il ticket lasciava decidere): un controllo del tutto invisibile su un telefono nuovo non si trova più, e l'impronta dice dove appoggiare il pollice. 📌 Il criterio che rende o rompe la feature — «il primo dito non si perde» — è stato verificato e non dedotto: il tocco non è mai subordinato all'alpha, e dopo il fade un tocco nuovo muove il personaggio nello stesso frame in cui i controlli tornano opachi (fade_alpha=1.000 e move_down=true a un frame di distanza). Guardati i tre PNG a 2556×1178: nel pieno il joystick ha frecce nere e pomello bianco e i tasti sono saturi col bordo nero; nell'alone restano un contorno appena percettibile e tinte spente — e nello stesso scatto pausa e pulsante mappa sono identici, a piena opacità. Regole vecchie invariate: gamepad collegato → niente controlli, finestra modale aperta → nascosti (SU-224). ⚠️ Buco dichiarato: il provino gira su HUD.tscn isolato, su fondo grigio uniforme — non nel mondo vero né nel tutorial, che il ticket chiedeva. Su selciato e palazzi l'alone può leggersi diversamente, ed è la prima cosa da guardare su device. Non provate nemmeno due dita insieme (una ferma durante il fade, una nuova). - [change] SU-317 — su telefono la modalità AUTO dà controlli MEDI e testo GRANDE, e altrove non cambia niente.
_auto_scale() e _auto_text_scale() hanno un solo early return in testa: se is_phone_screen() — la soglia fisica preesistente di SU-225, non toccata, cioè «la soglia già usata dal calcolo automatico» che il ticket chiedeva — restituiscono i valori fissi 1.35 e 1.3, che sono gli stessi di "medium" e "large" scelti a mano in Opzioni: un telefono in AUTO deve vedersi come uno che ha scelto quelle taglie, non un terzo valore calcolato a parte. 📌 Il criterio «su tablet e desktop i valori NON cambiano» è stato dimostrato sul codice, non sulla misura, e la differenza conta: fuori dal ramo telefono il corpo delle due funzioni è invariato bit per bit (_auto_text_scale resta return 1.0), quindi l'uguaglianza vale per costruzione. ⚠️ La sonda numerica dava invece tablet 1,2735 → 1,3277, un numero che a prima vista falsifica il criterio: è rumore: su questo Mac lo schermo reale ritaglia le finestre-test in modo non riproducibile fra due giri, quindi i due valori rispondono a input diversi, non a codice diverso (desktop, che usa la stessa finestra in entrambi i giri, resta identico allo stesso bit: 1,7691 → 1,7691). È la regola «prima il codice, poi la misura» applicata a un caso in cui la misura avrebbe fatto bocciare un lavoro giusto. La sonda resta in repo (scripts/tools/probe_su317_autoscale.gd) per il riuso. Cambio di default, non opzione nuova: nessuna voce aggiunta a Opzioni, chi ha già scelto una taglia a mano non viene toccato, e le etichette che spiegano cosa vuol dire «auto» su telefono passano da MEDIO/NORMALE a MEDIO/GRANDE. Settings.gd contiene solo commenti aggiornati: zero righe di codice. content_scale_factor (SU-207) e content_scale_mode (SU-222) non toccati. - [fix] SU-319 — ai bordi della mappa il barbone torna al centro, e fuori dai confini non c'è più il vuoto. Strada A del ticket, in due pezzi. (1) Il margine è ricavato dall'inquadratura, non è un numero fisso: i limiti camera superano i confini di
BORDO_FRAZIONE = 0.66 della *mezza inquadratura* (forbice 48-1200 px), così su telefono in orizzontale il margine X nasce da solo più largo del margine Y — che è esattamente il caso peggiore citato dal ticket. Il conto è verificabile a mano: col clamp attivo il barbone appoggiato al confine finisce a (1−0.66)/2 dello schermo, cioè a un terzo esatto. I limiti si rifanno su size_changed, quindi la rotazione dello schermo è coperta. (2) Il riempimento: fuori dai confini prima non c'era nulla — sfondo e strada del generatore finiscono su world_size — e adesso un ColorRect «BordoMondo» a z_index −60 prosegue lo stesso asfalto con UV calcolate dalle coordinate di mondo, quindi stessa fase di tiling e zero cucitura, spegnendolo nel buio su una sfumatura lunga quanto il margine; texture e tinta sono lette a runtime da RoadTile/RoadBackground. 📌 Scartate e perché: un numero fisso di px (fallisce sul 21:9); allargare i nodi del generatore (sposta la fase del tiling e la cucitura si vede); la strada B del ticket (chiede arte nuova, che qui è un ticket suo). Numeri del provino (shot_su319_bordi.gd, 2554×1178, seme 424242): limiti prima L0 T0 R1632 B1632, dopo L−219 T−101 R1851 B1733; posizione del barbone ovest 1,2% → 34,1%, est 65,9%, nord 35,5%, sud 64,5%, angolo NO 34,1/35,5%, centro 50/50, tutorial bordo ovest 34,1% — tutti dentro la fascia centrale 33,3-66,7%. ⚠️ Guardato, non solo misurato (è la contromisura al fatto che gli ultimi tre giri di KO erano criteri visivi misurati invece che visti): nel PRIMA il barbone è mezzo tagliato dal margine sinistro e finisce dietro il pannello HUD, praticamente invisibile; nel DOPO è leggibile a un terzo con la città intera davanti. Profilo di luminanza sulla riga all'86% dell'altezza: 39 al margine → 43 → 54 → 75 → 85 al confine del mondo, senza scalini; nel punto più buio la texture resta leggibile (L min 31,7 / max 49,3), cioè selciato in ombra e non vuoto nero, e di notte il cerchio-lanterna illumina anche il fuori mappa mostrando selciato continuo. Nessuna riga di rete, RPC o snapshot toccata: la telecamera è locale, e MapOverlay legge generator.world_size, che non cambia. ⚠️ Da far vedere a Ivan: nel tutorial il bordo ovest ora mostra una fascia scura dove prima c'era corsia — è coerente col fondo del tutorial (#17151F, lo stesso di sopra e sotto la striscia) e lo sfondo è stato esteso da ±400 a ±2000 px apposta, ma resta un cambio di resa. 📌 BORDO_FRAZIONE è l'unica manopola: se il barbone si volesse ancora più centrato basta alzarla verso 1.0 (a 1.0 il confine cade esattamente a metà schermo). Non verificato: device reali, rotazione a run in corso, una partita MP a due peer, e il suolo a TileMapLayer (terrain_tilemap_enabled, spento di default) dove il riempimento ripiega su street.png. - [feat] SU-323 — ogni quartiere garantisce almeno un oggetto per ogni bisogno, e a FUMAROLA la panchina non manca più. 📌 La rete di sicurezza della fontana non è stata affiancata da un secondo meccanismo — è stata generalizzata, che è precisamente ciò che il ticket chiedeva: una tabella
MINIMI_GARANTITI (tipo, fase, min) letta da un solo giro _garantisci_minimi(). Nella stessa tabella è finita anche la rete gemella dei bagni pubblici (SU-181), che era proprio il secondo if parallelo da eliminare: il ticket ne ha chiuso uno preesistente oltre al proprio. Due fasi, perché i conteggi maturano in momenti diversi: la fontana resta PRIMA delle piazze (SU-175 — il suo posto è il centro del piazzale e l'arredo deve poterla evitare), gli altri alla fine; e la riga del bagno è la prima della fase finale perché è l'unica che pesca dall'rng, così la sequenza dei dadi resta identica a prima e le mappe che già stavano in piedi non cambiano. Tipi garantiti, col criterio «copre un bisogno gratis, o è l'unico modo di coprirlo»: panchina (energia, unica fonte gratuita), fontana (igiene), cestino/bidone (economia — nel codice sono lo stesso Type.BIN, due nomi italiani per un oggetto solo), bagno pubblico (igiene, unica alternativa ai $20 dei vestiti). 📌 Esclusi e motivati: rifugio, hot dog, gelati, liquori, vestiti e pensilina hanno già una garanzia più a monte nel footprint riservato di _promote_special_footprints(), e duplicarla qui sarebbe il doppio meccanismo vietato — il censimento li misura comunque come colonna di controllo e restano sempre ≥1; fuori anche il gattile (gimmick di GATTOPOLI) e il soup van (evento, non generazione). ⚠️ Scartata la variante bench_blocked.png che il ticket suggeriva: è il visual che dice «panchina bloccata dallo spazzino» (SU-115), e su una panchina funzionante mentirebbe spegnendo quel feedback; il «mal messa» arriva invece dalla geometria — angoli, poi mezzerie, poi centro, con ripiego sull'angolo di marciapiede di un capannone. I numeri, dal censimento rilanciato dall'orchestratore (su323_censimento.gd, 10 semi × 8 quartieri, base 424242, 19,5 s): senza rete FUMAROLA aveva 0 panchine e 0 fontane in 10 semi su 10 — il difetto del ticket è quindi confermato quantitativamente, non era un'impressione — e comparivano buchi anche a BRINA (1/10), NOTTEFONDA (1/10) e sui bagni a COLLINA (6/10); con la rete accesa il minimo su tutti i semi è ≥1 su ogni colonna garantita in tutti e otto i quartieri, e a FUMAROLA la panchina forzata resta una sola (min 1, max 1) che cade in punti sempre diversi. Forzati finiti dentro un muro: 0 su 80 città. Determinismo: firme IDENTICHE fra due generazioni dello stesso seme in tutti e otto i quartieri — è il vincolo multiplayer, host e client generano la stessa città. Non intrusività: dove la rete non forza nulla (10/10 semi a mercato, gattopoli e solleone) la città è identica a quella con la rete spenta. Quartieri.gd contiene solo commenti nuovi: zero moltiplicatori economici toccati, come imponeva il ticket. Non verificato: nessuna run del bot, nessuna prova MP reale, nessuna misura di prestazioni; e resta da guardare a occhio il caso in cui su un piazzale già pieno il forzato si sistema a 34 px da un altro arredo invece dei 44 abituali. - [docs] SU-322 — lo zoom col pinch si può fare, e la premessa del ticket era sbagliata: mondo e UI sono GIÀ separati. Il ticket dava per scontato che zoomare avrebbe ingrandito anche l'HUD, e chiedeva se servisse l'architettura di SU-241 (mondo in un SubViewport). 📌 Non serve: HUD (
HUD.tscn:25-26, layer 10, istanziato in Main.tscn:43 fuori dalla camera), MapOverlay, VirtualControls, RunHUD, LevelUpScreen, SuperCeremony, DebugPanel e FxSpawner stanno tutti su CanvasLayer, e nessuno ha follow_viewport_enabled — l'unico nel progetto è FinestreLayer (World.gd:4381), che deve seguirlo. Quindi camera.zoom non tocca già oggi un pixel di UI; ciò che scala mondo e UI insieme è content_scale_factor (VirtualControls.gd:495-509), che è un'altra faccenda. SU-241 risolve il fill rate ed è in gran parte già coperto da SU-222: resta un buon ticket, ma non è un prerequisito di questo. Strada consigliata: (b), solo camera.zoom — il SubViewport vorrebbe dire riagganciare le 18 chiamate a get_canvas_transform/get_final_transform sparse fra World/NPC/Player/FxSpawner, tre shader in spazio FRAGCOORD e ~50 provini in scripts/tools/. ⚠️ «Economica sul codice» non vuol dire gratis, ed è il punto che il ticket non sospettava: due delle rotture non sono estetiche ma regole di gioco travestite da resa. night_light_radius è in px schermo (World.gd:37, e il commento a :80 lo dice) e arriva allo shader non scalato (:3780, :4416): zoomando fuori la lanterna illumina 2-3 volte più città, cioè si comprerebbe un vantaggio notturno con una manopola visuale. E _pick_hidden_cat_spawn (:1819) / _pick_magnet_cat_spawn (:1926) misurano «fuori schermo» sullo zoom corrente girando solo sull'host, quindi in multigiocatore lo zoom dell'host deciderebbe dove compaiono i gatti per tutti; _cat_spawn_is_on_screen (:2129) invece è per-peer ed è corretta così — verificata e da non toccare. 📌 Il prezzo vero è un terzo, e non si aggiusta: si decide. interact_label (Player.gd:609-614) e i prompt degli interagibili sono Label di mondo: a zoom 1.5 rimpiccioliscono del 40% e il font è pixel, e sotto ~1 px di schermo per pixel-di-disegno il tratto sparisce (la soglia è scritta in VirtualControls.gd:471-481). È lo stesso tipo di difetto che ha già bocciato SU-207. 📌 Il pinch non ha bisogno di toccare VirtualControls.gd: quel file rivendica il dito solo se cade nella metà sinistra entro JOY_BASE_R*2.2, o su un tasto entro BTN_R*1.35 (:749-782), e non consuma gli altri tocchi — quindi un handler in _unhandled_input vede per costruzione solo le dita libere, e la «zona franca» che il ticket chiedeva esiste già. Vietato metterlo in _input: l'autoload verrebbe dopo la scena e ruberebbe il dito al joystick. 📌 Sei tacche fisse (1.5 / 1.8 / 2.1 / 2.5 / 3.0 / 4.0, default 2.5) e non pinch continuo, per una ragione tecnica e non di gusto: il continuo invalida ogni frame la cache _last_canvas_scale delle bolle NPC (NPC.gd:336-357) rifacendo font_size e layout di ~50 Label, e fa «vibrare» la grana del dithering notturno, che è round(pixel × scala) (World.gd:3811). ⚠️ Nota di stato che ha cambiato i conti a metà analisi: SU-319 è atterrato mentre l'agente leggeva — World.gd è passato da 5268 a 5424 righe, _setup_camera() sta ora a :3554 e delega a _aggiorna_limiti_camera() (:3569), e _mezza_inquadratura() (:3534) è un quinto lettore di camera.zoom che il ticket non elencava. Effetto collaterale utile: il pavimento tecnico dello zoom-out su iPhone è passato da 1.02 — cioè non si poteva zoomare fuori affatto — a ~0.41. Conseguenza operativa: ogni scrittura di camera.zoom dovrà chiamare _aggiorna_limiti_camera(), o limiti e riempimento fuori mappa restano tarati sullo zoom vecchio. Nessun file del progetto Godot modificato, come imponeva il ticket: verificato con git status riga per riga. - [docs] Jira: tre figli aperti e concatenati con «blocca» — SU-329 → SU-328 → SU-330. SU-329 (togliere allo zoom il potere di cambiare le regole: lanterna in px mondo, spawn gatti congelato sullo zoom base 2.5) precede SU-328 (il pinch vero, più la voce «ZOOM MONDO» in Opzioni e la persistenza in
Settings), che a sua volta precede SU-330 (misura appaiata A-B-A sull'Honor 10 di notte — 60 s a 2.5, 60 s a 1.5, 60 s a 2.5 — perché il telefono perde ~15 fps scaldandosi e non lo dichiara, quindi il numero assoluto non vale nulla; più il verdetto a occhio di Ivan sulla leggibilità dei testi di mondo). ⚠️ L'ordine non è pignoleria: SU-328 da solo consegnerebbe una feature che *sembra* funzionare mentre rende la notte più facile e sposta i gatti in MP. 📌 Un quarto ticket è stato scritto ma NON aperto, perché ha senso solo se SU-330 boccia la leggibilità: *«Testi di mondo a scala fissa»* — portare interact_label (Player.gd:609-614) e i prompt degli Interactable su un layer a scala fissa col trucco già in casa della bolla NPC (NPC.gd:336-357: canvas a scala 1, offset e font moltiplicati a mano), non col SubViewport di SU-241; criteri: a zoom 1.5 i prompt leggibili quanto a 2.5, a zoom 2.5 nulla cambiato, prompt ancora sopra i palazzi alti. Costo totale stimato: 3 ticket, 2,5-3 giornate (4 e ~4 se scatta il condizionato). 📌 Cinque decisioni restano a Ivan e sono scritte nel commento del ticket, coi default già messi nei figli: ampiezza del range, tacche o continuo, se il testo di mondo che rimpicciolisce sia KO in partenza, tetto in MP, e se lo zoom si ricordi fra le partite. ⚠️ NON MISURATO e dichiarato in prima riga sul ticket: il costo su Android: serve il telefono vero, ed è esattamente SU-330.
RIENTRI ATTESI: SU-314, SU-315, SU-316, SU-317, SU-318, SU-319, SU-320, SU-322, SU-323 — le nove chiavi messe In revisione in questo giro. Al prossimo sprint, prima dei lotti: quante sono tornate in «Da fare» e con quale KO. *(Giro precedente: delle due chiavi attese — SU-305 e SU-306 — non ne è rientrata nessuna: tasso di rientro 0 su 2, il migliore mai registrato, ma su un giro da due soli ticket dice poco per costruzione.)* ⚠️ Come andrà letto questo giro, dichiarato prima di conoscere il risultato: sono nove ticket e sette riguardano telefono e touch (SU-314, SU-315, SU-316, SU-317, SU-318, SU-320, più SU-319 che chiede esplicitamente la prova «su telefono in orizzontale»), mentre nessuno di essi è stato visto su un device o un simulatore vero — solo provini in-engine sul Mac. Se il tasso di rientro sarà alto, la causa più probabile non sarà il codice ma la distanza fra il provino e il telefono, ed è una lacuna strutturale del nostro giro, non un errore di questo sprint. ⚠️ I candidati al rientro, in ordine di sospetto. Primo: SU-315, dove il ticket poneva una condizione — «purché resti facile confrontare le tre carte fra loro» — e con la selezionata a ~3× rispetto alle laterali il confronto dei tre *effetti* richiede di selezionarle una per una; è un giudizio di Ivan, non un numero, ed è già segnalato sul ticket. Secondo: SU-316, il cui alone allo 0,15 è stato guardato solo su fondo grigio uniforme, mai su selciato e palazzi. Terzo: SU-319 e SU-323, che toccano World e la generazione e non hanno mai visto il multiplayer — è il buco che rientra da quattro giri di fila. Quarto: il tutorial di SU-319, dove il bordo ovest ora mostra una fascia scura dove prima c'era corsia: è coerente col fondo del tutorial, ma è un cambio di resa che nessuno ha chiesto. 📌 Un dato di processo da confrontare col prossimo giro: sei lotti su sette hanno chiuso in 20-40 minuti; il settimo si è impiantato per due ore e un quarto su un git stash e ha richiesto che l'orchestratore ne rifacesse verifica e correzione. Il lavoro non è andato perso perché il codice era già su disco — ma il tempo sì.