Skip to content

Instantly share code, notes, and snippets.

@Dreaming381
Last active November 6, 2025 06:50
Show Gist options
  • Select an option

  • Save Dreaming381/3aec938455f5e6f393a24e4febabd777 to your computer and use it in GitHub Desktop.

Select an option

Save Dreaming381/3aec938455f5e6f393a24e4febabd777 to your computer and use it in GitHub Desktop.
Continuous Feedback for the ECS Team

Latios Framework Unity ECS Wishlist

Last Updated: 2025-11-6

As the original author and primary developer of the Latios Framework for Unity’s ECS, I regularly run into bugs, inadequate functionalities, and pitfalls within the ECS ecosystem. This has resulted in lots of “hacks” in the framework to patch up problems. This is a living document describing the issues and hacks. My hope is that the Unity ECS team will find this to be a valuable reference to help improve the quality of their packages.

This document does not include all possible features the Latios Framework may eventually implement if no official solution is provided. If you would like to learn about such features, it is best to ask me. I’ve focused this list specifically on things I would like to see. There are a lot more things I could list that I know many users have asked for, and arrive to the Latios Framework due to these missing features or other issues. If you would like to get a list of these things in a specific area, or if you have any questions about anything listed here, feel free to reach out to me!

Ship Stoppers

These are high-severity items that are preventing the Latios Framework from functioning correctly, with no plausible workarounds.

While there are some major concerns that reduce the beginner-friendliness of the framework in Entities 1.4.3, there are no outright blockers for future development at this time. There are some incompatibility issues with Latios Framework 0.14.x and newer editor versions, but these issues are resolvable.

Major Regression or Compatibility Concerns

These are issues that are compromising my ability to provide the best possible API and experience for users of the Latios Framework.

Code Gen Desires

IAspect and ENTITY_STORE_V1 deprecation introduce significant problems. I don’t mind those going away, but I need the following to replace them.

I want to define custom type handles that SystemAPI can populate for me. I want to define custom types that can be iterated in idiomatic foreach and IJobEntity. I want to extract the EntityQuery auto-created by an IJobEntity definition. I wish the IJobEntityChunkBeginEnd interface was just part of IJobEntity and were default interface methods. And I want a method I can call that will populate all the type handles and indices arrays of an IJobEntity so that I can pass it into a generic method constrained by IJobChunk to schedule the job in a custom way.

I also want a per-world deterministic chunk ID that I can use to sort chunks deterministically.

New Big Features I Want

These are features that are deep in the backlog of things I may develop for the framework, but I’d really rather these be developed by Unity first.

Support for Unmanaged Lights

Companion Game Object lights are bad for any dynamic entities that are spawned and despawned. It would be awesome if we could feed unmanaged light data into the SRP, since that’s how it uses it internally.

Support for DOTS-Instanced Projected Decals

Projected decals are currently companion Game Objects which use manual instancing. But mesh decals can use DOTS-Instancing just fine, and is compatible with the decal render features/passes. Can decal projection material properties support DOTS instancing so that we can have pure entity decals?

Environment Baking

With the new environment system being killed off, please invest in some proof-of-concepts for baking environments authored with currently available tools into entities. I already have too much on my plate to take this on too.

Cinemachine Integration

Cinemachine does not play nice with the job system, or ECS physics. I’d like to see better integration.

Stumbling Points

These are areas that make it harder for me to develop features for the framework.

Numerics as a Separate Package

I’d like to see the Numerics assembly inside Unity Physics be split into a separate package. Otherwise, I’m going to have to copy it if I want to use it, since I have my own physics solution.

Chunk Fragmentation

I’d like structural changes made on entire chunk in-place to first check if there is a destination chunk that can house all of the entities contained in the source chunk, and then move all the entities there. This would solve a lot of fragmentation problems I am constantly having to dodge with cleanup and chunk components.

Burst Inspector Function Navigation

When Burst compiles a job, it often breaks the job up into multiple functions. I want an outline of all these functions that I can click on to jump to them.

ID Management

It is very difficult to enforce unique identifiers to external resources, and correctly handle instantiation deep-copying those external resources and garbage-collecting dead entities. I want to see this area improved.

Runtime Inspectors

I want a better way to make more data visible to the runtime inspectors, such as fields I specify as internal. I also want to be able to override the entire DynamicBuffer drawer, rather than each element.

BlobStrings, UnsafeText, and String Interpolation in Burst

It seems Burst really only likes string interpolation for the fixed string types. I’d like the range to be covered a little more.

SharedStatic Index Acquisition

