Isometric depth sorting: draw world entities back-to-front so tall sprites occlude correctly #66

Closed
opened 2026-07-19 07:44:10 +02:00 by marco · 1 comment
Owner

Tall sprites (the training dummy, trees, and mobiles) are anchored at their base tile but extend upward, visually covering neighbouring tiles that are higher on screen. Today the client draws entities in dictionary order (_players.Values then _mobiles in separate loops in GameScreen.Draw) with no depth sorting, so occlusion is wrong: a player standing behind the dummy is drawn over it (looks like they walked "into"/through it), and players are always drawn over/under all creatures regardless of position.

Fix

Render all world entities (players, mobiles, corpses, tall statics) in one back-to-front pass sorted by isometric depth — typically by the anchor's screen Y (or tile Y then X). A nearer entity (lower on screen) is drawn last and correctly occludes farther ones, so a tall sprite "stands" on its tile and hides whatever is behind it.

Note: this is purely visual — movement already blocks correctly on a creature's tile (server-authoritative). This only fixes the draw order / occlusion.

Definition of Done

  • Entities are drawn in a single depth-sorted pass; a player behind a tall sprite is occluded by it, a player in front is drawn over it.
  • No visual "walk through" a creature/tree: the sprite reads as a solid object standing on its tile.
  • Players and mobiles interleave correctly by depth (not all-players-then-all-mobiles).
Tall sprites (the training dummy, trees, and mobiles) are anchored at their base tile but extend upward, visually covering neighbouring tiles that are higher on screen. Today the client draws entities in **dictionary order** (`_players.Values` then `_mobiles` in separate loops in `GameScreen.Draw`) with **no depth sorting**, so occlusion is wrong: a player standing behind the dummy is drawn over it (looks like they walked "into"/through it), and players are always drawn over/under all creatures regardless of position. ## Fix Render all world entities (players, mobiles, corpses, tall statics) in one **back-to-front pass sorted by isometric depth** — typically by the anchor's screen Y (or tile Y then X). A nearer entity (lower on screen) is drawn last and correctly occludes farther ones, so a tall sprite "stands" on its tile and hides whatever is behind it. Note: this is purely visual — movement already blocks correctly on a creature's tile (server-authoritative). This only fixes the draw order / occlusion. ## Definition of Done - Entities are drawn in a single depth-sorted pass; a player behind a tall sprite is occluded by it, a player in front is drawn over it. - No visual "walk through" a creature/tree: the sprite reads as a solid object standing on its tile. - Players and mobiles interleave correctly by depth (not all-players-then-all-mobiles).
Author
Owner

Real-world feedback (owner testing): tree hedges are very counter-intuitive to read in-game. The player stands on the walkable lane beside a tree band, but the tall tree sprites — drawn in the map pass, entirely behind the entity pass — overlap the walkable tiles and the player, so it looks like you are standing inside/among the trees. Movement + LOS are correct server-side (you cannot enter a tree tile or shoot a bolt through one); the issue is purely the render order.

Two fixes, ideally both:

  1. Depth-sort entities together with obstacles in one back-to-front pass (the core of this issue) so a tree nearer the camera occludes the player instead of rendering behind them.
  2. Fade obstacles that occlude the player — when a tree tile would cover the player's tile, draw it semi-transparent (a common iso trick) so you can always see your character and read the walkable lane.

Item 2 is cheap and would immediately fix the readability even before full depth sorting lands.

Real-world feedback (owner testing): tree hedges are **very counter-intuitive to read** in-game. The player stands on the walkable lane *beside* a tree band, but the tall tree sprites — drawn in the map pass, entirely behind the entity pass — overlap the walkable tiles and the player, so it looks like you are standing inside/among the trees. Movement + LOS are correct server-side (you cannot enter a tree tile or shoot a bolt through one); the issue is purely the render order. Two fixes, ideally both: 1. **Depth-sort entities together with obstacles** in one back-to-front pass (the core of this issue) so a tree nearer the camera occludes the player instead of rendering behind them. 2. **Fade obstacles that occlude the player** — when a tree tile would cover the player's tile, draw it semi-transparent (a common iso trick) so you can always see your character and read the walkable lane. Item 2 is cheap and would immediately fix the readability even before full depth sorting lands.
marco closed this issue 2026-07-19 12:11:17 +02:00
Sign in to join this conversation.
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#66
No description provided.