Quick answer: Pygame sprite group rendering in shuffled order? Group iterates as a set - use LayeredUpdates for guaranteed z-order via sprite.layer attribute.

UI sprites randomly render under gameplay sprites despite being added later. The 'add last, draw last' assumption is wrong.

Use LayeredUpdates

g = pygame.sprite.LayeredUpdates()
g.add(sprite, layer=10)

Layer integer determines draw order. Higher = front. Stable; ordinary Group is not.

Or sort manually

Subclass Group, override sprites() to return sorted(super().sprites(), key=lambda s: s.z). More code than LayeredUpdates for the same outcome.

Avoid relying on insertion order

Even with Python 3.7+ dict ordering, Group's internal storage doesn't guarantee it. Don't depend on add order for visual ordering.

“Group is a set. Sets don't have order. LayeredUpdates does.”

For tiled games, layer by tile y-coordinate. Built-in y-sorting via LayeredUpdates is the simplest correct path.