I want to assign each SharedStatic<int> a unique array index at creation time, so that I can use these as named indexers into some other resource, without having to try and gather all these instances at application startup.

Burst Type Comparisons

I want to compare types with some kind of generic method AreSameType<TA, TB>() that returns true if they are the same type, and false if they are different. While I could use runtime type hashes to do this, I really want this to be a compile-time constant expression.

Performance Pains

These are issues that are preventing me from getting the most performance out of the framework.

Fixed 16 kB Chunk Capacity

While I think the first chunk of each archetype could be the fixed 16 kB layout, if there are archetypes that need more than one chunk, I’d like to see them switch to a design that allows far more entities to be iterated linearly at once, so that we can benefit more from hardware prefetching.

Shadow Casting Light Culling

SRP allows all shadow-casting lights to be culled and processed in batch. Yet the culling callbacks sent back to BatchRendererGroup happen one-by-one. I’d love to perform culling for all lights at once.

Structural Change Performance

I’d like the option to allow the component data moving part to be deferred to a parallel job during large structural changes, and for DynamicBuffer memory freeing operations to also get deferred to some later point off the main thread.

Bitwise Operations on Component Enabled Bits

I want to use SIMD (or pairs of 64-bit ops) to process enabled states of components in a chunk, both for reading and writing.

API Gotchas

Here’s some examples of API holes that are a bit inconsistent. Commented out lines are lines that I would expect to compile, but don’t.

using System.Collections.Generic;
using Unity.Burst.Intrinsics;
using Unity.Collections;
using Unity.Entities;
using Unity.Entities.Graphics;
using Unity.Rendering;
using Unity.Transforms;

partial struct ApiProblemsSystem : ISystem
{
    public void OnUpdate(ref SystemState state)
    {
        var list         = new NativeList<int>(state.WorldUpdateAllocator);
        state.Dependency = list.Dispose(state.Dependency);

        var array = CollectionHelper.CreateNativeArray<int>(8, state.WorldUpdateAllocator);
        //state.Dependency = CollectionHelper.Dispose(array, state.Dependency);

        Entity anEntity = Entity.Null;
        foreach ((var transform, var entity) in SystemAPI.Query<LocalTransform>().WithEntityAccess())
        {
            anEntity = entity;
        }

        //foreach (var entity in SystemAPI.Query().WithEntityAccess().WithAll<LocalTransform>())
        {
        }

        var valuesManaged  = new List<RenderFilterSettings>();
        var indicesManaged = new List<int>();
        state.EntityManager.GetAllUniqueSharedComponentsManaged(valuesManaged, indicesManaged);

        state.EntityManager.GetAllUniqueSharedComponents<RenderFilterSettings>(out var valuesUnmanaged, state.WorldUpdateAllocator);
        //state.EntityManager.GetAllUniqueSharedComponents<RenderFilterSettings>(out var valuesUnmanaged, out var indicesUnmanaged, state.WorldUpdateAllocator);

        // Why do we even have custom SystemHandle APIs for things rather than just expose an Entity property on SystemHandle?
        var dstBuffer = state.EntityManager.GetBuffer<LinkedEntityGroup>(state.SystemHandle);
        //state.EntityManager.GetSharedComponentData<RenderFilterSettings>(state.SystemHandle, default);

        state.EntityManager.GetComponentDataRW<LocalTransform>(state.SystemHandle);
        //state.EntityManager.GetComponentDataRW<LocalTransform>(anEntity);

        state.EntityManager.CompleteDependencyBeforeRO<LocalTransform>();
        //state.EntityManager.CompleteDependencyBeforeRO(ComponentType.ReadOnly<LocalTransform>());

        var systemTypeIndex = TypeManager.GetSystemTypeIndex<ApiProblemsSystem>();
        //System.Type type = TypeManager.GetSystemType(systemTypeIndex);

        var srcBuffer = state.EntityManager.GetBuffer<LinkedEntityGroup>(anEntity);
        dstBuffer.CopyFrom(srcBuffer);
        //dstBuffer.AddRange(srcBuffer);
        dstBuffer.AddRange(srcBuffer.AsNativeArray());  // Safety violation

        var archetype = state.EntityManager.GetChunk(anEntity).Archetype;
        state.EntityManager.SetArchetype(anEntity, archetype);

        var entityArray = new NativeArray<Entity>(1, Allocator.Temp);
        entityArray[0]  = anEntity;
        //state.EntityManager.SetArchetype(entityArray, archetype);
    }

