#archived-dots
1 messages ยท Page 17 of 1
I think it's worded badly
If you say go to the back of the queue irl you would be the last to leave
Think "end" in the comment as the earliest added in the queue
i'll test this. can't imagine this really being FILO
Values are being added at index [0] and the end is being pushed back.
So taking from the end returns the first in.
Wouldn't you say go to the start of the queue?
What it should say is "front" of the queue.
Similarly "start of the queue" could be interpreted to mean either the part of the queue containing the people that started the queue (front) or the part of the queue where new entrants must join to start queueing (back).

English. Yes. Everything needs to be emojis.
(says man who has never used a single emoji in text before).
Then this is definitely for you: https://www.emojicode.org/
yep, NativeQueue is FIFO. just a reaaaally bad comment. should plainly say, returns the earliest element that was enqueued or make a FIFO reference.
Well unless it was using parallel writer then it's really just a random element
I think native queue is just a bunch of circular buffers.... i think
You can make a queue using an array and 2 ints but resizing it, no clue.
Everyone likes stacks. Far superior. Requires one less int.
But is there a good emoji for a stack? didn't think so
it will still be the earliest enqueued ๐ i haven't studied the implementation too much. uses a bunch of Interlocked at times
{
NativeQueue<Entity> queue = new NativeQueue<Entity>(Allocator.Persistent);
var queueEntity = EntityManager.CreateEntity(typeof(MonsterLineQueue));
EntityManager.AddComponentData(queueEntity, new MonsterLineQueue()
{
queuePtr = UnsafeUtility.AddressOf(ref queue)
});
}``` any idea why this is not working? I should be able to store the nativeQueue ptr like that and restore it with UnsafeUtility.AsRef
does addressOf only work for unmanaged memory?
Pretty sure it has a block per thread
And it reads back per block
So 1 thread, then the next, etc will read back
Interlocks for grabbing a new block if it fills up
yeah, that's what happens. anyway, not interested in parallel writing to queues. (i think that's a total fail) guess my method is not working. have to save the pointers or make an unsafe wrapper
Does it have to be FIFO?
yes ๐
the queue is created once, dequeued in a ST job and always filled up to a certain amount. i had a list before but the list has the problem that i can't just insert an element to the front without a memmove
well, actually the first element in the list was last. filling it up was the problem where i changed to the queue
memmove isnt that expensive... i think. Just move it a large amount instead of 1 by 1 and then store the current back index. If it reaches 0, memmove again.
Unless you're doing this in parallel then yea, a queue will be better
i'll keep this in mind. the list can have several thousand elements but i can keep it to 1 memmove. no parallel job involved
Does unity have any plans to incorporate C# hot reloading in the future?
Can you read an entity's component data using only a ComponentType? It doesn't seem possible from what I can see besides using reflection to dynamically create a GetComponent<T> with the T being the componenttype...
yes you can
it'll be pointer to memory
so you simply read required amount of bytes
if type is unknown
What if I don't know how many bytes to read? My use case is I'd like to just get all components with all fields from an entity
pretty sure ComponentType can give it to you
I think I'll just stick with reflection, it doesn't really need to be performant
Hey, are there any scientific sources / papers on Unity DOTS or the Burst compiler? I've done some search already but been struggling to find any.
What in particular would you find helpful
That is already really helpful. Didn't have that one in my literature list yet
In general things I can cite on the topic. My big problem currently is that much of the information on DOTS and Burst is from Unity's website / docs which I am not really allowed to cite in my thesis.
Ah, gotcha. Well, what's your thesis? It would make it easier to identify relevant sources
I'm working on a performance comparison for crowd simulation between OOP (traditional Unity component system) and DOD (Unity DOTS)
this paper is gold
Great, glad you're enjoying it
Hopefully the bibliography can be mined for more references
Something annoying me at the moment, although i think i've noticed this before:
I have a system with lets say two ForEach jobs..
The first one writes to a particular buffer, the second one reads from that same buffer
However, the read job occurs a frame after the write job
But because both jobs are part of the same dependency chain, it throws the error ( must call Complete() on job 1 to read from that buffer in job 2 )
So I know that there is no problem as the second job always follows a frame after the first ( due to the presence of an entity created in the first job which the second job looks for )
So that problem can be avoided by simply splitting the system into two systems
It does exactly the same work in exactly the same way, but it doesn't throw this dependency problem
automatic dependency only exists between systems
within a system you are entirely responsible for manually handling dependencies
well as i say, it's throwing the error, when both jobs exist within the system
even when job 1 only runs on frame 1, and job 2 only runs on frame 2 ( ie there is no conflict in read/write )
even if the job doesn't run, it still means you're accessing something from the first job in the system after you schedule it
right yeah that's kindof what i suspected
wouldn't this just easily be solved by scheduling the read job first within the system?
so internally, the system is cueing up that data for a write and a read, as it is part of that dependency chain, even if only the write job runs or only the read job runs
that's a good point yep
i think it also has the benefit of kind of implying the read job is reading the previous frames work
without having to look at the actual job code
useful in 2 years time when you come back to it and forgot what's happening
i'm glad you got what i was saying, i was worried 'nobody's going to get this' haha
yep that's true also
i sometimes wonder, what's better - split a system up into multiple systems, or just have a bunch of jobs within a system
is there any significant overhead or detriment to splitting them up
i guess one potential advantage is you can have RequiresForUpdate and be more granular about which jobs/systems actually run at all
SystemBase has quite a bit of overhead
much better with ISystem
especially if you're using the same query or component handles
it adds up over 500 systems
any news about DOTS lately?
Seen the video where the CEO talks a little bit about dots ?
I'm confused how you are running the jobs @devout prairie
I have several jobs in a single system like a chain all time and it seems to work fine
Yeah it often is fine i think it's simply because:
- JobA i pass in a GetBufferFromEntity<MyBuffer>, and write to it inside the job
- JobB i readfrom MyBuffer in a ForEach
So because the first job writes to those buffers, the second job can't reliably read from them
oh yes I see, one of my sequences involves a buffer but that buffer is written to a nativearray and then that nativearray is passed to the second job
I think buffers are generally finicky like that
I'm still confused, wouldn't JobA's GetBufferFromEntity have write permission, forcing JobB to wait until it has finished executing if the handles are scheduled correctly?
Nvm, I thought you meant BufferFromEntity, not GetBufferFromEntity...
I think I remember tertle saying something about you can't be sure about what's accessing a buffer sometimes so they have to have more protections
I'm guessing it's because he is getting the buffer before scheduling the job. I'm actually amazed unity lets you do this (pass a DynamicBuffer to a job), since that doesn't seem correct. I might be mistaken though
Ah, I missed the part about them not running in the same frame
Disregard everything I said ๐
it shouldn't make any difference even if they are in the same frame
If you schedule them as dependencies it should work fine
yeah, to be honest I thought systems had auto dependencies
Do you mean inside the system or between systems?
inside the system
They kind of do, one overload of Schedule (the one that doesn't get a JobHandle) automatically adds the dependencies for that scheduled job to SystemBase.Dependency
Meaning the dependency chain is equal to the order you call Schedule
oh ok
It's explained here in detail: https://docs.unity3d.com/Packages/com.unity.entities@0.51/manual/ecs_job_dependencies.html
cool, thanks
Anybody else her got this VlidTRS error?
This happens to me sporadically:
Assertion failed on expression: 'ValidTRS()'
UnityEngine.Matrix4x4:get_rotation ()
Unity.Entities.CompanionGameObjectUpdateTransformSystem/CopyTransformJob:Execute (int,UnityEngine.Jobs.TransformAccess) (at Library/PackageCache/com.unity.entities@0.51.1-preview.21/Unity.Transforms.Hybrid/CompanionGameObjectUpdateTransformSystem.cs:96)
UnityEngine.Jobs.IJobParallelForTransformExtensions/TransformParallelForLoopStruct`1<Unity.Entities.CompanionGameObjectUpdateTransformSystem/CopyTransformJob>:Execute (Unity.Entities.CompanionGameObjectUpdateTransformSystem/CopyTransformJob&,intptr,intptr,Unity.Jobs.LowLevel.Unsafe.JobRanges&,int)
Seems to be an internal problem with the Unity Companion Transform updates
seems like your TRS is invalid
Well how do you know ๐ค
are you using default(float4x4) anywhere in your code?
or default(float4) for rotation?
no I dont. The error happens in Unities TransformCopySystem while copying rotation and scale from the transform to the entity
I wonder if it's a problem with some transformation on the gameobject/Vector3/Quaternion side generating a NaN, maybe create a system before the transform copy system that inspects the values
Or debug step
it's been a while since I had touched the conversion system & prefabs, but I'm having some difficulty linking a prefab entity to another authored entity
class DeclarePrefabSystem : GameObjectConversionSystem {
public override void OnUpdate() {
Entities.ForEach((SomeAuthoringComponent foo) => {
this.DeclareReferencedPrefab(foo.Prefab);
}
}
}
class SomeAuthoringComponent : IConvertGameObjectToEntity {
public GameObject Prefab;
public void Convert(...) {
var prefabEntity = conversionSystem.GetPrimaryEntity(Prefab);
dstManager.AddComponentData(entity, new PrefabComp { Value = prefabEntity });
}
}
It's in a similar vein to the code snippet, but I think I'm getting a different entity via GetPrimaryEntity (e.g in a subscene I'm getting index 8, but on runtime index 8 is a completely different entity)
That's a good idea. Will try it out tomorrow. Problem is the error is sporadic
I've never created a conversation system in that way, but I think your system should implement the interface IDeclareReferencePrefabs
Ah so the DeclarePrefabSystem runs in GameObjectDeclareReferencedObjectsGroup since I had recently ditched IDeclareReferencedPrefabs
since I still had the same issue ๐ค
This is the barebones of a typical mono i use for declaring prefabs, it doesn't use subscenes though:
[DisallowMultipleComponent]
public class SelectionSystemAuthoring : MonoBehaviour, IConvertGameObjectToEntity, IDeclareReferencedPrefabs
{
public GameObject circlePrefab;
public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
{
var selectionSystem = dstManager.World.GetExistingSystem<SelectionSystem>();
selectionSystem.placerRing = dstManager.Instantiate(conversionSystem.GetPrimaryEntity(circlePrefab));
}
public void DeclareReferencedPrefabs(List<GameObject> referencedPrefabs)
{
GeneratedAuthoringComponentImplementation.AddReferencedPrefab(referencedPrefabs, circlePrefab);
}
}
I tend to chuck these together pretty quickly just to get something that 'works' so i'm sure there's a better approach, i'm not even sure if using mono's like this will be supported for long.
The whole conversion thing is a bit of a mess tbh, quite the headache
Fwiw i don't normally instantiate the prefab inside the conversion like that, but just to demonstrate that it does actually work and deliver the correct primary entity
conversion's getting overhauled in 1.0. Dont know how they're changing referenced prefabs though.
Yeahhh i really hope they just strip away all the crap and say 'okay this is how it should be done'
instead of what they have now which is basically a minefield of different approaches without any clear guidance on what exactly is what
aint nobody got time for that
That's definitely going to happen in 1.0: https://github.com/Unity-Technologies/DOTS-training-samples/blob/dots-training-2022-05-na-group1-Buckets!/Ported/BucketBrigade/Assets/Scripts/Authoring/FiremanAuthoring.cs
Everything unified into 1 Baker<MB> interface.
not much changing compared to IConvertGameObjectToEntity tbh
Ohh, interesting
at least not for the common use case of just binding data and add some IComps
Kinda. No more EM boilerplate in front of all the AddComponentData stuff. Otherwise yea, it's identical.
yeah true, don't get me wrong it reads a lot better but it's all details and i don't care too much about that
dstManager.AddComp or AddComp ... meh
It looks like a GOCS except without the Entities.ForEach() and the primary entity implicit inside the EM actions.
dstManager is quite long though. Especially the GOCS's dstEntityManager.
do you think they'll switch to subscene only approach for conversion
i'll guessing not
ie probably support both
Disappointingly no
unity's heavily pushing subscenes. I think the toggle / MB convert to entity will be deprecated soon
when the ConvertToEntity is gone. How would you convert without a subscene?
They posted recently, on netcode I think, that runtime conversion still a thing in their latest master
I feel like if they aren't removing it in 1.0 will never be removed
one of the things i've always struggled with, that there doesn't seem to be clear guidance on ( and so you have to find out through a lot of trial and error ) is for example when systems are created, vs when mono's are instantiated, vs when mono conversion code runs, vs when subscene content is streamed in and available, etc etc
to me that whole thing is really messy and difficult
whereas ECS itself - no problem, pretty straightforward
At the moment are speaking, ConvertToClientServerEntity it is still present in 1.0. A final decision is still in progress for what I know.
I will check fore more up-to-date status, but it is safe to assume it will be still there.
Jul 25, 2022
the problem being, you have to deal with all these problems because there's no avoiding mono's for UI and other things
UIE team did have plans to expose a DOTS hook to their UI system. That was back during the 0.15 days though and was shelved before it got anywhere.
For now, performance doesnt seem to be that bad just going through mono for UI. That's what unity is doing for the inspectors.
Yeahh plus i think either way, they're gunning for a hybrid approach so i think it would make sense to clear some of these things up
I don't really feel that just dumping a complete example project on github is the best way to do that either
Primarily the docs should be clear on these things
just my 2c tbh
any examples of the aspect workflow in that repo?
or what hybrid workflows look like?
Hybrid no. I'm concerned myself about that as well.
TransformAspect.EntityLookup seems built in
?
in the fetcherMovementSystem. Transform seems to be a builtin aspect
Oh yea, the default 3D transform components are grouped together into a default TransformAspect
which is nice because the roundabout way with the ITransform job was not that great
? Aspects are only an interface to the component. I dont think the transform jobs have changed
hm, is CDFE<Transform> a thing? Never tried it
The GO transform?
yeah
because that's what TransformAspect.EntityLookup does now
and I don't think that worked previously
GO Transform is a Component class. Not IComponentData. So it wont work.
have they started adding Transform to entities then? as a reference to the GO?
TransformAspect is just a grouping of L2W, Translation, and Rotation. The ICDs havent gone anywhere.
i never really used companions so i guess they could have
in which case i think it would be CFE<Transform>
oh really? then it's a REALLY dumb name.
TransformAspect is just this except with RefRW<Translation> Position, RefRW<Rotation> Rotation, etc.
lol, disappointing. i thought that was one new feature that helps with hyrbid
And from what I see from these training samples, there's no integration of aspects with the IJobEntityBatch interface. So we still need to do GCDH<> for job scheduling
Aspects are an entirely codegen feature. Nothing that we, largely, can use.
I imagine if we want to be able to use aspects, we'll need to use the Entities.ForEach lambdas.
yikes!
Are there any good DOTS equivalents of the old CharacterComponent?
i don't believe so but i can't confirm (i very much hope this isn't the case)
That looks like a physics feature. DOTS physics is pretty bare unfortunately so probably not.
You might be able to recreate it using a capsule body and then go from there.
CharacterComponent doesn't implement a full physics simulation, it just implements simple collision
the physics samples has a full character controller
I want to avoid using a PhysicsBody because it's much heavier than what I want
And another question - does anyone know a good way to implement a movement state machine in DOTS? It's usually very object-oriented so it's hard to come up with a solution that fits a data-oriented structure.
From what I've seen so far, there are two obvious solutions:
- Component + System per State
- One component + system for everything and differentiate between states using enums.
Neither really seem like good solutions imo.
The first one is organized, but it means that there'll be a lot of systems running in the background and also means that I'll have to switch components often, which will reset the related cache. The second one is gonna be ugly. If I'm going to have ~15 states, the code will be unreadable. It's also not going to take much advantage of the instruction cache's efficiency boost, so it beats the point of using DOTS in the first place.
first question
what purpose is the state machine serving for the problem you're trying to solve?
a 3d platformer character movement. I'd also like to use a state machine structure for every other living entity in the scene
- even though less efficient will be much faster btw
which solution?
1 system
you say this
It's also not going to take much advantage of the instruction cache's efficiency boost, so it beats the point of using DOTS in the first place.
but i'm pointing out it'll be much faster than your other solution
I'd end up with 10 systems that always run in the background even though most of the times nothing uses them
your best options are the characterController from the physics samples or the Rival asset
the overall performance will improve, but I'm afraid I'll get lag spikes (noticeable or not) when I switch between states. From what I understand, removing and adding components at runtime isn't very optimized
you're reading what i said completely backwards
i'm saying
- One component + system for everything and differentiate between states using enums.
is faster
I was looking at Rival earlier and I was thinking about getting it to read how they implemented some things, but I'm not sure if it's using a PhysicsBody or not
let me check
This beats the purpose of DOTS imo. I'm pretty sure most of DOTS performance boost comes from "abusing" the machine's instruction cache by bulk-running similar tasks instead of scattering them around the game tick. If I have a system with a complex task per entity, I might as well run it scattered anyways because the instruction cache won't be able to work with it.
i think you've over simplifying the purpose of dots
what you're getting here is much better thread utilization
and significantly less main thread overhead
your data is packed even tighter together instead of being split over 15 chunks
I'd always want all of my movements to run on a single thread.
The place where DOTS really shines is the way they group tasks to run together. It sounds simple but it can bring a serious performance boost: https://youtu.be/CBP5bpwkO54
This Unreal Fest Europe presentation by Rare's Senior Software Engineer Jon Holmes covers the techniques employed to efficiently manage the scale of Ticking Components and Actors within Sea of Thieves while also diving into a few real-world examples of how the team optimised these systems and detailing how it all plugs in neatly inside Unreal En...
I did pretty much a state machine with a bunch of enums in one system it was pretty fast from what I can remember
i'm not sure what's your problem with a physics body though. set to kinematic it doesn't do anything
I'm not saying it's not gonna be fast, I'm just saying that it's not taking a lot of advantage of what DOTS has to offer - especially if multithreading doesn't interest you.
I've posted this before but if you want numbers from an actual production environment
original implementation, lots of little systems - 6ms
merging to single system, lots of little jobs - 2.5ms
1 single system, merging into 1 large job (reusing Gets) - 0.75ms
1 single system, 1 large job, burst compiling Gets - 0.35ms
lots of systems is by far the worst thing you can do for performance in entities atm
if you're targeting anything except high end desktop market
I think it takes advantage of dots fine
pretty explicit ๐ ERROR: kinematic character objects cannot have a PhysicsBodyAuthoring component. The correct physics components will be setup automatically during conversion. Conversion will be aborted
very esoteric usage of DOTS. performance is a mix of, linear data, prefetching, multithreading and SIMD. the best code takes advantage of all.
Well then this sums it up pretty well. If multiple systems aren't gonna work and if I want to avoid having big systems with a switch case, I'm gonna need to go back to the drawing board and come up with a 3rd solution.
If you need a lot of systems, use ISystem
it's the only solution to the problem
If you can use ISystem you can get away with a lot more of them
Another solution that was brought up was to not use a StateMachine at all, but it's pretty hard to come up with something new
well that's pretty much why I was asking what state machine provides you
Up until now they've been known as the best way to implement a complex character controller (mainly for 3d platformer games) but they're heavily dependent on an OOP structure. I guess I'll need to give up on that idea if I wanna use DOTS properly
i think FSMs are an OOP concept. not that great in DOD
yeah I'm curious what the alternatives are like is it possible to make something where you don't know and don't hardcode the exact number of states
seperate jobs and queries for mechanics. it doesn't look too different, but it differs from having a huge switch case and calling a method. it's really about preventing polymorphic data
wouldn't that be the same as having multiple systems?
I wasn't saying you shouldn't have multiple systems
I was simply pointing out from your original statement that it's faster to have a single system (most of the time)
its like it depends how fast you want things as well
If you need a lot of systems, try and use ISystem
It gets rid of a lot of the overhead
it's very similar but it prevents overhead coming from SystemBase.
I'm sure if you used multiples systems it would at its base be faster than using monobehaviours
as fast as possible, obviously this discussion is about saving a few milliseconds but I'd still want to use the most efficient solution.
yeah but there has to be limits, just for gameplay's sake you can't just have millions of entities, I don't though it depends on exactly what you are trying to do
behind the scenes it'd still be the same.
no it's not for the reasons tertle pointed out multiple times
"yeah I'm curious what the alternatives are like is it possible to make something where you don't know and don't hardcode the exact number of states"
at the very least I want to end up with something like this
oh right, overhead. Tbh I don't know too much about that, I'll read about it
for the record you can have unknown number of switch statements / states in a job
if you are happy to get low and dirty
my AI system logic/states is built entirely from UI no code gen
you can hook up any number of state combinations
basically just builds a graph
sounds interesting but I don't like to get low and dirty 
again, completely destroys the major efficiency boost of the instruction cache. If an iteration in your loop behaves completely different than the previous one, it'll override the cache and won't carry on to the next one.
who cares
it runs 20x faster than the instruction cache optimized system i have at work
I, the creators of Sea of Thieves, and many other studios who used that technique to save their game's performance
all that matters is the final performance numbers
i can feed through over 100k entities/frame
into my utility AI system in 2ms
there is really no way you run into instruction cache issues in todays hardware. the bottleneck is always data read/write and random memory access
and if you do, you are at point with absolutely perfect memory layout and code
I wouldn't call it issues, it's more of a way to abuse it for extra performance. That's probably why Unity wants us to use systems in the first place instead of having an update function in every component
optimizing in the nanosecond range has no practical purpose if it isn't your dedicated job
yeah are you trying to make a game or a super AI
sorry i lied 200k entities in 1.2ms
what unity has done here, and changed, has nothing to do with instruction cache issues. it's about the data
calling single Update on monobehaviours was a problem because the data is all over the place
I want unreasonably good performance - not because I need it, but because I just like optimizing my code. Even if it requires a lot of extra effort.
that's okay, we all do. but start somewhere. code, profile, rinse and repeat.
(i was/am optimising for several months now ๐ )
Not really sure what you mean by that. The next step of my project is figuring this part out.
i mean, the first step is to make it work, then find the flaws.
mark it as done, I already implemented a state machine that works flawlessly. Now to optimize it I need to come up with a completely different structure that works with dots.
you implemented an OOP FSM with classes and managed memory, compiled in mono/il2cpp?
the question I have is, what type of entity count are you looking at?
Yes, both in Unity and Unreal. I thought the next interesting step would be to get something similar to work in DOTS
great starting point when you can compare
50 entities - some of them have unique states
haha yeah ๐
run it in a single thread from a single chunk (from a single system)
you aren't really going to notice most of the improvements until you hit 1k+ entities
since I'm making it with DOTS, I wanna come up with something that handles more than that. (again - I want performance that I don't really need)
with that entity count all you really care about is removing main thread overhead
your job threads are going to be so empty
it'd be cool to publish it afterwards for projects that'd want to take full advantage of it
oh yeah - I also want everything to run on a single thread. I'm going to run the system on a fixed interval and I'll keep track of the input every call. This way I'll be able to create a perfect replicate of the entire scene just by capturing and storing the inputs. (Perfect for replays, cheat detection, and data logging)
by everything I mean everything that has a collider and moves. I'm gonna use separate entities that smoothly follow their physical entity. These entities can run asynchronously
there's nothing really stopping you doing this with threads
most of entities / jobs are very deterministic as is
you just need to avoid parallel hashmaps really
and any usage of threadindex
The order in which I calculate the entities may affect the result. I need to make sure the entities are updated in the same order everytime I run the scene
it'd be calculated the same way every time
entities is quite setup to be deterministic
there's only a few things you need to consider (and obviously the floating point issue)
and it's very easy to have deterministic threaded code with it
but yeah if you don't care about crazy threaded scaling and you're doing everything on main thread
think about these situations:
- the platform moves away and then the character jumps to the edge of it
- the character moves to the edge of a platform and then the platform moves away
One will result in the player falling while the other will result in the player standing on the edge. This is just one example
if you want performance use ISystem without jobs
it'd be calculated the same way though
each playthrough (if you used a fixed update)
yes, and if they all run on the same thread
that's gonna be bad. I need to wait for one collider to finish to be able to accurately update the rest
the safety system ensures you can't fuck this up
the jobs will be scheduled after each other
then there's no point in running them asynchronously - they're all blocking each other anyways
no?
jobs run after each other != jobs run asynchronously
but the job itself can be parallel
and jobs that dont have dependencies on each other can run in parallel
they all depend on the current position of every capsule in the scene - they're gonna be blocked 100% of the time
collider*
yeah but what about the job that has some creature eating a berry
3 screens away
you talk about the point of dots being instruction layout etc
but imo the point of dots is easy, safe, mulithtreading
and to me there's no point in using entities if this isn't your goal
I'm only talking about the movement system, I plan to use separate threads for the rest.
sure
dots has a lot of good tools for multithreading, I'll definitely utilize it for other parts of the game, but if I want to run something in a sequence, multithreading isn't really a good solution regardless of how good the framework is
you could just you know, double buffer it (if you were willing to use physics it'd be done for you)
i think conveyer belt games are a very simple example of this
they need to not collide but they can't scaling without threading
I can't use physics, realistic physics simulations never give me the result I want.
i'm not saying you need to simulate physics - we actually only use physics for spatial queries at work
I usually code my own simple unrealistic physics - that's why I was using a CharacterComponent instead of a Rigidbody in my gameobjects project
if you don't give anything a physics velocity it basically just becomes a very useful spatial map
sounds like a lot of unnecessary calculations to run in the background.
you're recommending a PhysicsBody right?
all it does is build a very efficient BVH
Every frame it handles collision, physics materials, and (relatively simple) physics simulations. I only need the collisions.
handles collision, physics materials, and (relatively simple) physics simulations.
are you ignoring me
hahahaha
I think I'm missing the point lol
if dont have physics velocity it doesn't simulate anything
in fact feel free to turn off the simulation system it won't be used
Program ya own physics engine. It aint that hard. Then you know how the actual physics engine works
GetExistingSystem<StepPhysicsWorld>().Enable = false
that's the plan, I've done that outside of DOTS
okay, so why did you suggest using them in the first place?
Good luck then. Took me about a month starting from scratch to make my own 2d physics engine. And mine is still shit. But it's deterministic shit.
I still don't see how it's gonna be threadsafe, run in parallel, and give me exactly the same result every single time
Uhhh, physics integration and manifold resolution is inherently threadsafe.
Spatial partitioning can also be multithreaded. Raycasting is a read only operation so it's also threadsafe.
yeah it's threadsafe, but it's not gonna run everything in the same order every single time, one thread might always get ahead of the other, and in that case, nothing will break, but the execution order will be different
in 99.999% of the cases that's acceptable, but in my case I'd like to avoid that
??? What? I think we have a critical communication disconnect on the fundamentals of computational physics simulation.
Why would execution order matter for physics?
read this message
if you update the platform or characters position it doesn't matter because the physics position won't update till next tick
in one case the edge is still there when the character gets to it - so a coliision occurs,
in the other case the edge already moved - so the character just fell next to it
All collisions are detected initially before any movement occurs.
or that ^
In that example scenario, the point in which the player collider checks if it will land on the platform is independent of order of detection.
Either it is already intersecting at that physics frame, or it's not.
Now the order will matter in continuous collision detection but those are dependent on the previous frame's position. In which case, you may have a "ghost" collision for that time step.
Dynamic-dynamic continuous collision is possibly the most complex aspect of a physics engine and it is a very very very deep rabbit hole on how accurate you want to have with those types of collisions.
that depends on how the physics are implemented. Let's say I'm using Unity's old CharacterComponent and I have two gameObjects that call the Move function. They both collide with a wall because of that movement. What will be the order of execution:
- first object moves -> collision event called -> second object moves -> collision event called
- first object moves -> second object moves -> first event called -> second event called
If the second order is the correct one, then yeah, multithreading should be fine
Yes. The second order is how physics gets resolved.
so when will the events get called, in the next tick, or in the same tick after the physics calculations?
The actual order, for box2D at least, is Spatial partition -> Check for collisions -> Resolve collisions (move objects apart) -> Integrate forces into velocity and then onto the change in position.
For DOTS physics, fixed step iteration occurs before simulation step. So same frame.
okay that's great news, I can use multithreading
but since I'm running my "physics" on a fixed interval, is there a way to make unity's physics run on the same interval as well?
From what I understand, the current temporary solution for a FixedUpdate in dots is to update the systems manually through gameobjects, can I do the same for Unity's physics systems?
fixed interval? Physics is already running at 1/50 seconds.
can I configure that/have things run together with it?
That was the solution.... 3 years ago?
You can just add systems to fixed step as well?
I was following some really old tutorials XD update me please
oh is that a simple solution? ok I guess I'll be able to figure it out then
I dont know what you want. It seems like you're trying to think of DOTS as it was object oriented / monobehaviors. But it's not.
not at all, I just watched this the other day but maybe it's an old video https://youtu.be/CA8GssG0HVQ
๐ Unity Sample Projects: https://tmg.dev/ECSSamples ๐
๐ป My Game Development Setup: https://tmg.dev/GameDevRig ๐ป
๐ฌ Join the conversation with other ECS developers at https://tmg.dev/discord ๐ฌ
๐ See below for time stamps ๐
- 0:00 - Introduction and Project Overview
- 1:30 - Theory of Fixed TimeStep Workaround
- 2:27 - Unity Project Setup
- 2:55 ...
oh yeah... published on 2020...
that was from 2 years ago, and I'm fairly certain FixedStepSimulationGroup was released before that
I guess I should stick to Unity's official docs for information
Yes. I recommend that, the official samples, and reading the source.
Got it. now back to my original issue - finding an alternative to StateMachines in a data-oriented environment.
Is an up to date tutorial
I'll read it, thanks!
My Ai is a graph based utility system
I only use state machines for game states (menu, game, options etc)
I do have an I guess automated component based state machine
basically turns a component with a bit field (of any size) and then automatically assigns components to each bit
that will add/remove as the bit field changes
I'm not sure if I'll decide to go with a state machine but I'd still love to read the code, is it opensource?
one day i'll publish a link to this library
there's 2 types
1 where you can only have 1 state active at a time
and another where you can have multiple states active at a time
basically it maps 1 bit to 1 system
i don't use this that much outside of game level states
yeah that's definitely going to help. ty!
because component changes don't scale to the 6-7 digits of entities i benchmark with
but its very acceptable at 5 digits
(good chance it has a dependency on something else in my library so won't compile out of that bat)
I'm probably just going to read the source so it's ok. But @ me if you ever decide to properly publish it
tldr:
implement 1x StateSystemBase or StateFlagInstanceSystemBase which controls the components
then implement N x StateInstanceSystemBase or StateFlagInstanceSystemBase which assigns a component to each bit and put your component login in that (technically you can just implement the interface if you'd prefer to set it up differently)
-edit- just realized my documentation on StateFlagSystemBase is a lie
it's some interesting code
Why does DynamicBuffer implement IEnumerable if it's not implemented?
Is it because of the implementation for NativeArray.Enumerator?
Regarding "Performance by default" why not automatically make everything entities by default? At least on new projects, and/or at least as an option enabled by - drumroll - default, which can be opted-out from if desired
Is the ultimate goal of dots/ECS to replace the object oriented system? Will it eventually fully work with scene editor etc.?
I'm just a bit bothered by all the steps & scripts & "red tape" needed to go through in order to make use of the world of ECS, and hoping/wishing it would be "first class citizen" in Unity, working the ECS way by default with ease, just as the object oriented system works now
This was the original goal, but people objected, so I don't think this is the plan anymore
sad...
It's not finished yet, so that's to be expected
Will it be reconsidered once ECS is well established?
I don't think so. Not everyone wants to use an ECS to write game code
Aw man...
Why is that an issue for you?
You can use ECS if you want to, nothing is stopping you
They should make an alternate scene editor view maybe, for those who want first-class ECS Unity
I mean that part will eventually come, I didn't say they won't make it a first class experience, just that it won't replace the MonoBehavior workflow
There were plans to make a DOTS-only version of the editor which tied into project tiny, but nobody is quite sure what the progress is on that one afaik
so sad how a great technology has to be held back because of nostalgic userbase... Yes an alternate editor version for dots would be ideal
I mean it's not just nostalgia. Some people just want to write OOP code
so make them 2nd class ๐ they should be the ones needing to write converters & authoring components etc
And alienate their entire userbase, sounds like a good plan 
so don't make dots 1st class? Also a sad bad idea
You can make both 1st class...
I don't think this part will change even with 1.0 iirc, the conversion workflow will stay afaik
But I'm not super up to date on that, others here can probably comment further
that's the part I'm miffed about... def looking forward to dots being 1st class not conversion & all that
Like I mentioned, I'm not sure if that's ever going away
I recall reading something about that being the intended workflow, but I don't remember where
Sure they can keep the conversion workflow for those still coming around. But there should also be a ECS-by-default editor
it's ok to make dots/ecs 2nd class with conversion workflow etc. - but why also stifle those who wanna go full-on only ECS? Should have a 1st class editor for that too, doesn't need to mutually exclude each other
I think eventually it will be a thing, but no idea how far they will go with it. Project tiny was originally meant for games-in-ads as a use case, not for a AAA experience. But who knows what they have planned ๐คท
Every once in a while a technology gotta re-think "if we created Unity from scratch today, how would we do it much better?" And once every decade or 2 you gotta consider doing a significant rewrite... Otherwise the ecosystem gets kinda stuck/stifled/left behind in many regards
the need for a dedicated editor has vanished with the authoring/subscene workflow
^
I think they will eventually revive tiny regardless, just for the use case, but it will probably be focused on small experiences (e.g. only 2D physics, etc)
But it needs a LOT of scripting red tape, no? If it was "1st class" it would be a lot more streamlined wouldn't it?
It's not a huge amount of boilerplate
You just define your data and how it is converted
There's lots of places in ECS that require more boilerplate atm imo
wdym? if you are getting at the missing animation package or smth, okay. it will be released eventually. prioritizing entities at this point when it's not even at 1.0 makes little sense
What i mean is โ๏ธ are you sure it "vanished"? If Unity was invented today (with dots/ecs in mind) there would be a lot less boilerplate to script and itd be a lot more streamlined & integrated into the graphical editor & tools, i suspect
They will revive tiny. A lot of the experimental hooks for rendering and such are still baked into the engine in 2023.1A. If it was dead, they would've deprecated them.
Yeah, that's my thoughts too.
I haven't checked 2023.1A though, so that's good to hear
The issue at hand is that unity is trying to work around the limitations of C#, not the engine itself.
Yea. The hook for DOTS sprite renderer still exists in 2023A. It's hot garbage and completely unoptimized but still works.
haha
boilerplate is minimal. anything more specific? data has to be defined. systems have very little boilerplate, same goes for jobs.
Using the codegen jobs has minimal boilerplate. Actual jobs on the other hand, oof.
and unity is lagging behind bringing core systems to dots. at some point the gap will be closed. then there will be more development again in tiny and the editor. although i think tiny will be deprecated on the way
What they need to do is create a codegen version that passes in raw pointers and batch count. That's the bare minimum rather than the current handholding and unoptimized mess that is IJobEntityForEach or whatever it's called
I guess no more specifics, just general rantings of a noob's experience trying to make use of The New & Improved & Performant dots/ecs, it's much more script-heavy than when a newb starts learning Unity object oriented editor
Well ya, it is script heavy. But ECS itself is not really a newbie friendly coding style.
That's what i mean that the need for a dedicated editor has not really vanished
Unity has awesome appeal to ppl wanting to try their hand at it, and dots/ecs has amazing promise for performance, but the ease of tools is missing for dots/ecs
I don't personally see the current way it works as an issue. The boilerplate required for conversion pales in comparison to classic authoring time editor tooling that large games require
That I dont get. Authoring, once you get to know it, is 100% functional and actually very good. With the new Baker interface in 1.0, I think it's perfectly fine.
maybe i just don't see what a dedicated editor can bring to the table. it won't help with coding.
That's also something I like, you can put as much authoring crap and functionality on your authoring gameobjects as you want, once the game is actually running and converted it's gone
Ye I'm not entirely sure about that myself... But was guessing/hoping there were indeed a bunch of steps/boilerplate which Unity can actually just do by itself automatically by defualt, or something... And only needs scripting intervention just for the specific aspect of how to cut up data & behavior systems
that's where the IJobEntity, Entities.ForEach helps. with code generation
How to format your data and system structure is completely up to you. Unity isnt there to code your game for you.
A lot of people aren't happy with all the black magic unity already does for you, and actually want less
And I'm one of them. Unity needs to stop fucking handholding us. Just let us rip out the raw pointers and be done with it.
Yeah, I'd agree too
Why not? We need to imagine bigger ๐
Eventually you need to work with raw memory anyways
well you're not a noob being enticed to try out the wonders of Unity
Those kind of people flock to monobehavior first, since you can build 99.9% of indie projects with it i'd argue
except - why would you? If it were possible to build the same game with same/similar editor, but in dots/ecs
Because people like writing OOP code
convert all monobehavior Update() methods to systems
oh boy ... that discussion
You can theorize all you want, fact of the matter is game objects very unlikely to go away, and from what we know, the conversion workflow is here to stay
unless we have AI that can program itself
Now we're talking
Think different
๐
the last stage to singularity ๐
I'm currently stuck on conversion myself TBF. DOTS is suppose to be an entity driven system but using the built in 2d physics, that means it's a GO driven architecture and conversion really isnt intended for that.
How would they have implemented dots/ecs if the community didn't push them back into the conversion workflow, and why can't we still have that as an alternate option of building with dots/ecs
re. โ๏ธ
I mean we can't know, maybe they would have gone with this approach anyways. No point in theorizing about what could have been
I'm not sure I follow. You mean you use the 2D physics during runtime?
Yep. And those only work on GO rigidbodies and transforms.
So I need to conduct movement actions on GOs and then pull that data to the TRS components on entities.
I'd argue that's an issue separate from the conversion workflow, more like an issue with hybrid DOTS atm
Yea. And Unity made the companion link component type internal to Entities for some fucking reason.
I have a similar gripe at the moment. I'm working on some simple runtime inspection of entities, and there is no GetComponent that takes a ComponentType because Unity doesn't want people to "accidentally" use the slow version, so they just don't put it in at all and force me to use reflection...
yeaaaa, pain
Like, if that's the issue, hide it in some weird static utility class or something...
i've written some scripts to handle hybrid. i don't like having to do that myself. some streamlined version from unity would be great instead of everyone rolling their own. and yeah, going from MB to entities is weird. especially when there are some edge cases where it goes from MB->entities->MB. this really sucks
I think that's mainly stemming from the fact that it just isn't finished. I hope they have all of this sorted out with 1.0
(although I doubt it)
Hybrid will definitely not be resolved by 1.0.
I rarely check development updates, that's what I assumed
There are 0 examples of any hybrid interactions in the training github. If they're not training people on how to use hybrid dots, that means they're not ready to indicate that hybrid is production ready
I meant more along the lines of, make it less mandatory to go the hybrid route if you want stuff like sprites, 2D physics, etc
hybrid was on their roadmap for 1.0
"It just works."
Todd? Is that you? 15x the detail?
Yes, and there will be a new editor tab that will just be an instance of skyrim, integrated into the engine.
Basically just a GO with a wrapper entity at this point
i think its better to just manage the companion stuff manually unless those gameobjects will never be destroyed/instantiated
(and I never use 2d so not sure how tilemaps are used)
I kinda am?
I got my own GO -> Entity sync. Otherwise these are all just references to the components.
References to skip using .GetComponent<>() on the CompanionLink GO which is a reflection find.
i mean if it has a companionlink on it, it is still governed by the builtin companion update systems isnt it?
Didn't know about that or syntax, pretty cool
I use my own 2D transform components
Yea, it's to cut down on the code
Those systems still exist but since all these components are custom, they never run.
It's annoying that I cant get rid of them but they're just tags so they dont take up chunk space.
I skip touching companion anything for my entites that rely on gameobjects. gameobject is a prefab that gets instantiated and then pooled so I can create/destroy entities and reduce gc to a bare minimum of one class component(and then just access attached gameobject components from that one icd). could probably do something to manage them without even adding a class component reference but currently it is acceptable for my use
Yea. Pooled GOs of the same type would work but I'm lazy.
Hey folks i was wondering if someone could help - how do interpret this in particular the Semaphor.WaitForSignal - what is that and i'm guessing it's not great that it's taking up so much time in this stress test..
What does the timeline look like
a lot of physics steps
looks like it simply waits for jobs to finish
Yep. Looks like its waiting on jobs to complete. Expand the jobs tab below
bit more zoomed in and showing jobs
Well, there's ya issue. Blockman targeting system is quite expensive
and not well optimized.
okay yeah i was wondering about that
For one, it's a lambda job. Which means if you want to start optimizing, break out the copy paste and refactor it into a IJobEntityBatch.
when i look in hierarchy for that system it's not showing up as taking a lot of time:
but i don't think this reflects the jobs themselves right
The timeline is always correct. Hierarchy is ehhh
why even look at hierarchy with threaded code
the system doesnt take much time to schedule the job but the job itself takes time
right yeah
okay so it's probably a good time to start looking at struct jobs then i guess ๐
finally
at long last
do you need to run it inside the fixedstep group?
Is there a big performance hit to generated jobs? I usually just make them IJobEntityBatch for cleaner code
there is none from what I know
unless you use chunk specific optimizations
You cant optimize them as well. If you consider that a performance hit.
Like reusing per-job temporary collections?
mmmm i haven't tested with it outside of, it's actually unit targeting and movement update, which then propagates to my next system which applies the values as velocities ( so i keep that before end frame physics )
nah, actual chunk specifics, like checking system states and etc
Are there any DOTS specific optimization guides? I don't think I've ever seen any
im not unity pro, so why am i getting this
A Hybrid Renderer V2 batch is using the shader "Universal Render Pipeline/Lit", but the shader is either not compatible with Hybrid Renderer V2, is missing the DOTS_INSTANCING_ON variant, or there is a problem with the DOTS_INSTANCING_ON variant.
also getting this issue, not sure where the fix lies
nm... was my mistake. * totally works... lol
Note: Shader Graphs and shaders that Unity provides in URP and HDRP support DOTS Instancing
so what am i missing, latest URP installed
ah wait there i thought 0.51 is compatible with 2021.3 LTS. I guess not hehe
It is
oh right, so why these errors
Are you only seeing this once?
every time after the havok subscription warning
If you only see this once rarely it happens because the variant hasn't compiled yet
It should be fixed in 1.0
As long as you can see stuff of screen there's no issue
ok well im trying to open it as a new project. initially i was adding it to a project, but must have a wrong version somewhere
right so, semi working
it seems the shader works in editor, until i press play, then get the pink shader of error
Logic
Just started getting this randomly on my random array of length=workers
after moving the system from fixed step to the simulation group
perhaps an order issue, i usually interpret that as the array has no values assigned
Why
If they log the error first you can see it from burst
Instead of just getting an exception with the format string and no data
Ah, gotcha
Alright, found a use for the runtime conversion pathway: Hybrid DOTS.
Baked conversion makes GOs that are not added to the global update sequence. For example, setting a velocity on a rigidbody GO component of a hybrid entity will not move the object
However, using the runtime conversion (not the subscenes), the clone GO will work
Looking at this for my GOs
And this for my entities. Everything seems to work pretty well for a hybrid format
Hey everyone (especially tertle)! I'm using your event system for dots and I wanted to ask: does ConsumeEventSystemBase actually consume the event (as in destroys it and not let it through)? What I mean: if I have three systems that consume the same event, System1, System2 and System3, will Systems 2 and 3 receive the event or will it stop at System1?
no
all systems will receive the event
i guess poor naming but i just like the name of produce/consume ^_^'
Thanks!
huh, I thought I'd be crafty and use a class IComp for a singleton and now GetSingleton only supports structs
@viral sonnet there totally is extensions for this built into entities
public static unsafe class ComponentSystemBaseManagedComponentExtensions
{
/// <summary>
/// Gets the value of a singleton component.
/// </summary>
/// <typeparam name="T">The <see cref="IComponentData"/> subtype of the singleton component.</typeparam>
/// <returns>The component.</returns>
/// <seealso cref="EntityQuery.GetSingleton{T}"/>
public static T GetSingleton<T>(this ComponentSystemBase sys) where T : class, IComponentData
{
var type = ComponentType.ReadOnly<T>();
var query = sys.GetSingletonEntityQueryInternal(type);
return query.GetSingleton<T>();
}
/// <summary>
/// Sets the value of a singleton component.
/// </summary>
/// <param name="value">A component containing the value to assign to the singleton.</param>
/// <typeparam name="T">The <see cref="IComponentData"/> subtype of the singleton component.</typeparam>
/// <seealso cref="EntityQuery.SetSingleton{T}"/>
public static void SetSingleton<T>(this ComponentSystemBase sys, T value) where T : class, IComponentData
{
var type = ComponentType.ReadWrite<T>();
var query = sys.GetSingletonEntityQueryInternal(type);
query.SetSingleton(value);
}
}
#endif```
In ComponentSystemBase.cs line 658+
does any of you run on the apple silicon? burst 1.7.2 seems broken on this version of the editor and was wondering if you knew one that's not
ah thanks! the extension isn't detected and i don't have UNITY_DISABLE_MANAGED_COMPONENTS set. any idea?
ok got it, i need to use this.GetSingleton
no idea why it needs this in front.
because it's an extension method
(i forget that was required because I use this as standard ^_^')
oh ... right. of course. i'm getting sleepy ๐
Hello,
I tried to update Angry Bots to 2021.3.8f and Dots 0.51 version. Here is the repo: https://github.com/kharalos/AngryBots_ECS_2021.3
I managed to convert the code and use URP and the scene works but the player creates a clone of itself in the hierarchy and makes the controls junky. If I disable the clone after the scene plays then everything works fine. I tried to understand why it happens but failed. Can anyone help me?
that is a very old project to be updating!
is your problem you don't know why it's making a clone?
yes
Are you using convert to entity script?
should I just not use it on the player?
convert and inject creates clone of original game object
while creating entity
so at the end you have 1 original game object 1 clone game object and 1 entity?
is there a math function I can use to determine the angle (or radians) difference between two quaternions?
yes, that's not meant workflow
I see
There's the best practices course, if you haven't already seen it https://learn.unity.com/course/dots-best-practices
If youโre working on a game (or other real-time simulation) that requires the most efficient CPU usage possible, then Unityโs Data Oriented Technology Stack (DOTS) is a great way to get the performance you need. However, to use DOTS successfully, you canโt simply grab the API documentation and dive straight in. Before you begin creating a projec...
math.mul(
firstQuaternion,
math.inverse(secondQuaternion)
)
should give you the difference as a quaternion if I'm not mistaken
yeah but I need it as a float angle/radian
I don't find a Quaternion.Angle() equivalent in mathematics package at first glance ๐ค
you could reimplement your own dots version based on the source
// Returns the angle in degrees between two rotations /a/ and /b/.
[MethodImpl(MethodImplOptionsEx.AggressiveInlining)]
public static float Angle(Quaternion a, Quaternion b)
{
float dot = Mathf.Min(Mathf.Abs(Dot(a, b)), 1.0F);
return IsEqualUsingDot(dot) ? 0.0f : Mathf.Acos(dot) * 2.0F * Mathf.Rad2Deg;
}
// Is the dot product of two quaternions within tolerance for them to be considered equal?
[MethodImpl(MethodImplOptionsEx.AggressiveInlining)]
private static bool IsEqualUsingDot(float dot)
{
// Returns false in the presence of NaN values.
return dot > 1.0f - kEpsilon;
}
"AggressiveInlining" love that
Interesting. Wonder if he was hired by unity but I see no evidence of that yet
Damn I paid for that asset xD
Is that asset source free?
Yep.
Yes, but what's your il2cpp problem
maybe next time. i tried some of the ecs samples
tbh think i might be running out of memory on build, although i have 32gb
i found the boids example interesting, was wondering what its like on build. il2cpp multiple issues, mono build no entities show
ill try one more build, but its not going to build im sure!
subscene concept is interesting, assume i need to include in build
warnings on mono build and no show on entities (or subscenes)
ok il2cpp actually built that time, for once
but crash on load
well i had hope lol
IL2CPP must have the build for reduced file size to function
rather than faster runtime?
I dont remember the setting but yea. You have to toggle it on
No clue then
Passing stuff from the outside into a Entities.ForEach... does this allocate memory since its a closure ?
@robust scaffold where do i get the error log on load?
?
Development build?
oh do you have to have it in dev mode
it comes up with the unity crash window briefly
Could not open file F:/Programming/Unity/Downloads/ECSSamples/Build/Boids CPP2/Jobs_Data/StreamingAssets/EntityScenes/e1e53224c62f2477ea66ccbee8043957.entityheader for read
Could not open file F:/Programming/Unity/Downloads/ECSSamples/Build/Boids CPP2/Jobs_Data/StreamingAssets/EntityScenes/9c5ff16a37c4a4220a0e7795b6c38c6d.entityheader for read
Loading Entity Scene failed because the entity header file couldn't be resolved: guid=e1e53224c62f2477ea66ccbee8043957
seems the problem is here
hmm there is no streamingassets folder?
so entity projects must use the platforms package to build always?
Yes, for now. 1.0 DOTS will not need it
@robust scaffold doesnt ask where i want it built to?
lets see what happens, but no idea where its building to
ok, Builds folder
and it crashes, oh well
maybe ill try again tomorrow ๐
Mon 2x builds, but not il2cpp (crash on load)
mono
interesting
normal IL2CPP that built, works, if i copy the streaming assets over
but yes pretty impressed with 25 mil verts, 4k at 60fps
on a gtx 970
cpu is also quite old but still powerful, 3930k 6core
at least i learn to use the build pipeline, just to get the streaming assets folder
Huh, recent 2023.1A update has pushed documentation on IJPFT. Possibly the best documented IJPF variant now. And I was there when Unity threatened to remove it back in the day. Now it seems like it's a permanent addition, if they documented it and provided a code sample.
well they're embracing hybrid so they kind of need this
Still seems pretty clunky TBF. Would be nice if they added another API layer on top of TAA so I dont need to manually juggle and pool GO.Ts
huh good for phil to make something that unity decided to purchase. wonder what this means for the long term of the dots charactercontroller now
hot compiling and reloading compute shaders is iffy
where did you read that?
oh, have to scroll up. nvm
huh, damn. paid for it. never used it. lol
great stuff though!
Ya know, I wonder if a valid anti-cheat would simply have the entirety of the game logic and data located on the GPU. I'm pretty sure the majority, if not all, memory skimmers and cheat engines read from CPU memory. Assuming deterministic lockstep simulation using fixed point integer mathematics, current cheat engines would need to pull gpu memory and then parse the data in order to obtain hidden info. And that is pretty expensive. Anti-cheat through lagging the computer to the point where the game is unplayable.
You'll need to completely rewrite a gpu driven physics engine though. Practically write a gpu game engine at that point.
hm, you don't have to go that far. what if you just store crucial values on the gpu and pull them for the cpu to read?
Just something I thought up on the fly as I slowly grind my way through setting up rendering hooks.
what do i use to run managed main thread jobs? i can't find it and i remember it's possible
i'd write normal main thread code but i don't want to use .Complete in the system
Turning off burst?
.Run()?
job struct doesn't work with managed classes, right?
It does, if you turn off burst.
The second you remove the [BurstCompile], you can do anything
Including using classes cross main-job boundaries and so on.
huh, no idea where i got the error then. been a few days ๐ i'll try thanks
InvalidOperationException: RewardPlayerJob.inv is not a value type. Job structs may not contain any reference types. ๐ฆ
How did I manage to set shared component data inside a job then? hrm. Let me try
{
public NativeList<MonsterDrop> monsterDrops;
public Inventory inv;``` simple class here
Hrm, I think I manually allocated the class using c#'s GCHandle, which is a struct, then converted it back to the class inside a job
GCHandle handle2 = (GCHandle) parameter;
List<string> list2 = (handle2.Target as List<string>);
``` Largely what I did to pass in classes. Burst compile must be off in order to use the class as well inside the job.
how does Entities.ForEach do it?
like ```Entities
.WithoutBurst()
.ForEach((
Entity entity,
Animator animator,
in Rotation rotation,
in Velocity velocity
) =>
{```
True, how does the codegen look like?
uses public Unity.Entities.ComponentTypeHandle<UnityEngine.Animator> __animatorTypeHandle;
That can be used in a scheduled job?
not bursted of course
How do they get the actual class data?
that i need to find out. tha compiled job uses .Run
var animatorAccessor = chunk.GetManagedComponentAccessor(__animatorTypeHandle, __this.EntityManager);
huuuuuh. Interesting
then just animatorAccessor[entityIndex]
where the index goes from 0 to the chunkCount
well, i already have the inventory i want to access on a singleton entity ๐
if you pull from the gpu onto the cpu what's stopping you editing it during this stage
it doesn't execute a job
if you're writing IJob without burst and using Run
why write it as an IJob
what's the alternative? i think i have been there. my previous solution was to run it in another system group
So we dont need to go through GetEntityArray
an IJob without burst and using Run() is just a struct
just create a method in your system it's the same thing
well, i need to schedule as i have a dependency
Dependency.Complete()
MyMethod();
Can you see how they attached the scheduling of that managed component handle?
hm, what's the reason i can't schedule a job with managed objects?
fundamental restriction of the job system
it won't pin the managed objects
but holds the job as a pointer
Unity.Entities.JobEntityBatchExtensions.RunWithoutJobs(ref __job, HybridAnimationSystem_LambdaJob_0_Query);
if you want to pass managed objects in, pin them and pass in a pointer to them
This works, somehow.
yeah see it's not running as a job
it's literally just calling the execute method on the main thread
The handle. I'm using the direct EM method.
But it does work, somehow.
It defies all logic I know about job thread boundaries.
new DisposeJob
{
FluidData = state.EntityManager.GetComponentTypeHandle<FluidData>(false),
EntityManager = state.EntityManager
}.Schedule(_fluid).Complete();
``` Yea, it works.
i mean without even completing it
I still need to complete since Im doing a structural change right after
Absolutely magical. I have no clue what black magic unity did on the back to make it possible.
public unsafe struct SharedComponentDataFromIndex<T>
where T : struct, ISharedComponentData
{
#if ENABLE_UNITY_COLLECTIONS_CHECKS
private readonly AtomicSafetyHandle m_Safety;
#endif
[NativeDisableUnsafePtrRestriction]
private readonly EntityDataAccess* m_Access;
#if ENABLE_UNITY_COLLECTIONS_CHECKS
internal SharedComponentDataFromIndex(EntityDataAccess* access, AtomicSafetyHandle safety)
{
m_Safety = safety;
m_Access = access;
}
#else
internal SharedComponentDataFromIndex(EntityDataAccess* access)
{
m_Access = access;
}
#endif
public T this[int index]
{
get
{
#if ENABLE_UNITY_COLLECTIONS_CHECKS
AtomicSafetyHandle.CheckReadAndThrow(m_Safety);
#endif
return m_Access->GetSharedComponentData<T>(index);
}
}
}```
i have this, you could totally write one for managed components as well
you can't use entity manager if you don't complete though
Burst job accessable?
because it breaks as soon as next system tries to use it
well no because it's still managed data
but yeah if you use EntityDataAccess* instead of EntityManager it works fine to schedule it across systems
Readonly, yea. Makes sense. How is this created?
public static unsafe SharedComponentDataFromEntity<T> GetSharedComponentDataFromEntity<T>(this EntityManager entityManager, bool isReadOnly = true)
where T : struct, ISharedComponentData
{
var access = entityManager.GetCheckedEntityDataAccess();
var typeIndex = TypeManager.GetTypeIndex<T>();
#if ENABLE_UNITY_COLLECTIONS_CHECKS
var safetyHandles = &access->DependencyManager->Safety;
#endif
#if ENABLE_UNITY_COLLECTIONS_CHECKS
return new SharedComponentDataFromEntity<T>(access, safetyHandles->GetSafetyHandleForComponentDataFromEntity(typeIndex, isReadOnly));
#else
return new SharedComponentDataFromEntity<T>(access);
#endif
}```
extension method
it's actually writable if you want
good for writing data to RenderMesh
without a sync point
Oh, the entity manager just is used to pull entityManager.GetCheckedEntityDataAccess(); Thats basically what unity is doing.
If you write to a shared component, doesn't that mean structural change?
i'm not doing a set component
but if the shared componetn has a managed object
and i change a value
there is no structural change
but the write handle makes sure this is safe
(within entities)
Shared components rely on IComparable to ensure no collisions. I guess if you modify something outside the comparison, that wont be a structural change.
well yeah but your IComparable usually would depend on the reference equality
not the actual data within it
true, huh. Interesting
This seems really easy to extend into unmanaged shared components. At least a readonly functionality while still able to modify NativeArrays and other reference types. Why hasn't unity done this yet?
i'm sure you could do some dumb things
I can already do a lot of dumb things with the pointers available.
Jesus christ unity. Class name already breaks the max character limit.
I wonder, why use DynamicComponent when I can just use a generic job?
Damn, I thought I was onto something
if you know your type you should be able to use a generic job fine
Nah, it doesn't like creating a component type handle with generic component type.
i do this
why not?
what is idx
oh you're doing it through entitymanager instead of system
yea
System doesnt allow for managed component types... well in this case it shouldnt matter
yeah your idx
what is it
your AddTransforms generic doesn't seem to match
unmanaged
not struct
you are passing a struct generic
which might not be unmanaged
Just changed that
Both are unmanaged to get the most narrow equality
Error's unchanged
It uses managed components. It's not bursted
It's pulling the companion link game object's transform and adding it to the transform access array
well in that case, all work
Just wild.
Hrm
Looks like this doesnt work sadly
It compiles sure but the reflection throws error
Actually thats not the issue. hrm
oh hmm yeah i think the same generics rules apply even if you're not using burst these days >_>
Well fuck, guess this wont work anyways since a private field of transform access array is not prefixed with NDUPR
i'd like to mod 3d model games like stumble guys
i search everything in youtube but i never found 1 that works
Welcome to DOTS. I dont think this is the right place for that?
Ask in #๐ปโcode-beginner
just turn off safety on the whole job ๐
What's the attribute?
yea. there's the toggle within burst.
time to reinterpret and make your own copy with attributes
pain
I think I'm just gonna stick with the slow non-job'ed version. The second I need to make my own wrapper copy is a bit too far.
It's not scheduled anyway
I think...
So you can probably get away with generic chunks iterator
alright help me out here, what am i missing..
when the simplest thing suddenly causes problems moment,
i moved this system into fixed step to diagnose raycasts not detecting hits
Not really sure what you're showing us
Things missing if usually causes by bad layers
Either your belongs to or collides with
The error i'm getting re CreateProjectile not being assigned to a dependency
Oh whoops didn't see that on my phone
If there no second exception?
This usually happens from another exception and the system exiting early
no
it's kindof weird tbh
restarting the editor, was just having some lunch
yeah still doing it
i figured i was just missing something obvious
yeah, tertle wrote some ๐
yes i have a dozen or so custom job types
any example to share?
interesting
this is pretty cool actually, cause that means you can use Job system for custom ECS
so when i comment out the first job on this ( the offending one that's complaining about CreateProjectile ), i get an error saying the previous system ( collision system ) is writing to the world RigidBody array..
The problem is both systems are RegisterPhysicsRuntimeSystemReadOnly() and i'm not writing to the world.Bodies array
i am reading the Bodies though
If you're updating inside fixed update you still basically have to order your systems properly
Physics is a big reason why I'm strongly against coupled systems
It's so painful to use
yeah i get that, i can't see any issues with the ordering, or why it's complaining that i'm writing to bodies
hmm i'm pretty sure i've copied the ordering in the collision system from the samples, it's basically just a bastardization of their stateful collision event setup
but again, i'm not writing to the bodies at all
the collision system works fine etc
issue is it thinks i'm writing to the bodies in that system
So whats the reasoning for ordering it for block Man but not projectile
well i've just arbitrarily set projectile system to run after the collision system
hmm physics samples actually orders their stateful job like this:
mm i don't follow
Projectile can satisfy updating after blockman while also updating after end frame
While blockman must update before end frame
So either you're saying blockman doesn't need update before or you should add an update before to projectile
I'm not certain this will fix your issue, I'm just pointing out an inconsistency with your ordering
hmm i'm not sure that matters at all
i get what you're saying, the first job is set to run before end frame, whilst this isn't specified in the second job.. but it doesn't matter, they still order as expected:
so i guess i need to figure out why it thinks i'm writing to bodies, when i'm not
Show scheduling code for blockman
1 sec, trying what you suggested in any case ๐
same, so basically this:
i guess it could be that Job, but again, it's only reading from not writing to bodies
You're ignoring the part where it doesn't know that
The read only tag is used by burst
well that's what this if for right:
That's the interesting thing here I'm thinking about
If they're both read only
They can both execute at same time
But it shouldn't matter because as you say, no writing
when i add a dependency to that Job above, to ensure it 100% is linked up in the dependency chain with the CollectCollisionEvents job, it makes no difference as expected
Convert collision etc etc could you should the schedule part
so obviously it thinks i'm writing to bodies in this collision system, and i need to figure out why and how to tell it i'm not
Are you not missing withreadyonly(bodies)
hmmmmmmmmmmm
maybe
damnit i think you're right
YEP
holy damn
it never occurred to me for whatever reason, that i'd need to specify that, or i've simply just overlooked doing it
as it was set to RegisterPhysicsRuntimeSystemReadOnly
thanks @rotund token ๐
Ok good because it's way past bedtime and I'm sick and need to sleep
Have a good day
Cheers, hope you're feeling better tomorrow.
When i pass something into a Entities.ForEach from the outside... does this allocs memory since its actually a lambda ?
i think yes unless it is a pointer to native memory, like a NativeArray
Oh shoot, thats why system generates like 1.5mb per call
Damn and how the heck can i pass stuff into it without generating tons of garbage ?
no
what is it exactly you're doing?
well, depends actually on what you're passing
cause native array is passed by value, but it's not literal value of all elements, but just pointer
// Initialize and spawn a prefab/gameobject with network transform and rotation
Entities.ForEach((Entity entity, ref Mesh mesh, ref NetworkTransform networkTransform, ref NetworkRotation rotation) => {
if (!mesh.instantiate) return;
var contentStorage = Database.GetContentStorage(mesh.id);
var goContent = contentStorage.Get<GameObjectContent>();
var prefab = goContent.Representation;
// Spawns gameobject asset and assigns it to the component
var pos = networkTransform.pos.AsUnityPosition(mercator, Map.WorldRelativeScale);
var handle = prefab.InstantiateAsync(pos, rotation.value);
}).WithAll<MeshAdded>().WithoutBurst().WithStructuralChanges().Run();
Little example of my method, running on the main thread and its use is to spawn in gameobjects for me.
Database is actually existing outside of the loop... mercator too...
A class, sorry forgot to mention... mercator is a struct however
But in case of a closure/lambda both should be copied right ? Atleast i know that closures and putting stuff into closures is pretty bad for gc
it maybe be the Instantiate that's generating garbage
you tried running without just that last line ( var handle = ) to see if it avoids the garbage
Hmm thats actually great i think... and yes the instantiate creates garbage, theres no way around it. But my profiler tells me :
Damn i dont have the profile anymore... atleast it told me that there happens many many Gc.Allocs inside there for some reason. The instantiate calls however were listed seperatly
it's kinda hard to guess what you're getting back from any of these lines tbh:
var contentStorage = Database.GetContentStorage(mesh.id);
var goContent = contentStorage.Get<GameObjectContent>();```
not familiar with those
Did a deep profile looks like i was wrong
Looks like ALL the allocs are really happening from the adressables stuff
Kinda sucks, thought the adressables speed up things
they do?
