#archived-dots
1 messages ยท Page 4 of 1
so i guess really it depends how much data you're storing in the buffer ( ie whether it's faster/slower than a blob )
yes, it's all about keeping your data as local and small as possible
and i think the true strength of chunk buffers lies in simd.
and if it's not simd, at least that it's linear data
i think a blob should at least provide fast linear and native memory access right
can't say that for most blob data. at least not in my case. i save spell data in blobs and that's quite a lot of data alltogether
in my case i'm using a blob to store for example 1500 float3's
so i don't think db would work there, in fact i don't think there's any real alternative
sounds like amination data ๐
exactly what it is
blobs are linear, yes the layout is like [blob struct data][ptrs/length][...][arraydata1][arraydata2]...
i'm not optimizing for the moment but yeah, just curious about that
seems fine to me, the first access is random but then it's linear
atm it's just a flat array of float3's, all bone pos/rots packed into a single array
i'd not save this any other way. you are not capped by any 16k limit
can I have second opinion on that? ๐
hm, i dunno, try it. should be a fast test ๐
i'd say it doesn't work but who knows ๐
it doesn't
Inheritance is a naughty word here in dots land
word
I'm pretty sure someone showed me that interfaces has some clever applications
and I don't think it was about generic jobs
nvm memory is a funny thing
Is this what you remembered reading about? SceneManager.MoveGameObjectToScene(GameObject go, Scene scene) ?
Tried it, works perfect. Before this I tried what you mentioned Open scene, instantiate, and then go back to previous scene. T'was a disaster, buggy.
Maybe. My research aimed for smth else, kek
Great it works
It'll probably a good feature for designer tools
Anyone recognize this error from doing a build:
not using subscenes, wondering if my gameobject which is building a blob during Convert ( just in a mono / IConvertGameObjectToEntity ) has anything to do with it
last time i built was prior to building any blobs and it worked ok.. only other thing is, i recently created a new blank project and copied my assets/scripts in, so there's maybe possibly an outside chance it could be a package problem, but i doubt it
Is this just a compile error?
I've seen this before when setting up a new project
What .net are you targeting
And do you have netcode in your project?
well oddly, it seems to have gone after messing around with it ๐
i'd deleted the sample scene which comes with a blank template URP project, which was showing as 'deleted' in the build scene list, so i removed that, enabled dev build, clicked my heels together three times and rubbed my nose, and error seems to be gone
spoke to soon it came back
no netcode no, targeting .net 4.x but flipping back to 2.0 just to try and get this to go away
entities only supports standard
i'm 99% sure my previous version of this project was 4.x
was that before 0.50 or 0.51?
now i'm getting some staging error
no, same 0.51
did you add local packages recently
no
just entities/hybrid/tmp
going to load my previous project and compare/doublecheck
weird error, i'll try a restart, maybe as i'd changed over to net 2.0
not sure sorry but i can tell you that there are at least 2 studios who had this error targeting .net framework after a 0.51 upgrade and fixed it switching to standard 2.1
the error generally occurs anytime a package change is made
including any use of asmref
(the original, no idea about that new weird one)
rather than importing from git url, i manually changed manifest which was probably a mistake
when i was setting up the project
dont think that should make any difference
i had a couple of odd issues during that
anyone who pulls repo has to setup via manifest
mm
it's also locked this folder even after closing unity, inside my build dir
just having lots of fun
just restart your pc on that
if you check task manager you will probably see some process not closed
unity.exe
or some compiler
'just' hehe
easier/faster to just restart
yeah
is it possible to setup performancetest data via subscenes? the editor entities are there so shoudkd be possible, right?
Never tried but I don't see why not
Just load the subscene into a custom world in the test
Just need to add the 2 or 3 scene systems that are required for loading then tick it until it's loaded
hm, gonna try it. i need some better testing ground ๐
now i've time to get back to the stats reading. that last coding session really annoyed me. i tried 3 different ways and every way was slower. i came to the conclusion. as i'm reading a few stats in the first job the must be already in cache and it's faster to then build the stats for the spell calculation. otherwise, i don't know how to explain that the first job needs 1.5ms for building and another job needs 2+ms
Only concern would be maybe the requirement for editor tick to load assets but in pretty sure there's a way for unit tests to support this
hm, i guess i don't need a full subscene. just a prefab that has to be converted
Probably an easier alternative
Generally everything in my subscenes are prefabs anyway so I don't need to open to edit them
Getting some strange behavior, can someone help me understand why this is happening? Ok. So I have static Game.Save(), which writes to disk data gathered by an ECS job like so var data = await _system.GenerateSnapshot();
_system is a SystemBase class. Here is the async GenerateSnapshot() method:
public async Task<WorldSnapshot> GenerateSnapshot()
{
// gather all unit positions and rotations
var unitSnapshots = new NativeArray<UnitSnapshot>(_unitQuery.CalculateEntityCount(), Allocator.TempJob,
NativeArrayOptions.UninitializedMemory);
var unitSnapshotJob = new UnitDataExtractionJob
{
unitGuids = _unitQuery.ToComponentDataArrayAsync<UnitGuid>(Allocator.TempJob, out var guidsJobHandle),
transforms = _unitQuery.ToComponentDataArrayAsync<LocalToWorld>(Allocator.TempJob, out var transformsJobHandle),
unitSnapshots = unitSnapshots
};
var dependencies = JobHandle.CombineDependencies(guidsJobHandle, transformsJobHandle);
var unitSnapshotJobHandle = unitSnapshotJob.ScheduleParallel(_unitQuery, dependencies);
Dependency = JobHandle.CombineDependencies(unitSnapshotJobHandle, Dependency);
while (!unitSnapshotJobHandle.IsCompleted)
await Task.Yield();
var snapshot = new WorldSnapshot(unitSnapshots);
unitSnapshots.Dispose();
return snapshot;
}
The reason why I am not using Source generation is because it gave me weird errors since I was trying to execute this outside the system's OnUpdate method. But old school worked ๐
Alright here is the strange behavior part. On my in-game UI, you click Save Data button, and it will just forward call to Game.Save(). The data gets saved without error.
But in my inspector, I have a component that has a button Save Game In Editor and it too does Game.Save(), but it gives me this error and I have no way of knowing how to plug this hole! Can someone help me understand why in one place it executes fine, but called from another it doesn't?
Here is the exception: InvalidOperationException: The previously scheduled job GatherComponentDataJob reads from the Unity.Entities.EntityTypeHandle GatherComponentDataJob.safety. You must call JobHandle.Complete() on the job GatherComponentDataJob, before you can deallocate the Unity.Entities.EntityTypeHandle safely.
As you know GatherComponentDataJob is a Unity job and not one I wrote...what's going on? If you need to see other code, let me know I'll paste it.
What you're doing is not safe and the editor button is just pointing this out
It's not safe to use ecs access via public methods like that
A system only updates its dependencies in before on update
Just use em, cache the data and run your save
Or do it if the same system as caller
So it's a matter of timing? Is there a way to "wait" for that moment and send the signal?
Meaning, move the methods and logic to that SystemBase class?
Also both are being executed during runtime.
Yeah pretty much, you can just use an Entity event (what I do) to trigger system or just use entity manager instead to sync data before and do it directly on the ui
Could you elaborate on that Entity event?
And that system that "GenerateSnapshot" has "AlwaysUpdateSystem" attribute
Also 1 note is you're not writing your dependency back either so no other system can wait on it
I simply have a component called Save
And if I want to save game I create an entity with that component
And that triggers my system to run
I had a feeling I was doing something wacky with deps. How do I write it back?
Oh that's a good idea. I think I'll fallback to that approach if this dependency issue doesn't solve it.
Could you help me understand how to write the dep back so other systems can wait on it?
Meaning the system is not in the stack trace initiating the call to that method? Because that method is in the system class.
build working fine after switch to net 2.0 and restart
Arriving at gym back in like 90min
Ok, cool. I'll mess around and hopefully find a solution before then ๐
Just to confirm
Ok, right after I wait for handle.IsCompleted to be true, I do CompleteDependency() and the operation actually works. It still throws that exception, but it actually does what I need it.
When I remove that await handle.IsCompleted and just do CompleteDependency() it works without throwing.
Where are you calling generate snapshot from
So it's not called from the system the method is in
No. Game.Save() has var data = await _system.GenerateSnapshot();
that's where that injection takes place. _system is a SystemBase class.
Class starting afk again
ok
I can upload all the relative code for you somewhere if you want to look at it later and give me some insight.
Alright I just did Game.Save(bool forceMainThread = false). And when editor calls this, it does Game.Save(true); This then bypasses the handle.IsCompleted awaiter and just forces CompleteDependency() and it all works ๐
how do you clear/rebuild entity cache via script?
Ideally you shouldn't have to
You can register asset dependencies in subscenes and any change to these assets will rebuild relative subscenes
And you can version conversion scripts
That said the version approach is a pain tbh
I agree. But my editor script that loads worlds into a sub scene, and when that does, it spawns remains of previous data even though game objects have been destroyed.
So I need to clear cache when I clear scene before loading
Can I just delete the SceneDependencyCache folder and that should force rebuild right?
In the dots menu
There's I button that opens a window
That has a button that clears the cache for you
I can't remember what it's called, on a tram so can't check
If you look at the code of that window though you could see how to trigger it from code yourself
All it does it look for GlobalEntitiesDependency scriptable object, and generate a new GUID for it. Unfortunately that class is internal. Quick question, can I execute internal class methods via Reflections? If not, then it looks like I just need to delete that asset....right?
you can
Oh! Can you give me a quick boiler plate? So this is the magic formula: EntitiesCacheUtility.UpdateEntitySceneGlobalDependency();, but EntitiesCacheUtility accessor is internal and sits in the Unity.Scenes.Editor assembly. How can I trigger this via Reflections?
imo easier to just give yourself internal access using asmref
but if you want to do it via reflection you need to get access to type using something like Type.GetType()
then just call GetMethod using something like GetMethod("UpdateEntitySceneGlobalDependency", BindingFlags.Static | BindingFlags.NonPublic)
Yeah I know how to use reflections. I'm just having a hard time EntitiesCacheUtility.GetType() because EntitiesCacheUtility is not allowed to be used since it's internal lol. Anyways, I just did EditorSceneManager.MarkSceneDirty(scene); and it seemed to do the trick, I'm no longer experiencing those issues. So for now, keep my fingers crossed cause this wasted way too much time.
easiest way imo is just find something else in the assembly then just do a GetType
typeof(SceneImporterData).Assembly.GetType("Unity.Scenes.EntitiesCacheUtility")
SceneImporterData was simply just something you picked at random that exists in Unity.Scenes.Editor assy right?
yep
just the first thing i saw in that assembly that was public
most of it's internal
alternatively you could use a full qualified name with Type.GetType(namespace, type, assembly, version etc)
smart thinking. That's exactly what push I was looking for. Thx!
lol
had this warning pop up randomly, is this something i should try fixing, or is it just a random one off thing? I have not touched any of what it was saying in the warning, as far as i know.
What package version are you using and what version of unity?
the latest 2021 long term release, and ill quickly check the package version brb
HR or Entities?
i dont know what HR is lol, so i was gonna check entities, is that right?
Hybrid Renderer vs the Entities package.
oh ok, should i check both?
i dont think so
Check your entire solution for any of those tags on methods. See if it's the same situation as in that documentation page. If you know for certain it isnt your code, just ignore it.
ok ill check around, cause it only popped up after i was doing some dll import stuff, could that cause it?
ok ye no burst discard anywhere
Hrm. I dont think so. Unless you have burst code in those DLLs. This error is due to C# compiler optimizing and unintentionally disabling burst.
weird, i doubt it would have burst code in the dll, it a c++ dll,
If you aren't using it anywhere. Restart the editor and see if it happens again. It might just be an old burst cache.
ok ill try that and report back, thanks!
ok editor restarted, and yup it is gone, thanks so much!
anyone know much about these artifacts for unity physics?
enabling it definitely seems to show a more stable simulation
Sir, do you happen to know whether it's possible to swap burst compiled function pointer with another?
Or whether it's even presented this way internally?
It's regarding modding
sure why not?
new FunctionPointer<TryFunction>(ptr)
function ptr just takes an int ptr
you can pass in anything you want
as long as signature is correct it'll work fine
yeah, but what I mean is swapping for existing burst compiled code
are those pointers stored somewhere available to user code?
you can pass whatever function pointer you want into a job conditionally
but what I mean is modding from outside
after you built game
you launch it, load your assembly and you want to swap pointers
meanwhile original implementation is vanilla burst in Entities.ForEach loop
there's really nothing special about function pointers as far as i'm aware
waaaait a second
{
get
{
CheckIsCreated();
return Marshal.GetDelegateForFunctionPointer<T>(_ptr);
}
}```
by default (outside of burst) all it does is marshal pointer
let's say there's 3 bursted functions with same signature
can you put them all in one, that will be executed one by one?
ahh what
prefix,postfix
a function pointer maps 1 : 1 to a method
hmmm
just think of it as a delegate
yeah
that's what I mean
() => {
/// code
}
instead of this
have
()=>{
ptr.Invoke();
ptr1.Invoke();
ptr2.Invoke();
}
for bursted function pointers
so that you can swap original one with that one
no because you can't do () => in burst
and pass all parameters between them
that's just example
for the sake of passing my thought process
if you have a job with 3 function ptr fields
you can pass whatever 3 functions you want to those methods
they can be different each frame
no, I mean is modify existing job without any function pointers
so instead of only original code that was compiled AOT
you could run additionally loaded more bursted functions
probably going to have a much easier time just writing a call to a native library
and have that run extra code
i guess the only way i could think of
is if function pointer of function pointers work
i dont know about this though
eh, I just hope Unity will simply make a JIT compilation on demand
for burst and modification of code
you're probably going to have to pay for an engine license if you want that anytime remotely soon
in which case you couldn't share it anyway
modification license*
well, at least something to be able to modify execution of bursted code
allthough
considering ECS
I have a feeling
that simply creating a System with constraints UpdateBefore/After can be enough
literally will work like prefix/postfix
oof
I really need to think of a way to have prefab system
But I can't figure any solution
I need a way to keep prefab reference of existing entity
so that I can easily "clone" entity based of it's initial prefab
not based of it's existing state
In Dots NetCode is it possible to define a Component that will NOT be synced through network? Because everytime i ADD a component on serverside it seems to result in a network update for this entity, even though the component is not actually being synced
public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
{
var builder = new BlobBuilder(Allocator.Temp);
ref var def = ref builder.ConstructRoot<Def>();
def.defType = new FixedString128Bytes(defType);
def.defName = new FixedString128Bytes(defName);
var reference = builder.CreateBlobAssetReference<Def>(Allocator.Persistent);
conversionSystem.BlobAssetStore.AddUniqueBlobAsset(ref reference);
dstManager.AddComponentData(entity, new DefReference { def = reference });
}
Is that the correct way to create blob assets in conversion?
hm, i think as long as a comp is on the ghost prefab it will be created on client side. it won't be synced though. that would require the sync tag afaik
i have GOs in a subscene. those are converted to prefabs automatically and on runtime start i create a hashmap based on comps. would that also work for you?
that's not only about having database
it's also about having link on entity
to that prefab
rn I figured
I could store blob asset reference on every entity
so the instantiated entity needs a reference to its original prefab?
yes
i also had that at one point. you can patch it via ecb
this for A: saving system
B: gameplay interaction
nah, I want to do it one time in conversion
I decided
that I just limit myself from having prespawned entities
and instead do all spawning through code
would also work when the prefab references itself
i had true runtime data so when i was doing it i had to use ecb patching
but actually
it's not Entity reference
it's string reference
I figured I'll use
defType and defName strings
some stable hash or id makes sense when it's for a savesystem too
to define unique combinations for any sort of defnitiion I want
currently I have this weird error
and counter makes me worry a bit ๐
[Serializable]
public struct Def
{
public FixedString128Bytes defType;
public FixedString128Bytes defName;
}
public struct DefReference : IComponentData
{
public BlobAssetReference<Def> def;
}
not sure if I did anything wrong
it's correct. try to remove the serializable
nope
hm, that's odd. i don't get any errors with FixedString in my blob.
I am very confused
I even changed name for type
and it still says same error with old name
yeah, that helped only on second attempt
bruh, now I get this odd error which pauses editor on start
tf is wrong with blobs
hmm
doesn't look like anything from blobs
public struct Definition
{
public FixedString128Bytes defType;
public FixedString128Bytes defName;
}
public struct DefReference
{
public BlobAssetReference<Definition> def;
}
public struct Def : IComponentData
{
public DefReference def;
}
oh god...
do I really need this monstrocity?
no ๐
that's the only way error dissappears
does it work with a second struct?
hehe
lol wtf
ok, I'll try again
with 1 wrapper
nope
errors
[assembly: RegisterGenericComponentType(typeof(BlobAssetReference<Definition>))]
hmmm
what if
nah
double wrapper lezzgo
wait a second
turns out
this error appeared
if you had query debug window opened
huh
damn, it was hidden so well behind other windows ๐
@rotund token sir. I remember that you made custom inspector for some pointer based component. Could you tip me how were you able to do that?
Just implement Inspecter<>
uuugh, no idea what is that
at least
can't locate any useful reference in manual
I am the manual
It's probably Inspector can't remember
Yeah Inspector
Just override the build method
{
public override VisualElement Build()
{
var list = this.Target.Targets;
var label = new Label($"Target Chunks: {(list.IsCreated ? list.Count() : 0)}");
return label;
}
}
ah yes, this is so good
thank you sir
math has this little helper math.all(bool2 x) which will return if both bools are true
any idea if there's something like a math.none?
ie if both bools are false
mm no because, if one is true and one is false, it'll return false
smid friendly little helpers hehe
yeahh
tbf, it's just this:
but cleans things up and as you say any math stuff should be simd friendly afaik
Does anyone know how to fix this problem: my cube disappears when I "close" the scene
I have this
I assume you have hybrid renderer installed?
Yes
What render pipeline?
what do you mean
For the Universal Render Pipeline (URP), use the Universal Render Pipeline template.
I'd say start with that
Thanks
Burrrrrrst. Why is IJobEntity not vectorizing any of the code. PAIN. Dont make me write out the whole IJobEntityBatch by hand
UGGGGHHHHHHHHHH. I'm gonna have to atomize these components if I want actual vectorization arn't I.
PAIN
Now I see why aspects are gonna change the world. Because this is pain
Holy shit unity. VECTORIZE IT PLZ
IJobEntityBatch 4 life
I cant believe i have to resort to this nonsense
What was the entire purpose of 0.50 if I have to sully myself with this manual code writing?
come on burrrrst
Wait no, that's the fallback. Here we go
This is so sad. 0.50 did absolutely nothing to the standard workflow
If I have to manually list the component type handles in order to get some vectorization, this was a complete waste.
At this point, I'm using a slightly fixed up version of 0.17. Unity has failed me.
I feel like I regressed in some way. After seeing the light that is code-generated jobs, this is just so disappointing.
I guess the upside is that now I can see the burst compiled code really easily with the no inlining tag.
you can rewrite that with Reinterpret instead of the float*
Ehh, do you remember the burst loop unrolling tests we did a year or two back? How [NoAlias] tagged pointers resulted in unrolled floor loops slightly more often than similarly tagged ref floats or native array inputs?
i had some good results with burst 1.7.3
In this case, I can use Reinterpret as it did unroll it successfully but I would like to keep my code style standardized.
auto 2 loops for counts that are % 4 > 0
I guess, would make things easier
But it would balloon the size of the method parameter list
afaik it's not even burst but LLVM
don't make a method. i stopped doing that
should be quick enough for you to test out the results
I'm using it for easy burst inspection. I use aggressive inlining tag when I'm happy with the inspector.
Otherwise it's buried in a mountain of chunk code.
yeah makes sense. i wish there was some focus on the codefile to get rid of all the other nonsense
During the early days of 0.50 announcement when Unity felt brave enough to talk on the forums, the Burst team did say that was a proposal they were looking into. Not implementing, just testing out things.
Yea, it unrolled. Hopefully this works for everything.
I dont get why Unity's code gen version doesnt. It's literally the same code.
Literally.
wait, what doesn't unroll?
IJobEntity. The code gen'ed job struct
wdym?
how does it help?
Atomized component structure.
Aspects will group together component structs without actually merging them together into one struct.
You want them in separate structs to pack the native array for burst. But an aspect will simplify querying the components together
So you dont need to type in a quarter million ComponentTypeHandle<> for all the components now separated into their own unique struct/component
Yea, hopefully
that will be nice. haven't thought of that
But seeing how the current code gen isnt able to handle vectorizing a simple multiplication, i'm not holding my breath
i think it will still need some reinterprets though. not sure the compiler gets it
Hrm
This allows for a single loop vectorized multiplication
However, not unrolled.
This will allow for the unrolling of the angular multiplication but not the second. Both loops are vectorized though but not merged into 1 by burst.
This does not vectorize.
interesting. does this one unroll with a tmp stack value of float dampening = dampening[i];?
shouldnt matter, modern compilers will simplify to the code I have now but I'll try
Yea, doesnt matter
What NativeArray<> will not allow is this.
how?
(elementat on a native array is my extension, it only exists on buffer by default)
but a ref float3 should be able to just write back to xy
This also works, I think
oh lol, right i just have it as extension. sorry ๐
i'm curious if it'd be different if you used element at
anyway, that's the method if you need it public static unsafe ref T ElementAt<T>(this NativeArray<T> array, int index) where T : struct { return ref UnsafeUtility.ArrayElementAsRef<T>(array.GetUnsafePtr(), index); }
Using a pointer also removes several commands.
pointers are my jam ๐
Well that just gets the pointer but hides it behind a extension method
If I just use the pointer directly, there's no need for custom extension methods
hmm
why does this show up in the mix
is that just the indexer
doesnt look right
yeah, i think it is
Kinda a mess
I dont think it's the indexer
Seems like if I were to use .xy swizzler, it moves the result of the addition as a single operation instead of packed
Dont know if the cost of an addition insert and blend operation, even packed vectorized, is worth having the move be vectorized as well
Of course, if I assume everything is a float4, that simplifies everything
That however means 4 floats being wasted. Hrm, I might need to make translation a float2
Rolling my own translation simplifies the commands slightly. But that would mean completely re-implementing the transform system.
out of interest why the noinlining
Burst inspection. Moves the code to the top of the inspector
I change it to aggressive inlining when I'm done staring at purple colors.
because without that
mine generates nicer code
burst generated different operations
No difference
interesting
Also fails to vectorize when merging the for loops together. Commented out the [NoInlining]
And copy pasting it into the Execute() method doesnt change the code. Just disperses it across the entire output
Im gonna stick with [NoInlining]. Makes debugging small changes a lot easier to find.
left inline, right noinline
removes the vbroadcastss instruction
huh. hrm
๐คทโโ๏ธ
Can not replicate
is your damping marked readonly?
Can you paste that as text?
private struct TestInline : IJob
{
public float FixedDt;
[ReadOnly]
public NativeArray<float> Damping;
public NativeArray<float> Angular;
public NativeArray<float2> Velocity;
public NativeArray<float3> Translation;
public void Execute()
{
this.Vectorized(this.Damping, this.Angular, this.Velocity, this.Translation);
}
private void Vectorized(NativeArray<float> damping, NativeArray<float> angular, NativeArray<float2> velocity, NativeArray<float3> translation)
{
for (var i = 0; i < angular.Length; i++)
{
angular[i] *= damping[i];
}
for (var i = 0; i < translation.Length; i++)
{
velocity[i] *= damping[i];
translation.ElementAt(i).xy += velocity[i] * this.FixedDt;
}
}
}```
thought i'd just throw it in a performance test for interest
hrm, thats pretty significant
10 mill elements
the only thing i can think of is native array vs ptrs
but i dont see why burst couldnt figure that out
alternatively can you try to use another value for count
oh tertle did the test with elementat. seems fine, right?
I tested both. I expanded the elementat to the full unsafeutil as I dont have the extension
yeah i saw
i got no idea, can't break it changing anything
The broadcast is for FixedDt.
Commenting it out and turning it back to no inlining removes the broadcast
ah
if you pass it into the method does it produce a similar thing
or maybe cache it at start of loop
odd
Hrm, yea. Alright, so make Vectorized static.
Yep, this is for the actual IJobEntityBatch method.
[BurstCompile]
private unsafe struct TestInline : IJob
{
public float FixedDt;
[ReadOnly]
public NativeArray<float> Damping;
public NativeArray<float> Angular;
public NativeArray<float2> Velocity;
public NativeArray<float3> Translation;
public void Execute()
{
Vectorized(Damping.Length, FixedDt, (float*) Damping.GetUnsafeReadOnlyPtr(), (float*) Angular.GetUnsafePtr(),
(float2*) Velocity.GetUnsafePtr(), (float3*) Translation.GetUnsafePtr());
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static void Vectorized([AssumeRange(1, int.MaxValue)] int length, float dt, float* damping, float* angular,
float2* velocity, float3* translation)
{
for (var i = 0; i < length; i++)
{
angular[i] *= damping[i];
}
for (var i = 0; i < length; i++)
{
velocity[i] *= damping[i];
translation[i].xy += velocity[i] * dt;
}
}
}```
Can you performance test this?
The only difference now is inlining. And with [MethodImpl(MethodImplOptions.NoInlining)] -> [MethodImpl(MethodImplOptions.AggressiveInlining)]
let me undo my deletes then sure
actually
take that second one
i think the first was flawed
Hrm, relatively similar?
Wait, no inlining is faster?
by nanoseconds
eh, it falls within 1SD
Is the inline using aggressive?
i think they're exactly the same but the results vary 1ms between tests
yes
how about without the tag at all.
actually id say on average no inline does tend to edge ahead
but maybe its because its running second ๐คทโโ๏ธ
Yea, with a difference in the 10 ns, it might as well be equal.
Thats what, 4 operations?
run it in reverse order
and it swaps around
but yeah results are quite varied
sometimes randomly have a 17 vs 21ms fights
alternating
Im gonna run with yea, no difference.
i dont think we'd expect there to be
Thanks for that. I still need to figure out how to make that performance tester work
static method in a method with nothing else
good distraction anyway
time to back to debugging something that's causing me issues =\
Huh, using floating point deterministic mode does actually change the burst output
They did say it was in very early testing phase. No announcement but if you do every single math operation to floats in burst, it's largely deterministic
on the modern hardware within the same environment we've found it to be completely determinstic (as expected)
any modern intel/amd chip seems to be fine
it fails across platforms though
i.e. consoles
ah, about to say cross platform
with the deterministic tag or without?
without
How about fast float operations, MADD?
havent tested
hrm, interesting. I guess deterministic will be for cross platforms and for 100% guarantee determinism by removing any optimization
we don't rely on determinism we just use it for debugging seeds that people report as having issues
Im very slowly rolling my own 2D deterministic stateless physics engine
so it's nice to be able to generate the same environment if an issue is reported
works across desktop platforms? Linux - Windows?
hrm, good to know
only tested consoles + windows
dont quote me but i believe scarlett might be fine with desktop windows
i haven't tested enough to be certain though
It's unannounced feature anyways. I'll develop with the assumption it'll work someday
Unity has advertised the 3D physics as deterministic so burst will have to be deterministic one day
burst team have mostly worked on usability, bug fixes and performance for last like ~year
which i appreciate
but i feel like it's at a good point now
so we might start seeing new features sometime
The inspector itself has been making leaps and bounds in usability.
yeah the one thing htat would make it amazing
is the ability to hide job boilerplate code in it
basically, an only show user code option
Yea, as I said above, the Burst team has stated on the forums they're looking into it. Compiler magic if they figure it out.
from a purist coding perspective it sounds a bit gross
Until then, I'll stick with no-inlining
like the compiler having knowledge about other libraries that may or may not exist
might just be a tag, something like "folder this method in the inspector"
and have unity tag everything they do to the job under it
but yeah definitely my #2 feature i'd like to see
#1 being my request for an always/force burst compile option for specific jobs
Make the [BurstCompile] tag optional?
there are certain jobs that are just not usable without burst on
Assume everything is burst compiled, make the burst discard the new conditional?
an example which i think may expedite my request for them is the dots hierarchy
accidently start the game without burst and spawn like 1mill entities with that window open
and your editor just locks up for ages
Oh yea, without burst it simply doesnt function with large amount of entities
yeah hence that window should be force burst compiled always regardless if burst compile is enabled!
I have to kill unity in task manager just to close and reopen
Why does the editor pull all entities? Shouldn't it pull just enough to populate the current hierarchy view. Dont know if thats possible though
With burst, anything is possible
well i'm more thinking about ui toolkit
and how it's holding up
imagine if that was drawn with imgui
They were planning on something like a DOTS hook. But last I heard of DOTS integration with UIE was back when it was UIE and not named UIT.
I've gotta check the code for the hierarchy to see how they're passing data to UIT. The current method of per element is very slow.
ugh, burst why
why don't you actually memset this
Burst recognizes it as a mem set. This is easier.
does it? interesting
it's always done some simd instruction to set it for me
instead of using an intrinsic
tbf i haven't tested in ages
well thats nice of it
think i'll still keep using my memset so some other dev doesn't come in and add something to the loop
and just break everything
but good to know
If it's grouped with other operations in the same loop, yea it breaks the mem set
which is why there are 3 for loops and not 2.
sure it wouldn't perform better if the top 2 loops were combined?
Burst will not vectorize the first for loop for some reason. Switches to scalar single operations.
If it's merged with the second.
Isolating it results in proper PS operations and even unrolling. A similar drop in efficiency occurs when I merge the quaternion.RotateZ(angle[i]) in the second for loop. But it's just a single mov operation added to the loop so I determined it, without testing mind you, worth the cost of not having a 4th loop.
no no, removing the quat and merging it has the same issue
it's the float2 of velocity and float3 of translation thats the problem
i have screenshots of the burst output above with and without merged, this was before I added the quat line.
Without the unrolling and vectorization?
alright, so merge it together seems to win. Wow
I really gotta figure out how to run performance tests. That is quite surprising
again though, it's too close to really say
Easier to read if it's merged. And I dont think I need to run a test to know that mem-set is always faster than a vectorized set.
1 sec
might have been a minor flaw in my test let me rerun
burst above was fine but because i have safety off for running these missed something
ok your double loop actually helps
measurably
๐
Alright, thats much more logical.
starts performing worse once you get to 5 loops ๐ (makes sense)
saw no difference with 4
anyway i really need to stop procrastinating
Ha, imagine procrastinating (looks at unfinished thesis)
Can't find anything on a DOTS physics rope. Is there any asset or tutorial to have that?
heavily testing burst and simd = procrastinating. got it, i'll continue blowing leafs and be productive
not heavily testing my own burst and simd = procrastinating
i'm too easily distracted by interesting things others are doing
i can relate. at least it's a learning experience and eventually useful ๐
well, that's not good. i've now a testcase for my job. pretty complicated one to setup. in game it's around 3.8ms, in performance test ~12ms.
@rotund token There has to be a better way than this. Is there?
afraid that's it
put a #region around this abomination. this is what i did so at least i don't have to look at it
noooooooooooooooooooooooooo, God I wish Unity's code gen wasnt so bad.
the only thing more ugly than the above is regions
you take that back!
ok i'll bite. what's so bad about regions? especially around ugly fire and forget code blocks?
i mostly stick to stylecop ruleset to ensure consistency
In many editors, including Visual Studio, the region will appear collapsed by default, hiding the code within the region. It is generally a bad practice to hide code, as this can lead to bad decisions as the code is maintained over time.
i don't necessarily agree with all the rules in the set, but i like having a standard ruleset for consistency that i can enforce with analyzers
(though personally i somewhat agree with regions, i've never felt they improved any codebase I worked with)
is the navmesh api available in dots?
I have a large world that spans multiple scenes so I need to generate a navmesh 100x100 around the player. I dont plan on using ecs but i'd like to use the job system if possible
kind of
they used it in the first demo way way back
so would it be possible to generate a navmesh at runtime in a job?
yes but I imagine its very slow right?
a job would not change anything
but no i find unitys navmesh generation extremely fast
i wrote my own wrapper for recast
and unless i drop down all settings
unitys is about 6x faster
if i drop down all settings is near identical
(it does produce a very similar navmesh)
except their height is better for some reason
What is the class name i would be looking for in the docs to do this?
what size maps were you doing when you found this out?
larger than 100 meters id imagine?
with 8000+ meshes
ok then yeah
alright awesome what api did you use to do this?
unity actually has a tutorial for this (never looked at it)
but it's just all from this package
Do you know if it supports 2d navmesh?
my world is 3d but its a top down on a flat level so I could in theory just make the navmesh 2d
there's no specific option i don't think but if you define your components so only the ground is walkable and everything else blocks
it'll just be a single ground mesh
Alright thank you
So since I am just generating a surface around the player could I just attach a navmesh surface component to the camera or does it actually have to be attached to the geometry I am generating for?
ah yep thats the one thanks
how do I enable this? the NavmeshSurface.BuildNavmesh isn't done async
do i just use this when I want to regenerate?
/// <summary> Rebuilds parts of an existing NavMesh in the regions of the scene where the objects have changed. </summary>
/// <remarks> This operation is executed asynchronously. </remarks>
/// <param name="data"> The NavMesh to update according to the changes in the scene. </param>
/// <returns> A reference to the asynchronous coroutine that builds the NavMesh. </returns>
public AsyncOperation UpdateNavMesh(NavMeshData data)
that is async
{
var sources = CollectSources();
// Use unscaled bounds - this differs in behaviour from e.g. collider components.
// But is similar to reflection probe - and since navmesh data has no scaling support - it is the right choice here.
var surfaceBounds = new Bounds(m_Center, Abs(m_Size));
if (m_CollectObjects == CollectObjects.All || m_CollectObjects == CollectObjects.Children)
surfaceBounds = CalculateWorldBounds(sources);
return NavMeshBuilder.UpdateNavMeshDataAsync(data, GetBuildSettings(), sources, surfaceBounds);
}```
it returns an async handle for you
nav mesh surface just provides a convenient wrapper for you
the underlying actual api if you want to write your own implementation
NavMeshBuilder.BuildNavMeshData
NavMeshBuilder.UpdateNavMeshData
NavMeshBuilder.UpdateNavMeshDataAsync
etc
@rotund token Is this the right setup for a performance test?
seems fine
i usually have my measures in separate methods
but whatever works
this might be nicer if it works
i am far from an expert on this package, there are a lot of tools in it that i am not familiar with that are probably really useful
This is my first time writing unit tests so any knowledge is infinitely more than my knowledge
Wow, performance test shows that PS operations is not always better: Another test shows 0 difference.
Ran it for twice as long. There is 0 difference
Can someone give me a quick example on how to use ArchetypeChunk.GetComponentDataPtrRW()
Seems self explanatory. Gets the pointer to the component data of entities within the chunk. Although there should be a component type for declaration for it.
Yea. It's basically GetNativeArray<>().GetUnsafePtr() you see in IJobEntityBatch.
this seems like rotate0 is not used?
in another job, I copied it there for a screenshot
Imagine if unity code gen worked:
And it's gonna get even longer. That's only a circle.
Imagine, if unity provided an "unsafe" IJobEntity code gen job type. Instead of handholding users with "safe" ref and in parameters that break burst vectorization, they pass the raw pointers and let the user deal with the safety. For example, my Vectorized() method should be the Execute() passed by the code gen. Everything else is boilerplate.
Well, code gen for IJobEntity doesnt work on ISystem anyways.
TRS to Local to World. Slightly more readable with the one shipped with DOTS.
Fully vectorized. The WithoutRotation is actually unrolled by burst.
why are you rewriting all of this ๐
thought i was going to be 2d or something at least
hmm, is there a way to register generic component type through attribute to that generic type, not to assembly?
Fatal error. Internal CLR error. (0x80131506)
bruh
don't mess with generic components
or else you get this
bruuuh
I have no idea what's up, it appeared after I added generic component
but now it won't be gone
even after full library folder removal
I assume RequireSingletonForUpdate ignores Disabled tagged entities?
so were you just awaiting it in a coroutine when you used it?
All my stuff was in jobs at my renderers were render meshes and entities not game objects
But yeah I don't use this anymore as I use my own wrapper to recast as mentioned
Yes
Any reason you prefer it over unity?
Doesn't appear UpdateNavMesh works with volume surfaces
Its just building a one piece mesh the same size/shap of the ground ignoring any buildings x)
I have a lot more options
Also how I wrapped it and exposed it to unity still let me take individual methods from the native library and rewrite them in burst over time
I'm not sure why it would be any different
You need to register what can be in your volume from memory
hmmm
having WAY too many systems is ok?
I talk about like 200-400
or more
With the way I decided to handle my Input
I'd need quite a lot of ISystems
to handle events
we have about that many or more at work
main thread cost definitely adds up
strongly recommend making as many ISystem
imagine if they're only 0.1ms each
thats 40ms
or 25fps
you say that now
but your project will get slower as you add more entities, systems and archetypes
actually they are not even running, kek
usually 0.03ms is about as fast as SystemBase will run at for the most basic work
so, what do you actually mean by that?
[BurstCompatible]
public static bool ToggleState<T>(this EntityManager em, in Entity stateEntity)
where T : unmanaged, IComponentData
{
if (em.RemoveComponent<T>(stateEntity))
{
return false;
}
em.AddComponent<T>(stateEntity);
return true;
}
On average my reactive input handlers will just run smt hlike this in OnUpdate
and only once trigger fired
meaning like once per 10 seconds or smth
so the most of my concern - checks whether that system should run
[UpdateInGroup(typeof(LateSimulationSystemGroup))]
[BurstCompile]
public struct PlaySimulationHandler : ISystem
{
private Entity _playSimulationState;
public void OnCreate(ref SystemState state)
{
state.RequireSingletonForUpdate<GalaxyLoaded>();
state.RequireSingletonForUpdate<Performed<TogglePlay>>();
_playSimulationState = state.EntityManager.GetOrCreateSingletonEntity<Singleton<PlaySimulation>>();
}
public void OnDestroy(ref SystemState state) { }
[BurstCompile]
public void OnUpdate(ref SystemState state)
{
state.EntityManager.ToggleState<PlaySimulation>(_playSimulationState);
}
}
here one example of such system
(this is for starting/pausing game)
yeah, so that kind of work will eat 0.03ms?
simply checking if theres any entity in the query
hmm
the Complete() that happens at the start of every system
I'd need to figure a way to group them
actually nevermind on this
that doesn't happen anymore unless the system actually runs
but yeah if you're doing this in ISystem
it won't be that bad
are such checks bursted?
i believe its in a function ptr
but its actually cached as well
theres been a lot of work on this
they are certainly trying to build entities to support this number
via ISystem
if it was me who did it I'd make a one bursted check that generates array of bools, so later it just does simple bool comparison
really hope they have some improvements to ComponentSystemGroup in 1.0
whether system should update I mean
so, you mentioned that ISystem does query check faster
hmm
is it actually check one by one?
it should be the same
all it does to check a query is
public bool IsEmptyIgnoreFilter => _QueryData->GetMatchingChunkCache().Length == 0;
can I literally see in profiler that timeline
{
if(!MatchingChunkCache.IsCacheValid)
ChunkIterationUtility.RebuildChunkListCache((EntityQueryData*)UnsafeUtility.AddressOf(ref this));
return MatchingChunkCache;
}```
when it checks whether system should run?
if you have a valid cache all it's really doing is a bool check and an int check
it's pretty fast
yes structural changes will invalid caches
hmmm
(another reason static archetypes are important for performance)
this is all part of my main thread fast system group
in which all I do are structural changes
hmmm
that's no good I guess
meanwhile implementing ECB will probably be not as good
hmmmm
i believe it has to be a structural change that affects this chunk
but i assume you aren't doing these changes every frame?
nnnah
only when you make game state changes
I also made a some kind of pattern
where I use one entity per
toggle state
as in EnabledTag is switched on and off
on one entity
while it also has some other tag, that says that this Entity is this EnabledTag holder one
singletons basically
Trade off of memory for perfomance I guess
kek
I am using ecs 0.51 with unity 2020.3 2021.3.5f1
and it shows same 6 messages but I don't understand why
how can I fix for these messages?
You're using a class not a struct
Thanks, oh god.........
hmmm, I wonder how I can implement dynamic building for required Query with multiple constraints
basically I have that same EntitySelectionSystem
and now it requires SelectionRequested singleton
if it exists, selection is performed and result is written to other component
but here's the thing
maybe instead of SelectionRequested I can implement a way to dynamically require any sort of components for selection to be performed
goal is that it can be done without changing types (since modders don't have access to adding interfaces to types)
Is there any ways to have the entity manager itself hold custom data? I want to be able to reference a value that all components can read from. Thanks.
For instance, a global integer.
EntityManager is partial
you can reference assembly and add new fields to it
but I'm not sure
whether it's safe
Then rather than an entity manager, how would you go about it?
I just avoid it as pattern
on the very low end
I use World for such modifications
it's managed anyways
You can just keep the data as a singleton entity. Or is there a reason why you don't want to do that?
If the value doesn't change you can use a blob asset, or as Dot suggested above a singleton entity with data holder component
I've been trying to learn on how to utilize singletons. Regardless, I'm developing a voxel game where I want, essentially, a global **changing **variable that represents the player's most recent voxel chunk position. Then, the system can automatically regenerate the entities around the player.
Then a singleton entity is probably your best bet. It allows you to stay burst compatible
And how would I go about access said entity when performing a 'foreach entity' call?
There's a convenience method GetSingleton which you can use to get the entity before for each
I'll look into it, thank you for the help.
if you singleton entity is meant to be never changing (as in, it exists as long as world exists)
you can use this poggie woggie approach
[NotBurstCompatible]
public static Entity GetOrCreateSingletonEntity<T>(this EntityManager em)
{
using var query = em.CreateEntityQuery(ComponentType.ReadOnly<T>());
return query.IsEmptyIgnoreFilter ? em.CreateEntity(typeof(T)) : query.GetSingletonEntity();
}
so you just keep Entity reference
in any system you want to access some data
and anytime you need it
you just do
EntityManager.GetComponentData<PlayerInput>(_inputEntity)
in case if you need it in jobs
you can access it through ComponentDataFromEntity
but sadly for best efficiency you'd need to use IJobEntityBatch
but if you really just want static value
burst supports SharedStatic<T>
what do you mean with this bit?
getting that value outside of job is sync point
( i've never used or looked at those jobs )
getting that value in any job but batch
equals getting that value for every entity
meanwhile in batch you access it once for chunk
ah right
so with for each, probably the best approach is just get/cache the value to a local variable first, and then pass that into the foreach right
well
in case where you need it in loop
you are simply doing smth wrong
kek
that's kind of against the pattern imo
not sure why you'd say that, it's often necessary to get data from elsewhere and use it inside foreach
say for example deltaTime, or some global value
you get it in OnUpdate, store it to a local value, then use it inside foreach
well, for time they literally built that into World
unmanaged one
hmmm
do you guys know any way to implement this:
I have a special singleton entity, which is loaded from subscene/async
because of conversion
I need to convert it
can't make it manually
and so as result I can't get reference to that entity at OnCreate
meanwhile that entity is basically static, once loaded never unloaded
Is there any solution to this?
goal is to avoid Getting singleton in loops
sometimes if i can't get something, due to ordering with creation of systems and mono's and conversion etc, i just put a hack inside OnUpdate like:
if (systemFieldEntity == Entity.Null) systemFieldEntity = //get entity code//
so often just fighting with how and when things are created etc, easier to just do that, and then maybe later fine tune it
just my 2c ๐
yeah, that's what I avoid...
OnUpdate is bursted
getting singletons is not possible here
yeah
and I can't use unburstable methods inside bursted method
even if it's behind if check
how then would you get a singleton inside OnUpdate?
i miss those, in early days we could access global variables which was way faster than copying large arrays
you are not copying large arrays tho
i'm not using the ECS part of dots, still using mono so i'm copying back and forth arrays to jobs
ah
that's not really what we talked about though
accessing data from jobs is equally troublesome
no matter if you use ECS or not
kek
You bring up a good point. If Im reimplementing the transform system, I might as well roll my own 2D transform components as well. Trim down the number of not used properties.
Im pretty sure you can now. Just cache the query containing the singleton at OnCreate().
Also, OnCreate() will get bursted when Unity finally makes entity query creation burst compatible.
huh
Singletons were a pain point in 0.17. One of the improvements in 0.50 was burst compatible get singleton. Might be the only one in fact...
Is there an Entity journal yet?
?
where you can see where certain entity was instantiated?
Never used the journal before. So no clue.
@rotund token btw, I checked that approach of using DestroyEntity in order to clean it up from all components but system states
Here results:
every frame I destroy same entity
for 0.02ms perfomance
kind of curious whether I can optimize with query check
but I can't think of a way to check whether entity has any components but this
creating query with way too many component types also didn't really work
Can I create BlobAssetReferences (that point to BlobArray wrappers) from within a Parallel job?
No. The only memory you can allocate from within a job, parallel or not, is with Temp allocation. BAR with Temp will be deleted the next frame.
You might be able to create and allocate Blob builders outside a job, send it into a job to populate, move it out and then finish it off with create references outside the job.
I see. Thanks for that.
My inspector is getting really really long. Anyone have any tips on either a custom inspector or something to compress it?
split logic? xD
I've just started to dabble with DOTS and I've noticed a convert to entity bool on the item inspector, is this meant to replace the ConvertToEntity script? if so, does anyone know where the API is to access it?
it's literally adding mono script automatically, kek
pretty sure it's just Editor script that adds component to editor scene game object
I am 99% sure that button is on the list to be killed by DOTS 1.0. Replaced entirely by subscene conversion.
That button is a carry over from... 0.12? 0.9? Ancient.
ok, ill avoid now and just do a layer and add the script in a foreach or something
No no, you should use subscenes. Trust me, once you get it nailed down, it's pretty smooth.
Word
Oh yeah, that automatically converts everything inside it to entities anyway right?
what's more
it fully serializes data
before you press run
Yea. And helps with conversion with a bunch of side features.
making loading way faster
sweet, im planning a hybrid approach first, gonna convert all the static geometry to entities for a start
do normal raycasts work on entities?
It's just a surprisingly advanced DOTS feature. Not really something that a beginner to the land of ECS or Unity's flavor of it can easily pick up.
ah, special API for it?
separate physics package
Completely different physics engine.
Join me in coding your own physics engine. Free from capitalism unity interference.
so i wont be able to detect ground or shoot walls or anything using standard raycasts? or even have access to API that enables me to? 0-0
DOTS is still considered alpha, kek
unless i install physics that is
Well, yes. If you completely convert your physics scripts to DOTS format.
bruh
why so much hate?
even tertle's own fully bursted renderer had similiar perfomance as HR
DOTS without HR = fast. DOTS with HR = slower than mono.
that's not true at all
i suppose i could use the seperated collider objects, since they are seperate from the ECS'd renderer, i can still detect the colliders using standard raycasts, I just wouldnt be able to do anything fancy like have specific sounds for specific surfaces.....
Trust me. For something as big and integral as physics, you do not want to roll hybrid.
pretty much anything Hybrid = pain, imo
this is assuming im not using DOTS physics
I tried with something as "simple" as 2D tilemaps. It's really clunky and slow.
So bad, I'm implementing my own 2D physics. DOTS integrated.
I decided to do pure ECS, so far I feel like it's the best decision
learning is though
but
I work on very simple game visually
so that might not apply to others, kek
Yea, crossing over is just ugh. The one part I think is actually fairly decent is stock rendering as compute buffers and compute shaders have NativeArray hooks and can easily be attached.