    struct Job : IJobChunk
    {
        public ComponentTypeHandle<EntitiesGraphicsChunkInfo>  chunkComponentHandle;
        public ComponentTypeHandle<MaterialMeshInfo>           componentHandle;
        public DynamicComponentTypeHandle                      dynamicHandle;
        public SharedComponentTypeHandle<RenderFilterSettings> sharedHandle;
        public DynamicSharedComponentTypeHandle                dynamicSharedHandle;

        public EntityQueryMask queryMask;

        public unsafe void Execute(in ArchetypeChunk chunk, int unfilteredChunkIndex, bool useEnabledMask, in v128 chunkEnabledMask)
        {
            chunk.GetEnableableBits(ref dynamicHandle);
            //chunk.GetEnableableBits(ref componentHandle);

            //chunk.GetSharedComponent(ref sharedHandle);
            chunk.GetSharedComponent(sharedHandle);
            chunk.GetDynamicSharedComponentDataAddress(ref dynamicSharedHandle);
            //chunk.GetSharedComponentIndex(ref sharedHandle);
            chunk.GetSharedComponentIndex(sharedHandle);
            chunk.GetSharedComponentIndex(ref dynamicSharedHandle);

            EntityQueryMask defaultMask = default;
            //bool isDefaultMask = queryMask == defaultMask;

            var arrayRO = chunk.GetComponentDataPtrRO(ref componentHandle);
            //var dynamicArrayRO = chunk.GetComponentDataPtrRO(ref dynamicHandle);
            var dynamicHandleAsRO = dynamicHandle.CopyToReadOnly();  // RIP lookup cache.
            var dynamicArrayRO    = chunk.GetDynamicComponentDataArrayReinterpret<byte>(ref dynamicHandleAsRO, 4);

            chunk.GetChunkComponentData(ref chunkComponentHandle);
            //chunk.GetChunkComponentDataRW(ref chunkComponentHandle);
        }
    }
}

Hacky Solutions I’d Like to Replace

Sometimes, I need to do hacky things to accomplish the desired functionality. While this isn’t a complete list, here are a few areas to look at to see if things can be improved.

Exposed APIs

I use this asmref directory to expose various extra APIs from the Entities package that I need. https://github.com/Dreaming381/Latios-Framework/tree/master/EntitiesExposed

The ILPostProcessing next to it is also hacks into the Entities package for where I needed to add extra hooks.

Please ask what I use each of these for.

Custom Bootstraps for Non-Runtime Worlds and Bakers

I have custom bootstrap types that define other worlds, such as the editor world and baking worlds. I eventually plan to add a bootstrap for subscene post-processing. But it would be really nice if I didn’t have to do crazy hacks to make these things work.

Callback in Player Loop After All Rendering

Somehow, I can’t seem to find a PlayerLoop point that happens after all the rendering including SRP Render Graph execution. I need to use an end-of-frame coroutine on a hidden GameObject to run systems at this point. And then making those systems show up in the Systems window also required a bit of hackery.

Blob Baking

Right now, I have my Smart Blobber feature, which makes blob baking with deduplication safer and easier, while offering parallel baking for fast live editing. However, I’d much rather see an approach that allows blobs to be baked in bakers with the same benefits. This would require two things:

First, it would require the ability to specify separate per-bake and per session hashes for potential blob assets. And second, it would require async awaiting on scheduled jobs so that other bakers can run while jobs are processing a blob.

Interfaces in Baking

Everything in here I would have expected to be provided out-of-the-box. https://github.com/Dreaming381/Latios-Framework/blob/master/Core/Authoring/BakerInterfaceSupport.cs

Big Feature Problems that Caused Me to Do My Own Thing

These are the big features that the Latios Framework provides some kind of substitute for, and the oversimplified reasons why.

Transforms

I wanted animation-friendly squash-and-stretch hierarchies. And I also wanted much better performance. Unity Transforms did catch up performance-wise in a lot of ways since I started this endeavor.

Entities Graphics

I needed much better performance for skinned mesh rendering. Turns out, this path led me to discover optimizations for all projects in general. And after that, I went on a quest to support LODs for dense worlds as well. The Entities Graphics package has been mostly stagnant in regards to features, getting the occasional bugfix every few DOTS releases.

Physics

I needed much more direct spatial query capabilities. And nowadays, I need more customizability over the simulation. Also, I needed hierarchies.

This unfortunately meant that I don’t get to directly use the character controller and vehicles packages either.

NetCode

I needed much more control over the interpolation of synchronized objects. And I needed better hierarchy support. I just could not achieve a good motion feel in NetCode for motions that felt great when not networked.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment