#archived-dots
1 messages ยท Page 15 of 1
where to save it, where to read, where to manipulate
i'm re-implementing my incremental game from scratch with the new spellcasting system and the stat system is the nicest thing to work with
the one thing i'm contemplating is making my stats no longer ints
but it would double my manipulators size
from short/half to just float
i really liked it as ints, but gravity is making me consider my choice
since well -9.81 standard right
now originally the idea was just representing this as -981
but then i started thinking about crit chance, +0.2% doesn't seem uncommon
and realizing maybe i'm just going to pigeonhole myself here
how long until you want a generic stat system? ๐
do you mean different types?
yeah
i don't think ever
hm, can you store function pointer on components?
yes
(im pretty sure though i have not done it myself)
i believe netcode utilizes this a lot
they use this little thing
{
public struct PortableFunctionPointer<T> where T : Delegate
{
public PortableFunctionPointer(T executeDelegate)
{
Ptr = BurstCompiler.CompileFunctionPointer(executeDelegate);
}
internal readonly FunctionPointer<T> Ptr;
}
}```
they store a lot of them
why do they need it stored like that?
it's just wrapping all the compile code
PostSerialize = new PortableFunctionPointer<GhostComponentSerializer.PostSerializeDelegate>(PostSerialize),
so all they have to do is pass a method in
what restricts them from just calling the method?
ah ๐ ok
they all have their own serialize code, cleanup code etc
that's their source gen'd stuff, right?
for the most part yes
ok makes sense then. quite cool tbh, never needed such a thing but good to be aware of
writing an older project from scratch once you've done hard stuff for months is like going back to a level 1 zone as level 80
this is why i never get anything done
find a new way i like doing things
ok, 2 years of libraries need to be rewritten
hehe. I've already written this game 2 times. i never liked it. then feature creep and ugh, still wasn't better. some games just fail at the design stage really. but you still need to make it to realize.
2 times... More
if i would be strict i've written it 3 times lol. maybe the fourth will lead to something
1 oop, 2 ecs
the first time was in 2015 2016 ... god damn
funny side story, this guy in another gaming discord was adamant on the point that the game uses 1024 bits to represent 1.8 e308 because 2^1024 = 1.797 e308. what i find funny about the 08/15 gaming guy is that even when told, they can't back down ๐ and he's a programmer, so he knows best anyway.
hm, i already have a handle in place for this but what if i didn't. i have a target system which writes to TargetInfo. i have another system that needs the targetInfo, so a clear dependency. can this be designed in a way that i wouldn't require the jobHandle from the target system. would a writegroup help me somehow?
isn't this just by default handled by the dependency system?
or is this like a native container
it does? huh. i still have some huge holes in understanding the dependency system what it can and can't do.
no, entities and icomps
the system that reads from it is going to get the dependency from the system writing
ok cool, yeah. no errors. seems to work fine ๐ great then thanks
just to confirm this, the dependency is defined by the query and not the job parameters, right?
it's defined by everything in the system
any GetEntityQuery, GetComponentDataFromEntity, GetComponentTypeHandle etc
this is what i mentioned the other day missing from your custom fromentity
AddReaderWriter(isReadOnly ? ComponentType.ReadOnly<T>() : ComponentType.ReadWrite<T>());
this line is what adds the dependency to the system hence it's really important!
thanks for clarifying
the function pointers are not codegened right? You can assign at runtime like normal, right?
Right..?
yes
do i need to free such calls UnsafeParallelList<T>* unsafeParallelList = allocator.Allocate(default(UnsafeParallelList<T>), 1); I've compared it with UnsafeList and there no free is done on UnsafeList<T>* listData = allocator.Allocate(default(UnsafeList<T>), 1);
which confuses me tbh ๐
yes, you need to free it
UnsafeList is what a NativeList uses internally iirc
use this to free memory: UnsafeUtility.Free(void*, Allocator)
yeah, i know the rest. turned out i've missed another call which isn't called dispose /// <summary> /// Destroys the list. /// </summary> /// <param name="listData">The list to destroy.</param> public static void Destroy(UnsafeList<T>* listData) { CheckNull(listData); var allocator = listData->Allocator; listData->Dispose(); AllocatorManager.Free(allocator, listData); } which frees the listData
confusion solved ๐ thanks
so working with unsafeList. just disposing is not enough. it has to go through the Destroy method which is kind of unintuitive
i don't use it, but if i would, i'd have memory leaks for sure ๐
i'm confused
you only need to call Dispose on unsafelist
the Create method that does
UnsafeList<T>* listData = allocator.Allocate(default(UnsafeList<T>), 1);
is Internal
and only used by NativeList
because it allocates a pointer to the unsafelist
oh right! ...
just new UnsafeList<T> doesn't need to be freed itself
ok, then all clear. ๐ had to add the destroy pattern to my native containers because those were leaking :/ at least i catched it soon enough
the downside of the safety system. it doesn't save your ass when you are the one writing containers lol
That's why you got to add the safety system first
i've added it. it just doesn't catch such leaks.
it's just a dumb handle. it doesn't know about the internal allocs a container makes
that's what dispose sentinel is for
but yes if you don't write it properly
it doesn't help!
I thought the disposal sentinel is part of the "safety system"
yeah, i've been calling it safety system. dispose sentinel is what i meant
yeah i removed my comment didnt want to confuse
i personally consider them different things
you can add atomic safety handles etc to a container
for safety
without adding dispose sentinel
i have a bunch of containers that don't have leak safety but do have thread safety/etc
yeah for R/W access vs allocation managment
makes sense, I can see why you separate the two
kind of excited how the new system will be with the dispose sentinel gone. will a leak be detected then even when just going through allocator.Allocate?
/maybe/
hope it does, would be cool and a benefit of just using malloc
technically leaks are detected if you just use malloc atm
it just gives you no info about it
I personally just avoid using unity's built in stuff. Much easier to manage memory on your own (with the exception of their methods, I use a few sometimes)
well that's unhelpful with no info lol
and you can turn on -debugallocator
oh, i start unity with that?
i will try to make sure i have every leak covered now
does it report anything then with that flag?
Point Im making is it's easier to manage memory without overhead from safety system. I would honestly use the dispose sentinel over the atomic system to ensure disposal is being reported correctly
the problem enzi has is the dispose sentinel doesn't actually track the memory
it tracks that you've told unity that the memory has been released
it doesn't actually verify it itself
yeah, i could just free the dispose sentinel and do nothing else. it will leak but no one complains about it
so, tried with the flag. nothing is reported. either a good sign or it doesn't report as you said
Does PhysicsVelocity.GetLinearVelocity() slowly rotate/slide for anyone else?
having a hard time diagnosing the issue
Hello (and noob warning..)
making a mobile game and trying to push the limits of graphics; the scenes/levels are supposed to be very ambient / environmental / immersive, very scenic
basically - trees. thousands of trees and grass and vegetation as much as possibly possible within mobile (even some medium-low end devices)'s framerate capacity
they don't move around, just for pleasing the eyes
all i need them to do is: 1) collide when player tries walking through a tree 2) sway a bit in the wind
can DOTS help with the graphical rendering aspect of this? can DOTS increase performance and allow many more instances to be on scene even in mobile, if it's done with DOTS?
ok maybe i want trees to cast shadows too... and to have nice textures & shading.... and maybe i want to detect if a raycast collides with certain vegetation (bushes meant for hiding/stealth)
Yeah, but don't overestimate what mobile can do
i'm trying not to overestimate, but i am asking / pushing to discover what is the technological limit possible... whatever the limit may end up being
Some things you mentioned can't even be done on some low end desktops xD
i'm kinda hoping to theorize based on Far Cry 1 if you remember that game from 2004;
the graphics didnt really age well, by now it looks very similar to those late 90s racing/arcade/FPS games which were trying to be realistic but end up having that, well, late 90s kind of game aesthetic. However - they had low graphics settings which were able to work even on some lower end desktops
so i theorize / wonder.... can 2004 PC graphics happen on 2022 generation of high/medium/low end mobile devices?...
but yeah maybe i'm dreaming and delusional ๐
i don't think you'd have any issues running a 2004 game on a high end phone
i see. but only high end then i guess?
phone range vastly
but think about this
there are emulators on android that play ps2, gamecube/wii games
heh true
want this on mobile
can DOTS help render some thousands of vegetation/trees on mobile... ๐ค
this is already a thing for mobile even without dots kek
please do share
just gotta look around play market
Elder Srolls Blades
ark
it's not really dots that makes all of this possible
it's individual optimizations
like effective culling
also unloading unused parts of world
and etc
Is good practice(performance-wise) to save entity(that contains prefab) as a system class instance field or to use GetSingleton when ever we need it(saw this on yt dots related vid)?
if your prefab is persistent
why not
saving entities as fields is a normal practice
simply because some things are just unburstable regarding getting them
and other cause sync points
though - can DOTS help at all? let's say maybe the other techniques you mention (world loading/unloading, culling etc) account for 60-70% of performance advantages, might DOTS get another 10 or 15%? or does DOTS not really solve anything for dense environment props/decoration like trees & vegetation at all
dots makes everything faster
it's great if you aim for scalable simulations
some people here process millions of entities in a matter of 2 ms
what DOTS markets on the tin is "have thousands upon thousands even millions of objects in your game fast", is dense vegetation / grass / trees not a very pertinent use case for that?
interesting
it is meant to be perfomant by default, compared to classic Unity where it's simple by default
i see
so if i'm ready to bite the "not simple by default" bullet, then it's pretty much an easy - why not use DOTS, for any project, dense forests or otherwise
it's not released yet
it's more like in Alpha state rn
even though some parts of it are fully released
hmm
public NativeParallelHashMap<FixedString128Bytes, UnsafeList<Entity>> TypeCache { get; private set; }
I have such field
var typeCache = TypeCache;
Before job I do this
then in job I get UnsafeList value, if it's not created I create it and add it to map
and fill list
but later
when I access this list
I end up with this
even though I made sure
list got filled
Remember unsafelist is a struct
You have to write back to the hashmap and changes you make
huh?
I thought it's a pointer to memory
or wait
if I resize it
pointer gets invalidated?
{
var list = new UnsafeList<int>(Allocator.Persistent);
Test1(list);
var length = list.Length; // 0
}
public Test1(UnsafeList<int> list)
{
list.Add(1);
}
the length is not a pointer
only the buffer is
it must be passed by ref
sure, if you write your own lookup extension
Just another point to make for the above to why DOTS is good in my opinion its not just about performance
it helps me to write cleaner code and helps me to figure out problems a lot easier
OOP makes my brain hurt I have to figure out what is an object and is it an object of another or where is the object, some abstract concepts don't fit well into objects
with DOTS its all just data and how can you transform it in the most efficient way possible, simple
the fact that all data is public and accessible to anything is good
no need to get references
yeah that too data access is like a fundamental property, of it, OOP you've gotta figure out your own way to do it and there all more likely less efficient than in DOTS
well, not really
in OOP getting direct references is somewhat more efficient
but the fact that you have to create a whole system to get those references sometimes
is uuugh
Managed references are slower than unmanaged pointerz
really I was always struggling with getting object referencs in real time in monobehaviours
you always had to precache refs and had to know exactly what you needed before you needed to it to do it efficiently
i got into a discussion about this. What are your arguments here?
it's not about pointer vs reference
it's about
object.field vs ECS query
Ah nvm then
you don't have to make if object.field vs query ... the same could be done for OOP. really, the way you get references is highly variable. most of the references i need are pointers on the icomp that is being processed
well, you usually either do World.GetSystem... or query for specific entity
and most of the time you store entity reference
not direct pointer
One is managed, the other is not. Instead of the managed reference being moved/deallocated by GC, pointers are fixed to a specific address of memory. References point to an object that is fixed, which point to the actual memory iirc (kinda like pointer redirection)
well, as i said, i have direct pointers. going through world is very OOP like. querying has a lot of overhead, the question then is, can at least the required entity be cached because a CDFE access is also very OOP like again and still really fast
I don't understand why you would use pointers in Unity to be honest
Performance
you can do stuff you can't otherwise ๐
I guess but they are also dangerous
lol, not really
Type conversion, serialization, etc
wait, so if you have singleton entity and doesn't ever change archetype
does it mean you can store direct pointer to component?
no changes in archetype, yes
huh
interesting
didn't know that
any code share how you do it btw? maybe some extension?
i use this in quite a lot of places and only set pointers again when there are structural changes in the chunk
Not at all, unless you're careless with the bounds of the memory you're accessing
Alloc bytes > write to same bytes > share bytes > dealloc bytes > profit
I guess it's possible to make some kind of ComponentReference
well yeah that's what I'd be concerned about I might forget to release and it and the address gets assigned to something else I don't know how likely that is though
public unsafe struct LinkStatEntityBuffers : IJobEntityBatch
{
...
public void Execute(ArchetypeChunk chunk, int batchIndex)
{
bool orderChanged = chunk.DidOrderChange(version);
if (!orderChanged)
return;
var references = chunk.GetNativeArray(SpellEffect_StatEntityBufferReference_WriteHandle);
var statEntityReferences = chunk.GetNativeArray(StatEntityReference_ReadHandle).Reinterpret<Entity>();
for (int i = 0; i < chunk.Count; i++)
{
var reference = references[i];
var statEntity = statEntityReferences[i];
// todo, reduce the lookups, this could be merged into 1 lookup
var tmpBuffer = StatBuffer_Changes_Lookup[statEntity];
var tmpBuffer2 = StatBuffer_MainEffectReferences_Lookup[statEntity];
var tmpBuffer3 = StatBuffer_ChangesValues_Lookup[statEntity];
references[i] = new SpellEffect_StatEntityBufferReference()
{
chunk = StorageInfo[statEntity].Chunk,
bufferHeader_StatChanges = tmpBuffer.GetBufferHeader(),
bufferHeader_StatChangesValues = tmpBuffer3.GetBufferHeader(),
bufferHeader_References = tmpBuffer2.GetBufferHeader(),
};
}
}
}``` nothing special to it. here i set the BufferHeader* so I don't have to go through additional lookups.
Once a pointer is allocated it doesnt get overwritten. You can however, read or write bytes that other pointers "own"
that's not the issue with Unity ECS chunks
they are not subjects of GC
so
they don't get moved
meanwhile data in chunks can
ok that's good
Dont chunks only move during structural changes?
I actually meant, how you create such pointer reference
yes
benefits of pointers. i was able to make a generic stat system with configurable data types for all stats. all is stored in a big byte array that is directly accessed via code gen'd index. it's as fast as my old system, just more flexible. that wouldn't have been possible without byte pointers that can be reinterpreted to all kind of data types
you can make magic happen with pointers. they are quite fascinating ๐
My favorite part about pointers. Your memory can be whatever, but it will still evaluate to something regardless of the value type.
quite a few ways, UnsafeUtility.AddressOf. CDFE pointer return. writing &variable
You can also use IntPtr. I don't really use them tho, so idk what you can do with them
native containers also have getptr methods.
i have only used IntPtr to print the memory hex address ๐
debugged blob data with it to study and confirm the layout
I want to make some extension
that will get pointer reference to component
through EntityManager
meaning I could get it globally
especially useful with singletons
Hello, Why the job system uses only the main thread? https://pastebin.com/kZ9cATh8
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
JobHandle jobHandle = reallyToughParallelJobTransforms.Schedule(transformAccessArray);
jobHandle.Complete();
because you do this
if you do Complete()
main thread has to wait until job is done
and since it's single thread job
it's faster to do it on mainthread, rather than pushing to other
then what should the code look like to use all cores? ,what to use instead of Complete()?
if you want this exact job to use all threads
you need it to be parallel
and then ScheduleParallel
instead of IJobParallelForTransform?
instead of Schedule
thanks , i will try
what @rustic rain said. don't complete any jobs that are scheduled. if you really need it to be completed just use run instead.
no
he wants parallel job to be done right now
the only way - schedule parallel and then complete
Run() makes it single threaded
yeah, just a future reference if you ever run into this and don't care about parallel
in this case go with scheduleParallel
solved it, because I don't use entities, I can't use ScheduleParallel() and Run() but in my case, the problem was that the objects to be moved were in another object (nested because of object pooling).
No ScheduleParallel?
huh
looks like this job extension
doesn't support parallel
no such extension even with entities
ah
well
one thing you should probably consider
while this job doesn't support paralleling itself
it supports parallel with other jobs
so if you have multiple jobs
just schedule them all
and then complete them all at once
all of them will run in parallel
thank you, I will most likely use it in the near future, but at the moment I'm happy that it works for me as it is (I've been dealing with this problem for 2 days already)
it is parallel. its in its name. its always parallel and you cant Schedule it on a single thread.
its the same with IJobParallelFor. IJPF can also only be scheduled. IJPF is the old API exactly for that reason. the new way to Schedule a IJPF is to use IJobFor.ScheduleParallel() instead of IJobParallelFor.Schedule()
but judging by this guy's profiler
it was single threaded
i see two jobs in parallel?
that happend cause he called complete right away
following this thought โ๏ธ if i'm already working with DOTS, should I aim to use it for everything in the game?
usually i'd think to use it only for objects that seem "DOTS-appropriate" such as millions of NPC vehicles in megacity, or millions of asteroids, or thousands of units in an RTS etc. and the rest of game stuff would be regular GameObjects
phrased a bit differently - when DOTS matures, will it take over as the main "engine" in unity, completely replacing the current game-object hierarchy one? (once it can fill in for all the needed features of course)
DOTS is tech stack
jobs, burst, ECS
key parts
jobs and burst are production ready and can be used anywhere
ECS is not
meanwhile ECS is also the biggest change
because it's totally different way of coding game
if you want to know more - just read manual
its a bit annoying to interop between gameobjects and Entities. For example you have two different Physics engines for each which dont interact by default. in the future i expect it to be much easier to stay in pure ecs to avoid those friction points.
but unity also said they aim to do magic ECS optimizations to gameobject code without your knowledge
ah cool
wait so - for example if i want to make tens of thousands of trees/bushes using DOTS, but i need the player gameobject to collide withe trees and enemy FOV cones to be occluded by bushes etc. - these interactions between gameobjects and DOTS entities will not be possible? Or possible, just difficult / needing some extra hoops
extra hoops yep
ECS physics don't work together with Game Object physics
you should really pick one physics system(dots or physx) and base things from there, imo any interop between two would be a lot of pain
hm
and those extra hoops are as convoluted as just making the player an entity too lol
maybe for that reason alone i'd want to implement almost all game content in DOTS instead of gameobjects then....
atm that causes a lot less headache than hybrid
writing back from entity code to gameobject code only in one direction is easy though
so you can still use some monobehaviours like the animator or sth
thats the trap I feel into. there's still no official equivalent to mecanim if you need elaborate animation setups though so expect to require some somewhat convoluted workarounds there
but that ofc requires a gameobject as a representation for the entity
what about using assets tho? like the Starter Assets FPS controller, or Low Poly Shooter Pack etc. are those a no-go for putting them to use in DOTS-land?
they are a no go anyways lol
heh
anything that is monobehaviour derrived will need to be rewritten, if you need those things you should probably just stick without ecs
hm..
so committing to ECS is committing to writing your own everything, not being able to make use of any non-ECS-based assets
yep
good to know
you can still copy the code over to the ecs side though without much changes
@tropic venture if I were you I'd wait for 1.0 which should bring further clarity to the problem you are describing, and at least at that point there should be far more documentation and tutorials supporting it
ah, so there is a "known path forward" to move things from gameobject land to ECS land, i guess it's just tedious, needs manual work on every code file to look through and rework for ECS
is there an ETA on that?
and if you are prototyping youd probably have way better iterationtimes with gameobjects atm anyways
supposedly preview should be any time now and release end of year or early next
yes you can more or less just split every monobehaviour into systems and Data. afterwards you care about making it burstable. then parallelizable
your prototype most likely wont need the full ecs performance anyways
well;
...but my project is trying to be kind of a benchmark for mobile, like a "Crysis" for mobile ๐ i am aiming to push tech limits to the edge of what's possible, so i'm wondering if i'm wasting time prototyping in gameobject-land if it wont get me where i can get with ECS...
in my case i'm not really aiming for graphic realism too much, but more like graphic density, loads upon loads of scene content
detail
well, idk about graphics
but loading a lot of data is perfect with dots
subscenes allow for very fast load/unloads of parts of world
even on mobile?
any supported platforms
ecs wont speed up rendering, you could achieve similar results using DrawMeshInstancedIndirect
right, i'm eying that too
ahem
culling system
bursted one
altho i'm also hoping to support medium-lower end devices not supporting OpenGLES 3.1... where available - use instancing, where not - will need to reduce object count maybe and see what's the max i can achieve with all other optimization methods
why not just use Vulkan?
Does anyone know why this fails?
var attack = commandBuffer.Instantiate(attackSource.attackPrefab);
commandBuffer.SetComponent(attack, translation);
var attackComp = new AttackInstanceComp
{
damage = 1,
};
commandBuffer.AddComponent<AttackInstanceComp>(attack);
// Fine until here
commandBuffer.SetComponent(attack, attackComp); // A native collection has not been disposed
so i'm worried maybe i'll prototype in gameobjects and code everything around that, maybe come up with some smart culling system in gameobject-based scripts, maybe billboarding etc. and i'll be able to achieve <some number> like i dunno, 15000 vegetation in scene even on meduim-low devices. But then needing a full rewrite for ECS - now i could achieve 25000, significant difference, prototyping in gameobjects was a waste of time...
but maybe i'm wrong about this
doesnt unity choose that automatically or something?
why not just commandBuffer.AddComponent(attack, attackComp);
you select it in player options
That fails as well
Same thing
whats the exact error message?
A Native Collection has not been disposed, resulting in a memory leak. Enable Full StackTraces to get more details.
But I'm not entirely certain it's related
is it literally just a drop down select and done? or needs related changes in graphics / coding / shaders / other stuff
well enable full traces and find out ๐
it's that simple unless you use API specific code afaik
or maybe platform specific
cool then, why would anyone not use it... should be enabled by default or something
A Native Collection has not been disposed, resulting in a memory leak. Allocated from:
Unity.Entities.EntityCommandBuffer:.ctor(Allocator) (at Library\PackageCache\com.unity.entities@0.51.0-preview.32\Unity.Entities\EntityCommandBuffer.cs:1330)
๐
whats the full code for where you are using that commandbuffer? sounds like you arent disposing it
@tropic venture For Android and Linux, you should use Vulkan. However, be aware that the Vulkan drivers on many older Android devices are in a bad shape and will never be upgraded. This limits the platform coverage Hybrid Renderer can currently offer on Android devices. from the hybrid renderer docs
Looks like it
you make it sound like it's a magic Make My Game Super Fast Automagically button ๐ is it?
doubt
Disposing of it removes the exception, but it's still not spawning the entity
If I remove the SetComponent line, all's fine
is this something i can programmatically account for? or it requires a user setting/option "switch off vulkan renderer if things look horrible on your device"
@tropic venture my knowledge of mobile is basically what the docs say, so not sure
is it even possible to make choices about unity's renderer at runtime on mobile?..
I don't think so
i'd have to release a separate APK "try this version if the game looks weird on your device" or something like that
any other thoughts โ๏ธ re. prototyping vs. waiting for 1.0 to release?
i mean you should just do some simple prototypes regardless, maybe you will hate the workflow
hating the workflow can't possibly be a thing ๐ either you want to make a game, or you dont.... no?
some people fight conversion tooth and nail ๐
whadyou mean conversion, gameobjects to ECS?
yep
so is there any value in prototyping now? or is there a strong case to only prototype using ECS, or maybe even wait a while for 1.0 to release
by prototyping I mean start by opening the samples and make some very simple edits to familiarize yourself with the workflow, see if it is right for you. that alone should tell you if you want to attempt things further. something that is very simple where an player controlled entity moves, via the inputsystem and can play a sound from an audiosource will give you a feel for a variety of situations and how ecs works in context of other unity systems
i see
fmod is burst compatible kek
for sounds
@rustic rain personally im using myrri but split off from the latios framework
how are you setting up the command buffer?
did you call AddJobHandleForProducer on the ecbs?
i'm pretty sure he doesn't use ECBs
at least it sounds that way because otherwise you don't need to dispose
so it's probably not played back
true
It is
var commandBuffer = new EntityCommandBuffer(Allocator.TempJob); thats not how you create a commandbuffer
It is, according to the docs -.-
And it works just fine as long as I don't assign the other entity
var ecb = ecbs.CreateCommandBuffer().AsParallelWriter();
no, it's fine but i think you need a temp allocator. at least that's what i'm using
That's for multithreaded jobs
not necessarily. it's when you use a entityCommandBufferSystem which does automatic playback
Well, I play it back manually. Not the issue.
is this new? i wasnt aware i can just new() a commandbuffer
been there for quite a while
it's for manual playback. mostly not needed but it has its use cases
@gray tusk does the prefab already have a NewComponentType on it? im not really sure why its failing on the two lines you commented out, code looks fine there
Nope
var attackComp = new AttackInstanceComp
{
damage = 1,
distancePercentage = 0,
Source = entity,
Target = _headQuarters // It works if I comment out this line
};
A bit less abstract. _headQuarters is obtained succesfully in OnStartRunning, and I can access it's component data.
@gray tusk im out of ideas but could you try to replace otherEntity = query.GetSingletonEntity();
with otherEntity = GetSingletonEntity<OtherComponent>()
based on your forum post
yeah not sure what the outcome of a success or fail is but in oncreate you can use RequireSingletonForUpdate<T> and then use GetSingletonEntity<T> in onupdate. if you use OnStartRunning and your entity is destroyed it, your system may not know about it as it happened some time after the system started running
or use if(!HasSingletonEntity<T>()) return; if you dont want to require the singleton for update
https://blog.unity.com/technology/pick-up-these-helpful-tips-on-advanced-profiling this feels relevant to discussion earlier with gfx backends on mobile btw ๐
(0,0): Burst error BC1091: External and internal calls are not allowed inside static constructors: Interop.BCrypt.BCryptGenRandom(System.IntPtr hAlgorithm, byte* pbBuffer, int cbBuffer, int dwFlags)
Anyone else getting this error?
in it's stack it literally mentions every single job in my project
I cleared entities cache and also fully removed Library folder
error still persist
I've seen this before
Did you solve it?
nope
Had this discussion with a burst dev before let me find the convo
basically GetHashCode on anything will cause that BCrypt static constructor to need to be run in Burst, which uses managed data
My cause was I used HashCode.Combine
In GetHashCode
Which wasn't supported
And this type was used as a key in a native hash map
Was a pain to track down
Had to disable my libraries 1 as a time
Then my systems
Until I tracked it down to a hashmap.add line
Thankfully as my systems are all decoupled this didn't take too long
But yeah tldr, you're likely using something managed in a static constructor
Hey everyone! Quick question: how do I handle components with BlobStrings? Can I use Allocator.Persistent on them? Do I have to track them and dispose manually?
Blobs should live in blob asset store
You shouldn't have to manage this yourself they're tied to the subscene
Thank you!
If you are creating them outside of your though or managing your own blob asset store then you will have to dispose
I'm trying to figure out how to use this little asset:
https://gitlab.com/tertle/com.bovinelabs.event
I'm doing a level manager with levels stored in Addressables and referenced through strings. I want to make an event system that triggers the level change when I send the event with the specific level name and I'm wondering if it would be ok if I attach BlobString to the event component?
I don't anyone here would have any idea why when using an analog stick I seem to get a sort a lag where the same inputs persist over several frames
I think that is the issue its hard to debug to be honest, the inputs just don't feel as snappy as they should when moving an object directly with an analog stick, it seems fine with keyboard though
I'll post the code its really basic, but I feel like its a system or a value in a variable is not getting reset or something
dead zone too high? acceleration too low?
wireless? it has some input lag but shouldn't be that noticable
float2 currentmovpos = new float2();
currentmovpos = playInput.DirectionInput * CursorMoveSpeed * Time.DeltaTime;
if (math.length(playInput.DirectionInput) > 0.2)
{
float3 tempcurr = new float3(currentmovpos.x, 0, currentmovpos.y);
CursorSquare.Value += tempcurr;
CursorSquareQuery.SetSingleton<Translation>(CursorSquare);
}```
0.2 seems quite high. you tested it with a lower value?
yeah I tested it with 0.01 I don't think that is the issue
its weird its like it occasionally goes diagonally or any direction way longer than it should sometimes
old or new input system
new input system
well, i think the only way you can debug this is to print out frameCount and the received value from the input. from that it should be clear how it will react
and the only possible settings are here
that's exactly what I need thanks Enzi ๐
np, hope you find the issue ๐
it's somewhat mad to do it like this but also a very nice way to test my asset. the game where i'm using my asset now works very different in a lot of places. at first i thought, oh boy, this won't work out well but it turns out. DOD lends itself really nice to open custom paths. some ifs, some constants, some partials and code can be modified like crazy. quite happy how this is working out and not what i would have expected.
hmm i guess i missunderstood reinterpret :S
var packedEnablerCounts = cellEnablerCounts.AsNativeArray().Reinterpret<int4>(sizeof(int));
bool allValid = math.all(packedEnablerCounts[compatiblePattern] > new int4(0, 0, 0, 0));
if (cellEnablerCounts[compatiblePattern].Value > 0 &&
cellEnablerCounts[compatiblePattern + 1].Value > 0 &&
cellEnablerCounts[compatiblePattern + 2].Value > 0 &&
cellEnablerCounts[compatiblePattern + 3].Value > 0)
{
if (!allValid)
{
Debug.LogError("allvalid is wrong");
}
}```
this always throws the error.
i thought the evaluation with math.all does exactly the same as checking each entry individually. what am i doing wrong here?
hmm
your index is wrong
you're using the same index for the reinterpreted and original arrays
if compatiblePattern == 1
then for
packedEnablerCounts[compatiblePattern]
you're looking at elements
4,5,6,7
for cellEnablerCounts[compatiblePattern]
you're looking at elements
1,2,3,4
length of packedEnablerCounts is /4 of the size of cellEnablerCounts
ah damn. ofc. okay then everything works as expected. thats bad news cause that means my bug is somewhere else
Reinterpret<int4>(sizeof(int)) i don't get it. why int4 and then int?
never noticed before there's a parameter for Reinterpret ๐
in case the base type is int. okay. is it actually needed or does it help in any way?
its needed. getting runtime error if i leave it out
System.InvalidOperationException: Types {0} and {1} are different sizes - direct reinterpretation is not possible. If this is what you intended, use Reinterpret(<type size>)
ah i see. private static void CheckReinterpretSize<U>() where U : struct { if (UnsafeUtility.SizeOf<T>() != UnsafeUtility.SizeOf<U>()) throw new InvalidOperationException(string.Format("Types {0} and {1} are different sizes - direct reinterpretation is not possible. If this is what you intended, use Reinterpret(<type size>)", (object) typeof (T), (object) typeof (U))); } never ran into it because my types always have the same size
^ you figured it out but yeah it's for different size reinterprets
that's what I'm trying to check
public unsafe struct ComponentReference<T> where T : struct, IComponentData
{
internal IntPtr ptr;
internal uint orderVersion;
public T Read
{
get
{
UnsafeUtility.CopyPtrToStructure((void*)ptr, out T output);
return output;
}
}
Kek
if you have a chunk with XYZ components and you do a query A AddComponent, it will change the chunk to be XYZA
I don't want to enforce EntityManager reference
but I want to keep checks for order version
internal ArchetypeChunk(Chunk* chunk, EntityComponentStore* entityComponentStore)
{
m_Chunk = chunk;
m_EntityComponentStore = entityComponentStore;
m_BatchEntityCount = kUseChunkCount;
m_BatchStartEntityIndex = 0;
}
I see
why bother with ptrs
well, I kind of want to store it on entities at some point
{
internal UnsafeParallelHashSet<ArchetypeChunk> Targets;
}```
i do that
well not on individual entities
i store it as a chunk component
How can I create an entity from a GameObject that will be used as a reference to a child entity? The conversion workflow docs only mentioned prefabs, nothing about getting an existing GameObject.
Example:
public void Convert (Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem) {
DynamicBuffer<WheelBase> buffer = dstManager.AddBuffer<WheelBase>(entity);
buffer.ResizeUninitialized(wheels.Length);
for (int i = 0; i < wheels.Length; i++) {
//WheelBase wheel = new WheelBase(conversionSystem.???);
//buffer.Add(wheel);
}
}
GetExistingEntity(object)
wow that... is a badly named method
should be something like InterpretObjectAsEntity or something
regardless, thanks
hmm
How to get global system version?
Is that kind of data that can only be obtained from EntityManager?
to SetChangeVersion
var indexInTypeArray = ChunkDataUtility.GetIndexInTypeArray(chunk->Archetype, typeIndex);
chunk->SetChangeVersion(indexInTypeArray, );
public unsafe struct ComponentReference<T> where T : struct, IComponentData
{
internal IntPtr ptr;
internal uint orderVersion;
internal Chunk* chunk;
internal int typeIndex;
public T Read
{
get
{
if (chunk->GetOrderVersion() != orderVersion)
{
Debug.LogError("Order changed, component is invalid");
}
UnsafeUtility.CopyPtrToStructure((void*)ptr, out T output);
return output;
}
set
{
var indexInTypeArray = ChunkDataUtility.GetIndexInTypeArray(chunk->Archetype, typeIndex);
chunk->SetChangeVersion(indexInTypeArray, );
}
}
Just figuring out stuff hehe
where T : unmanaged, IComponentData
{
SetChangeFilterCheckWriteAndThrow(handle);
var typeIndexInArchetype = ChunkDataUtility.GetIndexInTypeArray(chunk.m_Chunk->Archetype, handle.m_TypeIndex);
if (typeIndexInArchetype == -1)
{
return;
}
// This should (=S) be thread safe int writes are atomic in c#
chunk.m_Chunk->SetChangeVersion(typeIndexInArchetype, handle.GlobalSystemVersion);
}```
ComponentTypeHandle, ComponentFromEntity etc
have this stored
Im not seeing any method called GetExistingEntity from the GameObjectConversionSystem or even the EntityManager
but it's fine
sorry, GetPrimaryEntity
kek that is what I was using, but I was getting nullref so I thought I was using the wrong one
every system update adds +1 to the globalsystemversion
guess I missed something else where
you have to get it before you return from a system
you can't get it in a job, it's too late
(at issue)
well I know
but I assume
getting this value
doesn't cause any sync points
so it's fine
my whole idea here is just
@rustic rain what is it you're tying to do anyways
to have a way to set data
to static entities
also read
without EntityManager
or sync points
allthough writing seems very unsafe
it only causes a sync point if it needs to
but still requires EntityManager
so?
no EM in jobs
It's good normally
but when you have a lot of entities with only 1 component
that never change
and you know you only read them and sooooometimes write to them
CDFE feels like a huge overkill
this is even faster, kek
yeah, and that is not meant to happen
why?
that's why I put order version check
ok so now you're checking
because this is meant for static entities
i don't think it's faster anymore
similiar to Time entity
no, I'm actually reducing total amount of code
because now I don't need to get cdfe
store field for it
but that's over 50% ! 
CDFE's are a bit cumbersome to use
and when entities adds their chunk garbage collection in 1.0
and things start moving
and you have to rewrite it all again
yes๐
That's going to be interesting... do you think it preform a structural change every time it runs
i can not confirm this exists
but it was mentioned a while ago on forums
(but so were a lot of features we want that probably aren't coming =D)
hmm... interesting ntl
Im sure a lot of well-needed additions are tucked away from the userbase that will only be disclosed on 1.0 release day
There is nothing you can do about it right now, but fragmentation & tiny / mega chunk support is definately something we will look at in the coming months.
2018 ๐
i have heard defragmentation a few times
I mean, ECS as of right now is still pretty good at the core. A few things could change yes, but it is functional and doesn't seem to have any blindly obvious major issues as of right now
there is one
some people noticed here
that if you create millions entities
whole system slows down
I would like to see more control over how the memory is managed by ECS
noticable
not really sure what you expect ^_^'
I mean, that is to be "expected" with million of entities
create millions of gameobjects and see how well you go
no, I mean
other systems
that don't process those entities
they slow down too
yes
it still has to look through every chunk
to fill a query
systems don't magically know what chunks it uses
while there is some caching now
memory lookup times gets slower as more entities/chunks are added
It's likely why they will add a GC for ECS so they can pack similar entities/chunks together for improved memory lookup times
fragmentation has been a long term concern
used to cause huge issues on our console release
yeah
that's why you switched to static archetypes?
oof that is pretty bad pref drop just because of fragmentation
oh we don't have static archetypes at work
but we did significantly reduce it
i just like the concept of static archetypes
makes everything easier
network serialization, saving
and things just work faster
i don't need to worry about component checking if something has been removed
static as in it's assigned to a static field or what?
as in i don't do any add/remove components
unchangable archetype
ah yeah
i also just like the challenge and i think it can make some beautiful crazy scaling code
i do not think most devs should focus on this
it makes a lot of things more complicated
entity per function of a complex system, instead of a component
Idk, I would have to figure out some other use cases
i should say i don't have completely static archetypes
and i do occasionally use tag components for long state changes
but i require the archetype of an entity to be rebuildable from the saved original archetype
i.e.
component with value = 1
would addtag3
therefore i load an entity with value = 1
it would automatically readd the tag
no need to add a tag then, right?
tag removes it from a system
or adds it to a system
as mentioned above, long state changes
minimum seconds, ideally minutes+
only timers i have atm are actually static
if I do GetEntityQuery in several systems, will they all share same query?
for (int i = 0; i < wheels.Length; i++) {
if (wheels[i] == null) continue;
Entity e = conversionSystem.TryGetPrimaryEntity(wheels[i]);
if (e == Entity.Null) continue;
WheelBase wheel = new WheelBase(e);
buffer.Add(wheel);
}```
I keep getting the error: An Entity index is larger than the capacity of the EntityManager. This means the entity was created by a different world or the entity.Index got corrupted or incorrectly assigned and it may not be used on this EntityManager.
Do I have to register it with the EntityManager somehow?
I don't quite get what you are doing
why are you making a Entity.Null comparison
instead of just using return value
of TryGet
idk I figured it may have been part of the issue
it doesn't even work, just covering all bounds atm
What is buffer?
when it's outside of subscene
you create it directly in target world
so entities don't get remapped
So it won't work in subscenes then since the world is different?
protected override void OnUpdate()
{
Entities.ForEach((DefConverter converter) =>
{
var converterEntity = CreateAdditionalEntity(converter);
DstEntityManager.AddComponentData(converterEntity, new DefType { value = converter.defType });
var buf = DstEntityManager.AddBuffer<RegisterDefReference>(converterEntity);
foreach (var converterPrefab in converter.prefabs)
{
var def = converterPrefab.GetComponent<DefAuthoring>();
Convert(buf, def);
}
});
}
private void Convert(DynamicBuffer<RegisterDefReference> buf, DefAuthoring def)
{
var e = GetPrimaryEntity(def);
buf.Add(new RegisterDefReference { value = e });
}
here's what I do
quite same thing
add buffer, get primary entity, add
wait a second
you resize
uninitialized
thus why value might be corrupt
try not resizing
I only did that because the sourcegen did it
lmao ok yeah that was the issue
It didn't like the invalid buffer elements ig
Do you guys have any better ideas?
I have this unique system that makes async read of current cursor mouseover
and in order to trigger it from different implementations
I made this
public interface ISelectionRequest
{
public ComponentType[] Desc();
}
so any system that wants to read selection result from that system
just implements this
and then I create update requirment for that selection system from that interface
why not use events and pass in cursor data any time there's a selection?
burst
my current async implementation allows for burst
in initialization system group new input system and ui elements create components of input
right after simulation ECB, I run selection system
which writes result to singleton component
and then all other systems can read it in bursted code
ok but your ISelectionRequest contains a managed array
it's only read on OnCreate
public static EntityQueryDesc[] GetAllRequests()
{
var list = new List<EntityQueryDesc>();
foreach (var request in TypeUtility.InstantiateAllOfType<ISelectionRequest>())
{
list.Add(new EntityQueryDesc() { All = request.Desc() });
}
return list.ToArray();
}
RequireForUpdate(GetEntityQuery(SelectionUtils.GetAllRequests()));
like this
And then in managed system, I make a selection, and set component data to selection entity
@rustic rain you recently mentioned a component to disable render..
RenderDisable or something?
DisableRendering
Aha! Thanks
was just looking for a quick shortcut to on/off some elements
state.RequiredEntityQueries
hmm, if I get this list
maybe that's the way
I want to try and make HashSet out of all queries in all systems that request selection
and then add them to SelectionSystem
for update requirments
any idea if RenderBounds or WorldRenderBounds are axis aligned to local orientation or of they are both AABB to the world axis?
just trying to figure out a way to get a mesh's approximate bounds
I use WorldRenderBounds to get bounds
I use it to dynamically scale this selection overlay
tbh, you could just select entity in inspector to manually see what they represent kek
hehe yeah the objects are currently placed in default prefab orientation so world orientated
i'll just rotate them and check, thought i may as well ask first ๐
so yeah i think RenderBounds represents the locally aligned bounding box, whereas WorldRenderBounds is the world axis aligned AABB
I have a weird System issue I think, it seems like a method call from PlayerInputActions.IPlayerControlsActions is only being called every few frames
the System is update every frame but this method for example is not
public void OnDirectionalControls(InputAction.CallbackContext context)
{
inputdirection = context.ReadValue<Vector2>();
//Debug.Log("The actual input is " + inputdirection);
}```
maybe that's normal behaviour although I'm sure it is receiving input every frame so I feel like perhaps that could be the cause of my problem
hmmm
Is there a way to get list of all managed components of type?
ok, it is possible
but it's super slow ๐ค
seems like doing thispublic partial class HandleCombatEventsSystem { private partial void CustomHandleCombatEventsUpdate() { breaks codegen with error CS0579: Duplicate 'global::System.Runtime.CompilerServices.CompilerGenerated' attribute
well there's more to it than the code i posted but calling a partial update method from the main update doesn't seem possible
yes
hmm
so anyone figured ways to make animations?
not skinned mesh ones
just general, for translations/rotations and etc?
I have an idea for how I might implement animations if I get around to it ๐ค
I'm not sure if it will work that well but I will try a stop motion type animation system
where I swap mesh's out in sequences
I already have a script that can extract single mesh's from animations in Unity
tbh, I figured my game doesn't need animations xD
but not certain
currently I have 2 things in game that potentially require animations:
space ship making jump to other system
space ship landing on planet
first thing is quite solvable without animations
but second...
yeah depending on the game you could get away with minimal animations
spaceship landing should be pretty easy without too
Can't figure what would be a better option
1 constraint - while landing ship must be vulnerable for combat
tweens could work well for that
yeah, hardcoded animation
Ok, I've definitely found an issue with the way I was receiving inputs
i'm baking clips into a blob asset ie the pos/rot values
then i have a system which increments the current frame on each animated thing, and applies the pos/rot
i think you could do this with code..
I don't know if its a bug or what but it seems using this way public partial class PlayerInputStuffSystem : SystemBase, PlayerInputActions.IPlayerControlsActions { to collect actions from the input system is not a good way
and now it means I'm going to have to write a new system to process inputs 
but at least I solved it
input can be solved with ISystem
actually
really? I havent used ISystems yet I kind of want to wait until they are fully implemented
well, the implementation is simple. you use ISystem to reset entity that stores all input tags xD
var inputActionTypes = TypeUtility.GetAllAssignableFrom(typeof(IEventAction)).ToList();
foreach (var assetActionMap in controls.asset.actionMaps)
{
foreach (var inputAction in assetActionMap.actions)
{
var name = inputAction.name.ToLower();
foreach (var type in inputActionTypes)
{
if (!type.Name.ToLower().Equals(name)) continue;
if (allStarted.TryGetValue(name, out var started))
{
inputAction.started += _ => em.AddComponent(inputEventEntity, started);
}
if (allPerformed.TryGetValue(name, out var performed))
{
inputAction.performed += _ => em.AddComponent(inputEventEntity, performed);
}
if (allCanceled.TryGetValue(name, out var canceled))
{
inputAction.canceled += _ => em.AddComponent(inputEventEntity, canceled);
}
if (allPressed.TryGetValue(name, out var pressed))
{
inputAction.started += _ => em.AddComponent(pressedEventEntity, pressed);
inputAction.canceled += _ => em.RemoveComponent(pressedEventEntity, pressed);
}
inputActionTypes.Remove(type);
break;
}
}
}
I do it this way: store all interfaced components
get their generics
with
Started<Event>
Performed<Event>
Canceled<Event>
that seems a bit complicated 
sometimes I add
Pressed<Event>
yeah, but then it's so liberating
cause now you have global input values
as components
and you can create trigger systems
that react on certain queries
and all of that is burstable
I mean I was just setting values in a componentdata and that worked fine for me
bools for buttons and float2s for mouse/gamepad etc
public void OnCreate(ref SystemState state)
{
var em = state.EntityManager;
_cameraEntity = em.GetOrCreateSingletonEntity<SpaceCameraTag>();
state.RequireSingletonForUpdate<Pressed<FocusCameraOnPlayer>>();
_playerQuery = state.GetSingletonEntityQueryInternal(typeof(PlayerTag));
}
[BurstCompile]
public void OnStartRunning(ref SystemState state) { _player = _playerQuery.GetSingletonEntity(); }
[BurstCompile]
public void OnUpdate(ref SystemState state)
{
var em = state.EntityManager;
var pos = em.GetComponentData<LocalToWorld>(_player).Position;
var sysID = em.GetComponentData<StarNormal>(_player).systemID;
em.SetCameraPosition(_cameraEntity, pos);
So then whole system that makes pressing button follow player looks like this
that's interesting ๐ค
it's probably less fast then simply checking component
but it feels good to use xD
also it supports modding really well
cause modders can add their own input components and any way they can be triggered
yeah exactly, and either way I bet its faster than a monobehaviour
I might actually make it a library
DOTS just gives way more flexibility
hmmmm
what if I instead make those chunk components
I wodner if queries will still work
the reason - I want to limit amount of chunks for input entity to 1
I have no idea, I haven't messed with chunks much yet, haven't seen any need to
if they can be used the same way
by other systems
I might actually make it way faster
allthough
it's probably
0.01ms vs 0.008ms xD
welp
turns out it's very simple
and looks like this is what I'm looking for
interesting
Burst compiled function pointers are slower than normal method calls if it is not a complex and expensive process. I messed around with them in the past, doing something simple, and performance was always 10x slower for such a small workload. Things may have changed tho, so you can only truly know if you benchmark it.
yeah, should probably benchmark it
huh, looks like Burst already supports struct in function pointers
what do you guys think would be the best place to post about that problem I have above, the DOTS forum or the Input Forum it feels like its an issue with both
supports struct if passed by pointer
also, i find your input solution fascinating
i can't tell if i love it or hate it
yeah ๐
I have a feeling input forum is way more dead than dots
from a purely data/reactive design it's quite nice
what is your issue calabi?
i feel like the type of issue would determine where it's posted
this is actually how the Unity physics guys made their character controller
I get a sort of lag issue where inputs are sustained if you check the gif I posted above using a certain method to get inputs
like if use the methods directly in the classes from public partial class PlayerInputStuffSystem : SystemBase, PlayerInputActions.IPlayerControlsActions { that
then it doesn't update every frame
I presume its using fixed update, but I can't figure out how to change that, and I have changed the input settings in the project setting to dynamic update
that's how they do it here
i think we need a bit more code than your interface
to see what's going on
they handle it similar to me, store the value in the system
then write to a singleton in update
i don't use the interfaces though, i prefer not hard coding my link to input
and pass in inputaction instead via configs
but effectively the same thing
yeah that is close to how I'm using it
I'll change my code to that example anyway, I can't remember where I got the example for using it the way I did
[AlwaysUpdateSystem]
[UpdateInGroup(typeof(InitializationSystemGroup))]
are you doing always update?
yep
the update method is called every frame its just a method like the below is not called every frame
public void OnCursorPosition(InputAction.CallbackContext context)
{
inputMove = context.ReadValue<Vector2>();```
I'm not sure if its a bug or just my implementation
hm, yesterday i wrote that this is not working so i have reduced it down and this version is indeed working. ๐
one method to either support mods or support modules for asset development
still interested if there's a better way of doing this
most of the code is not important. what this does is calling another implementation of an update method
where i still struggle a bit is how to set this up with asmdefs. main reason, the implementation of a partial method has to be in the same asmdef. so an empty implementation has to be provided or code file that is meant to be modified. but moving this file out of the asmdef directories ends in the implementation not being there and compile errors. then i tried setting up a custom asmdef but then you have circular references.
found out that calling GetSingleton leads to these weird codegen errors
their codegen is too dumb ๐ Unity.Entities.EntityQuery __query_0; protected override void OnCreateForCompiler() { base.OnCreateForCompiler(); __query_0 = GetEntityQuery(new Unity.Entities.EntityQueryDesc{All = new Unity.Entities.ComponentType[]{ComponentType.ReadOnly<NZSpellCasting.MonsterLineQueue>()}, Any = new Unity.Entities.ComponentType[]{}, None = new Unity.Entities.ComponentType[]{}, Options = Unity.Entities.EntityQueryOptions.Default}); } just creates a __query_index without checking if that's already been created
Hey everyone! I need an advice. I'm making a level manager for a modular game system. Level loading logic should work like this:
Level Load Called | For Each Module Call PreUnload Function | Unload Level | Load New Level | For Each Module Call PostLoad Function | Anounce Level Loaded
I've prototyped this using Coroutines and it's pretty simple there. Each PreUnload and PostLoad function is just another coroutine and they are ran one after another.
But with DOTS it is not as simple. Logic tells me that PreUnload and PostLoad functions should be systems and should position their updates using UpdateBefore and UpdateAfter attributes. But the problem is every step of the process should start only when the last one is finished. So, for instance if you have 5 modules, Unload Level step should start ONLY when all 5 PreUnload functions have finished their execution. How would you approach this?
this doesn't need to be 6 different systems. make 1 system and 6 different jobs. chain their dependency. done ๐
you are still able to make 6 systems. the jobhandle has to be shared though. it works but isn't as elegant
Yeah, sounds reasonable. So, I should just inherit jobs from IPreUnload and IPostLoad, then get them through reflection and stack them one after another in a single system, right?
why would you need the abstraction of the interface and reflection? just write an Entities.ForEach or job struct
unless you have different PreUnload jobs
Well, each module will have its own logic for those things, so the code for each module's PreUnload will be different.
That's why I thought about multiple systems.
hm, i see. then your initial approach sounds reasonable. here's what you can do. you can define systems what they require to run. one of those is RequireSingletonForUpdate<T>. the "For Each Module Call PreUnload Function" systems can require a LevelLoadCalled comp (it's just a single entity with this comp) which triggers the PreUnload stage systems. after you are done, destroy all singleton entities you created. this way you can chain the systems. also set the order with UpdateBefore/After as you mentioned. either this way or with shared jobHandles.
I'll try this. Thank you!
you're welcome
so all that partial class, partial job stuff
worked fine in 0.17
we had to rewrite a bunch of partial systems in 0.50+
was a painn
I reported these errors in my mega thread way back when 0.50 came out
oh, wasn't on my radar when you posted this ๐ did you have more problems? i'm just having trouble with GetSingleton
i'm using it to provide easy modification of base behaviour. could also help with modding support
you can't split jobs across files
huh, i'm doing that. splitting how? anything special? i've a lot of methods all over several files
Only if it's library
Modders won't be able to have asm ref
are they code genned though?
yeah which is fine
true dat, personally i just need it for my asset
modding support is such a pandoras box ๐ setup has to be much much more mindful
I figured best solution for mods I think
I create interfaces, base classes for many many things
Boot with different hooks for all stages
Ui
Even input
So my code can obtain it all through reflection
What isn't satisfying for modders can be improved with harmony
Meanwhile unmanaged game logic pretty much does not need much support in this regard
Cause it's all data anyway
And if someone wants to modify it he just does it
Also a key is that I base my own logic on these tools
great, my spell loader isn't loading with subscene closed (not unloaded) all entities are there. the fk ...
oh the loading order changes. that's annoying. one would expect that the loading systems are running in the same frame and before my systems. seems to not be the case
FloatMode = FloatMode.Deterministic I found this new float mode that is a placeholder. Will this be cross-platform determinism, or something else?
that's the plan but it's been on ice for a loooong time
and at that point, questionable if it will ever see true cross platform
i don't know the details but it strikes me still as weird that there float isn't deterministic on all platforms ๐
i mean, you'd think engineers would be thinking about this when the first network cable was plugged in. but apparently, everyone does its own thing despite norms
that's the cpus fault
and float specifications
that's what i wonder. why are they so different.
There's no standardized method of float math
That's why
which REALLY sucks
you have to either have a compiler do the work converting all floats to be deterministic, or use integer math (it's likely they both do that, just the compiler does it for you) which is slower
from our testing, all modern desktop cpus (not including apple m1 etc) produced deterministic results
but as soon as last gen consoles (ps4 etc) enter mix
results vary
i.e. intel/amd meeting x64 specification are fine which is not surprising
that said our testing was just just for debug tools, we don't require determinism so don't have thorough testing for this
How do you guys handle helper functions for components? Say I have a component that represents currency and this currency is represented by an int, but can be expressed as Gold/Silver/Bronze (think World of Warcraft).
Typically I'd just slap a function on the component that converts the int to the gold representation but components should only contain data, so this approach isn't recommended.
I find that I end up with so many random helper classes for my components that it's starting to get confusing, how do you typically organize your files/components/helpers?
I just use extension methods and nest the file in the same directory and namespace as the component.
For pre-existing components, like PhysicsMass I put them in a special folder, but put them under the same namespace as the component.
I would just have a property in the component itself to set/get the int with gold/silver/bronze. Recommendations by unity in certain contexts are not rules ๐
If it makes sense to do it, then it's fine, imo. Your example is literally just a reinterpretation of data fully contained in the component. Seems pretty harmless to me.
Break free from the shackles of vague recommendations!
my question is, outside of representing this to the user visually, does it ever need to exist outside of its pure int form?
i don't think there's much harm in throwing a few properties on a component to present the data in different ways
Unity even has properties for some components
Is there any way to transfer unity terrain over to ECS?
For this example it's probably practical to just use the integer, but it was just an example. But yeah, I suppose having a few properties here and there would be fine.
unitys recommendation is concerning logic. just data transformation is fine
Do lights not work? I cant seem to get entities to project any kind of light
Lights also dont work in subscenes
is there a setting I need to enable/disable?
Lights (and cameras and many other things) are still game objects. Only certain things is converted to entities
well I changed it to follow that Unity GatherInputSystem sample, tertle posted and I get pretty much the same laggy result in fact it feels like the cursor goes more haywire
hmm
when I use query in EntityManager.AddComponent
it modifies chunks instead of moving entities?
hmm
so here's what I'm trying to achieve
I have a singleton entity which gets tons of tags added
which results in dozens of chunks created for no reason
what I want instead: change it's chunk
switch it's archetype
while adding component to chunk batched seems doable with query
Removing components is not
Removing dozens of components from query seems just impractical and very costly
seems to me like you want to fix bad design. is it that important that the singleton is used for queries. i mean it's 1 entity. put some flags in a comp
it's dynamically created
but you must have a finite amount of tags, right?
can you create an archetype for it?
?
creating an archetype with all the tags would at least prevent the dozens of archetypes that are created via addComp
otherwise i don't see much you can do, it's just how entities work under the hood
hm, another dependecy issue. how is this not working? ```var updateIntervalsHandle = new UpdateSpellEffect_Intervals
{
...
}.ScheduleParallel(mainEffectsQuery_Intervals, Dependency);
var updateDurationHandle = new UpdateSpellEffect_Duration
{
SpellEffect_DurationEndTick_ReadHandle = GetComponentTypeHandle<SpellEffect_DurationEndTick>(true)
...
}.ScheduleParallel(mainEffectsQuery_Duration, Dependency);
var removalHandle = new RemoveSpellEffects
{
...
}.ScheduleParallel(mainEffectsQuery_Removals, updateDurationHandle);
var removalHandle2 = new RemoveSpellEffects_WithStats()
{
...
}.ScheduleParallel(mainEffectsQuery_RemovalsWithStats, updateDurationHandle);
Dependency = JobHandle.CombineDependencies(removalHandle, removalHandle2, updateIntervalsHandle);leads toThe system NZSpellCasting.CombatEffectSystemServer reads NZSpellCasting.SpellEffect_DurationEndTick via UpdateSpellEffect_Duration but that type was not assigned to the Dependency property. To ensure correct behavior of other systems, the job or a dependency must be assigned to the Dependency property before returning from the OnUpdate method.```
Could you have mods effectively produce an entity per modification and then gather them into a single archetype at runtime?
are you using your unsafe CDFE?
nope
straight GetComponentTypeHandle and GetBufferTypeHandle
my unsafeCDFE has AddReaderWriter calls btw when used in SystemBase or ISystem
Is there another exception after this
that's the only one thrown
chaining looks okay, right? maybe the problem is elsewhere
odd thing is that everything works fine. just the error gets thrown every frame while an effect is running ๐
