fix(client): profondità degli sprite alla cima della carta, non al piede #276

Merged
panda merged 1 commit from fix/sprite-depth-code into main 2026-08-07 21:22:08 +02:00
Collaborator

Summary

Il personaggio spariva dentro il terreno su un versante rivolto verso la camera. Segnalato camminando sull'asterra: "ti segnalo un problema sull'altro versante il personaggio finisce sotto il mesh" — riprodotto a (7516,4225), del corpo restavano due pixel.

Non era una regressione del lavoro sulla copertura: i file che governano la profondità erano invariati rispetto a prima di quel ramo. Veniva dalla fase 3D.

La causa. La base della camera dà toward = (0.3233, 0.3233, 0.8892): la quota pesa 2,75 volte la posizione planare. Il terreno che appare sopra l'entità sullo schermo può quindi essere più vicino in profondità, se è abbastanza alto. Lo sprite perde perché è un cartellone a profondità costante: un corpo in piedi è una colonna verticale e in questa base la testa è più vicina della camera dei piedi, ma disegnando l'intera carta alla profondità del piede la testa viene testata come se fosse a terra.

La correzione. IsoCamera.BillboardDepth calcola la profondità alla cima della carta: z + altezzaPixel / ZScale, con l'altezza presa dallo sprite stesso — AnchorY per i mobili, texture.Height per le statiche, che hanno origine (w/2, h). La grandezza è derivata, non tarata: si adatta da sola a un ratto e a una sequoia.

Un epsilon tarato è stato scartato: non ha un valore derivabile — troppo piccolo lascia il bug su pendenze più ripide, troppo grande spegne l'occlusione delle rupi.

Costo accettato e dichiarato: le gambe vengono testate alla quota della testa, quindi un dislivello che dovrebbe nasconderle non le nasconde. Sbagliare in questa direzione è molto meno visibile di un personaggio inghiottito dalla collina.

Screenshots / recording

Stesso tile (7516,4225), here 227, database fresco.

prima prima
dopo dopo

Comandi (docs/debug-harness.md): login test, poi /tp 7516 4225 via chat, poi screenshot.

How it was tested

  • 7 test nuovi in BillboardDepthTests, suite completa verde.
  • Il caso oracolo è costruito su geometria misurata sulla mappa spedita, non stimata: sonda che legge le region e campiona la superficie interpolata dentro il rettangolo di schermo dello sprite. Il giocatore sta a z 222 (l'HUD mostra 227, che è la quota display smussata); il terreno che lo copre arriva a z 225,6; deficit 2,33, cioè basterebbe una carta di 42 px contro i 120 reali.
  • Una versione precedente del test usava una cella scelta a occhio che proiettava 768 px lontano dallo sprite e non provava nulla: è annotato nel test perché non venga rifatto.

Limite noto

Se il terreno supera l'intera carta continua a coprire — corretto, ma può ancora far sparire il personaggio ai piedi di un massiccio. Il seguito è progettato in docs/superpowers/specs/2026-08-06-shaped-occluder-cutaway-design.md: tagliare solo il terreno che nasconde davvero qualcosa.

Checklist

  • just lint passa (CSharpier + analyzer, zero warning)
  • just test è verde
  • L'intera soluzione compila (client e tool inclusi)
  • Multi-piattaforma preservato: sola aritmetica float
  • Test aggiunti per questa modifica

Chiude parzialmente #275 (la parte ravvicinata; il taglio sagomato resta aperto).

## Summary Il personaggio spariva dentro il terreno su un versante rivolto verso la camera. Segnalato camminando sull'asterra: *"ti segnalo un problema sull'altro versante il personaggio finisce sotto il mesh"* — riprodotto a (7516,4225), del corpo restavano due pixel. **Non era una regressione del lavoro sulla copertura**: i file che governano la profondità erano invariati rispetto a prima di quel ramo. Veniva dalla fase 3D. **La causa.** La base della camera dà `toward = (0.3233, 0.3233, 0.8892)`: la quota pesa **2,75 volte** la posizione planare. Il terreno che appare *sopra* l'entità sullo schermo può quindi essere **più vicino in profondità**, se è abbastanza alto. Lo sprite perde perché è un cartellone a profondità **costante**: un corpo in piedi è una colonna verticale e in questa base la testa è più vicina della camera dei piedi, ma disegnando l'intera carta alla profondità del piede la testa viene testata come se fosse a terra. **La correzione.** `IsoCamera.BillboardDepth` calcola la profondità alla **cima della carta**: `z + altezzaPixel / ZScale`, con l'altezza presa dallo sprite stesso — `AnchorY` per i mobili, `texture.Height` per le statiche, che hanno origine `(w/2, h)`. La grandezza è **derivata, non tarata**: si adatta da sola a un ratto e a una sequoia. Un epsilon tarato è stato **scartato**: non ha un valore derivabile — troppo piccolo lascia il bug su pendenze più ripide, troppo grande spegne l'occlusione delle rupi. **Costo accettato e dichiarato**: le gambe vengono testate alla quota della testa, quindi un dislivello che dovrebbe nasconderle non le nasconde. Sbagliare in questa direzione è molto meno visibile di un personaggio inghiottito dalla collina. ## Screenshots / recording Stesso tile (7516,4225), `here 227`, database fresco. | | | | --- | --- | | prima | ![prima](https://git.homelab.devncode.it/attachments/922fe7cf-b1f2-46e7-972e-a29101bb76b9) | | dopo | ![dopo](https://git.homelab.devncode.it/attachments/34432c40-33f3-4391-86d3-5106d36eb62b) | Comandi (`docs/debug-harness.md`): `login test`, poi `/tp 7516 4225` via chat, poi `screenshot`. ## How it was tested - **7 test nuovi** in `BillboardDepthTests`, suite completa verde. - Il caso oracolo è costruito su **geometria misurata sulla mappa spedita**, non stimata: sonda che legge le region e campiona la superficie interpolata dentro il rettangolo di schermo dello sprite. Il giocatore sta a `z 222` (l'HUD mostra 227, che è la quota *display* smussata); il terreno che lo copre arriva a `z 225,6`; deficit **2,33**, cioè basterebbe una carta di 42 px contro i 120 reali. - Una versione precedente del test usava una cella scelta a occhio che proiettava **768 px lontano dallo sprite** e non provava nulla: è annotato nel test perché non venga rifatto. ### Limite noto Se il terreno supera l'intera carta continua a coprire — corretto, ma può ancora far sparire il personaggio ai piedi di un massiccio. Il seguito è progettato in `docs/superpowers/specs/2026-08-06-shaped-occluder-cutaway-design.md`: tagliare solo il terreno che nasconde davvero qualcosa. ## Checklist - [x] `just lint` passa (CSharpier + analyzer, zero warning) - [x] `just test` è verde - [x] L'intera soluzione compila (client e tool inclusi) - [x] Multi-piattaforma preservato: sola aritmetica float - [x] Test aggiunti per questa modifica Chiude parzialmente #275 (la parte ravvicinata; il taglio sagomato resta aperto).
fix(client): depth-test entity sprites at the card's top, not its foot
All checks were successful
ci / Lua content lint (pull_request) Successful in 11s
ci / Lint & Test (pull_request) Successful in 6m46s
26e8196cf1
panda merged commit 0b65ca7407 into main 2026-08-07 21:22:08 +02:00
panda deleted branch fix/sprite-depth-code 2026-08-07 21:22:08 +02:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
marco/IsoMmo!276
No description provided.