diff --git a/Engine.Core/Helpers/FastListOrdered.cs b/Engine.Core/Helpers/FastListOrdered.cs
new file mode 100644
index 0000000..d99c826
--- /dev/null
+++ b/Engine.Core/Helpers/FastListOrdered.cs
@@ -0,0 +1,172 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace Engine.Core;
+
+///
+/// TODO This is VEERY experimental, and doesn't work well with the indices access. Use with caution
+///
+///
+///
+public class FastListOrdered : IList, IReadOnlyList, IEnumerable where TItem : notnull where TIndex : IComparable
+{
+ private readonly SortedDictionary> items = null!;
+
+ private readonly Func getIndexFunc = null!;
+ private readonly IComparer sortBy = null!;
+
+ private int count = 0;
+ public int Count => count;
+
+ public bool IsReadOnly { get; set; } = false;
+
+ public TItem this[int index]
+ {
+ get { (TIndex tIndex, int i) = GetAt(index); return items[tIndex][i]; }
+ set
+ {
+ if (IsReadOnly)
+ throw new System.Data.ReadOnlyException();
+ (TIndex tIndex, int i) = GetAt(index); items[tIndex][i] = value;
+ }
+ }
+
+ private (TIndex TIndex, int i) GetAt(Index index)
+ {
+ int actualIndex = index.IsFromEnd
+ ? count - index.Value
+ : index.Value;
+
+ if (actualIndex < 0 || actualIndex >= count)
+ throw new IndexOutOfRangeException();
+
+ int leftIndex = actualIndex;
+ foreach ((TIndex i, FastList list) in items)
+ {
+ if (leftIndex < list.Count)
+ return (i, leftIndex);
+ leftIndex -= list.Count;
+ }
+ throw new IndexOutOfRangeException();
+ }
+
+ public int IndexOf(TItem item)
+ {
+ int indexCounter = 0;
+ foreach ((TIndex index, FastList list) in items)
+ {
+ int i = list.IndexOf(item);
+ if (i != -1)
+ return indexCounter + i;
+ indexCounter += list.Count;
+ }
+
+ return -1;
+ }
+
+ public void Add(TItem item)
+ {
+ if (IsReadOnly)
+ throw new System.Data.ReadOnlyException();
+
+ TIndex key = getIndexFunc(item);
+ if (!items.TryGetValue(key, out FastList? list))
+ items[key] = list = [];
+
+ list.Add(item);
+ count++;
+ }
+
+ public void Insert(int index, TItem item)
+ {
+ if (IsReadOnly)
+ throw new System.Data.ReadOnlyException();
+
+ TIndex tIndex = getIndexFunc(item);
+ if (!items.TryGetValue(tIndex, out FastList? list))
+ items[tIndex] = list = [];
+
+ list.Insert(index, item);
+ count++;
+ }
+
+ public bool Remove(TItem item)
+ {
+ if (IsReadOnly)
+ throw new System.Data.ReadOnlyException();
+
+ TIndex index = getIndexFunc(item);
+ if (!items.TryGetValue(index, out FastList? list))
+ throw new Exceptions.NotFoundException($"Index of '{index}' is not found in the collector");
+
+ if (!list.Remove(item))
+ return false;
+
+ count--;
+ return true;
+ }
+
+ public void RemoveAt(int index)
+ {
+ if (IsReadOnly)
+ throw new System.Data.ReadOnlyException();
+
+ (TIndex tIndex, int i) = GetAt(index);
+ items[tIndex].RemoveAt(i);
+ count--;
+ }
+
+ public void Clear()
+ {
+ if (IsReadOnly)
+ throw new System.Data.ReadOnlyException();
+
+ foreach ((TIndex index, FastList list) in items)
+ list.Clear();
+
+ count = 0;
+ }
+
+ public bool Contains(TItem item)
+ {
+ foreach ((TIndex index, FastList list) in items)
+ if (list.Contains(item))
+ return true;
+ return false;
+ }
+
+ public void CopyTo(TItem[] array, int arrayIndex)
+ {
+ int indexCounter = 0;
+
+ foreach ((TIndex index, FastList list) in items)
+ {
+ list.CopyTo(array, indexCounter);
+ indexCounter += list.Count;
+ }
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ foreach ((TIndex index, FastList list) in items)
+ foreach (TItem item in list)
+ yield return item;
+ }
+
+ IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
+
+ public FastListOrdered(Func getIndexFunc, Comparison sortBy)
+ {
+ this.getIndexFunc = getIndexFunc;
+ this.sortBy = Comparer.Create(sortBy);
+ items = new(this.sortBy);
+ }
+
+ public FastListOrdered(Func getIndexFunc, IComparer sortBy)
+ {
+ this.getIndexFunc = getIndexFunc;
+ this.sortBy = sortBy;
+ items = new(sortBy);
+ }
+}