prime31 / Nez

Nez is a free 2D focused framework that works with MonoGame and FNA
MIT License
1.76k stars 355 forks source link

RendererableComponentList uses unstable sorting algorithm #753

Open nrmiller opened 1 year ago

nrmiller commented 1 year ago

@prime31 Hey Prime! Just started looking into MG & Nez. I'm loving the framework so far, but I encountered a very bizarre issue while troubleshooting what I thought was some simple code and wanted to get your thoughts. In my project, I was adding several SpriteRenderer components to a single Entity to achieve some layering. My expectation sprites would be rendered in the order they were added to the entity, however, I found that the render order was unpredictable. While this could have been fixed by setting a RenderLayer to the components, I wanted to understand why this was happening.

I tracked it down to the use of Array.Sort in FastList. The problem is that, per MSDN, this sorting algorithm is unstable. How do you feel if I were to raise a PR to change FastList to use a stable sorting algorithm instead?

This implementation performs an unstable sort; that is, if two elements are equal, their order might not be preserved. In contrast, a stable sort preserves the order of elements that are equal.

I don't suggest the following since it defeats the purpose of the fast list, but this "fix" does produce a stable sort order.

image

prime31 commented 1 year ago

I don't see any reason why not to have a stable sort as an option. My only worry is the price paid for it when the renderables already have some bits in place to try to avoid paying the penalty of a stable sort, mainly the two-layered RenderLayer and LayerDepth which provides bucketing via the RenderLayer int and then fine-grained control with the LayerDepth float. If you have a good idea to keep it fast on large data sets then by all means give it a go!