#archived-dots
1 messages ยท Page 3 of 1
ok, that's a plan b
the GetSingleton value methods are even marked as burst compatible
it works fine...
let's hope so
I still would love that callback
to have bursted cleanup ISystem
kek
unmanaged world is tough
I guess what I could implement instead
is some special Class/Interface which will instantiated through reflection
and which will contain code that manually grabs system casted to required type
public interface IPostCreateCallback
{
public void PostCreate(ref World world);
}
``` smth like this
public interface IPostCreateCallback<T> where T : unmanaged, ISystem
{
public void PostCreate(ref T state);
}
Or actually like this
something I used to do was simply create my world, setup entities then create my systems.
alternatively an easier way to handle this is just add an extension
EntityManager.GetOrCreateSingleton
{
using var query = em.CreateEntityQuery(ComponentType.ReadOnly<T>());
return query.IsEmptyIgnoreFilter ? em.CreateEntity(typeof(T)) : query.GetSingletonEntity();
}```
which is something i used to do in the past for OnCreate issues like you're having
huh
that is really interesting approach
btw
CreateEntityQuery
Is it safe to flood?
there are a max number of entity queries you can have
also they allocate memory every time if you don't dispose
(queries get re-used though)
yeah, that says to me that it's kind of unsafe to use
but that query is being disposed
using var query
the simplest approaches are the best
I could still use a callback approach tho, kek
for long lasting changes
in my case: player can exist and not exist, game will continue either way
and that change happens very rare
I assume chunk component changes chunk instead of moving entity between chunks?
can you rephrase the question?
AddChunkComponent
That is equal to AddComponent to all entities in chunk, skipping moving them part?
@rustic rain a chunk component is a component on the chunk itself and not on all entities inside the chunk
I think the question was whether or not the other data in the chunk has to be copied or if the chunk component can be added to the chunk in place. Reading through the source, there is something about keeping the chunk in place if the archetype layouts are compatible, but 100% sure if this would be considered a compatible change.
the doc is pretty clear on chunk components: https://docs.unity3d.com/Packages/com.unity.entities@0.51/manual/ecs_chunk_component.html
Hi everyone! Could someone confirm if there are still major issues with DOTS in 2021? I was told to stick to 2020 just want to know if its safe to upgrade now.
there is 0.51 version which is for 2021.3.4+
Do you remember what the problem was?
Something was missing but i cant remember which part
there was bunch of problems. 1st of all dots devs was telling that 0.17 isn't for 2021+, but then thread on forum had appeared where some people was collecting issues and ways to fix it if possible, so a lot of stuff was missing
yep, waiting for 1.0 and ship with 2022
somewhere they said they are back with smaller incremental updates in the future. im not sure i believe it
as they like to say, with scary face i guess, "you will face BREAKING CHANGES"
yeah well.. I'll believe it when I see it. I'm still waiting for them to deliver on their promise of a faster editor and domain reload, compile times etc...
2021 improved that alot for me.
I'm trying 2021 right now, cant wait to see if its got "performance built in by default" now. Was that what they called it on the blog? hehe
I know what you mean
why is that?
no system cross references - add trigger entities instead
way easier to manage it all
also makes almost everything burstable
Currently I made my player input actions bursted (it's related with AI)
You'll fall in line eventually 
I am very confused
CameraOffset = SharedStatic<float>.GetOrCreate<CameraUtility, CameraOffsetKey>();
CameraOffset.Data = MainCam.transform.position.z;
code called from static constructor of this class
Is the first use of it from a burst method
no idea, but I even created a call for it from OnCreate
meanwhile stacktrace shows OnUpdate
Though from memory burst might actually call static constructors of any static read-only
I think they might initialise them per burst function
Just set this up on on create somewhere instead of the static constructor
well here's the problem
I use this offset for static methods
a lot
that are called from everywhere
Chuck a script on your camera that sets it up from onawake
Or in your camera system or whatever
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
public static void AfterSceneLoad() { _ = CameraUtility.CameraOffset.Data; }
I'll try this
nope
nope
Awake either
No no
You need to delete your static constructor
Every burst job will call this static constructor
oh
and then what?
oooh
hm
ok, let's see
ok, that works, but brings other problems along
oof
what bothers me most is that for some reason default world calls OnCreate before Scene is loaded
this takes an ungodly amount of performance ๐ฆ
i need a better solution, like, totally scrap it ๐
but I would still need some kind of snapshotting. so scraping it not really a solution :/
World needs to setup before scene by default so subscenes auto load have a world to go into
You can control all this though
weird, the finalStats are a foreign pointer. i now gave the entity a local finalStats array and the difference is pretty much 0
if those foreign pointers where aligned in memory you might have as much cache hits as with local finalstats
i can't say much about the order but otherwise, yeah, they are aligned well enough it seems
it's an issue i've run into quite a bit during testing libraries which is basically for my test/simulation all the data is setup at once in 1 place
so it's all beautiful in memory
when in reality in an app it'd be setup over time all over the place randomly
i wanted to gave data duplication a shot in favor of faster reading. i dunno, i have tried this a ton of times by now and everytime it failed. i don't even account for the lost time in writing the duplicated data
that aside, this little copy method takes 1 ms out of a 5ms job. kind of absurd
how many instances is that?
just from looking at code, this looks like it should only ever have to run twice
once for physical spells, once for everything else
(though i'm not sure what the prefetch is doing)
you mean like 2 methods to save some branches?
i mean just like, precompute the SpellStats for physics/spell
then just copy it to the spell depending if it's physical/spell
hm, not a bad idea actually
finally got back to having some fun (it's not grid based hence showing off the random angled set to the right)
well, when I said 0 difference. it's from 5.0ms to 4.8ms
that's cool! ๐
eh, hard to measure. i still conclude that it's not worth it. ๐ much less chunk capacity
is something here I should see? I mean more than nice looking building mechanic?
i just finally got my connectivity (+ to ground) stuff working
next up need to implement stress
just haven't worked on any actual game stuff recently so it was a fun change
though i'm about to write a tool to track change filters triggering to catch when things are triggering too often
I look forward to it ๐
I wonder if I can somehow force DOTS Physics to not rebuild everything constantly
no
use havok
DOTS unity physics is STATELESS
by design
my project mostly have static buildings and moving units, I really don't have anything simulated
and all I need is collisions and some ray/spherecasts
your static scene is not rebuilt every frame.
so? doesn't change the statelessness
yeah statics aren't rebuilt unless you add something
anyone tried to implement a WaveFunctionCollapse worldgen in ECS yet?
sure
moving units
not really sure what you expect here though
you have units that move, you have to rebuild dynamics
how did it go? any weird problems when parallelizing it?
i got quite some ideas to improve on the original WFC stuff
is there need or even possibility of parallelizing it?
haven't had any 'weird' problems with DOTS in general
if you can parallelize, then you should. only positives
if i didnt make a crucial error in my design i think i can parallelize the shit out of it
AFAIK scheduling can be more costly than not doing it
that's only relevant for incredibly tiny jobs
collapsing possibilities for all the cells should not be faster on mainthread than scheduling costs ^^
I don't see WFC as costly algorithm
it's still slow
WFC for big maps and lots of rules is quite slow.
shouldn't you collapse only the cell with least possibilities?
yes and then the next one with the least possibilieties and so on.
and you're not thinking here about the algorithm for a single cell, but for a whole bunch of chunks of cells
so there is need to do it one after another I think
not really
no not really. the order should not matter. as long as you use the low entropy
and propagation of possibility reduction for neigbor cells can be parallel anyways
so while there might be some steps that in theory could be parallel but in practice wont always be, the possibility propagation benefits alot from parallelism
but how do you make sure collapsing correct cells first?
and updating possibilities in nearests cells
by collapsing you are talking about the step where you take a random value from the available possibilities to get the propagation started right? you can collapse multiple cells at once as long as they are not too close too each other
and updating the possibilities does not rely on order as i see it
since you only ever remove possibilities
and its non directional
yep
Ive seen WFC implementations in frag shaders. If that's possible, it's possible in ECS/Burst
this depends on achieving first statement of choosing cells not next to eachother
how does it in fag shaders work?? they only have state of 1 frame....
and that's difficult how?
never said that's difficult
read from one texture, write to another, flip and run the shader again. Same as blur textures
ah. ok i guess
ill try propagating the impossible tiles instead of propagating the possible ones. it seems like i can precompute a matrix (Kernel) for each Tile that describes which other tiles it ultimately will exclude. using this precomputed Kernel updating the possibilities will be only one loop over each neighbor instead of 1 loop for each neighbor for each possibility
havent seen that used in other implementations. i wonder if i got a logic flaw there but my testcases seem to work.
I'm struggling to find good info on which pieces of DOTS will be supported for different platform builds. If I rely on the Job System, for example, will I be able to publish for all major consoles and mobile? What about ECS?
we publish on all consoles with ecs (except switch haven't tried)
job/burst is considered production ready and should be available on pretty much every platform that makes sense
ecs related packages seem to have a few issues with mobile platforms though (android in particular, purely based off forums as I've never tried)
@rotund token Thank you very much for your helpful response. Any idea where I can get info on Switch compatibility for the Jobs System (and possibly ECS)? I'm coming up dry on my forum search. Don't want to pay $1k for nintendo dev kit pre-funding, but also don't want to screw myself by building around incompatible architecture
burst is marked as working for switch on the manual
Windows Nintendo Switch ARMV8 AARCH64
can be built from windows
therefore it would be safe to assume jobs work for it
Pardon my ignorance-- does burst works == jobs works?
as for entities, there's no real reason the underlying library wouldn't work as there's nothing special platform specific for this
ok, thank you ๐
however there's no guarantee things like hybrid renderer etc
would work
but yeah you can't really get info publicly due to annoying ndas etc
ah. Yeah it's the lack of guarantees and explicit warnings from Unity that make me hesitant ๐
i would expect (hope) that 1.0 would guarantee support
It sounds like the safest thing to do would be to build around Jobs, but probably wait for ECS 1.0
but yeah i've never developed on switch
i think pre 0.50 it would have been problematic due to lack of platform build library support
but they got rid of that thankfully
Me neither, but I know one big potential VC is gonna push for it
Thanks very very much
you solve it by not using jobs
if you want a background thread just use a background thread
you can run burst code in this background thread, there is no need to schedule jobs for it
and?
you simply prepare you data on the main thread
then fire it off to be worked on in the background
just like a job
not like you can access unity api in a job
you can't use entity data in long running jobs either
you have to double buffer any work you want to do
you just need to pass the data back to main thread whenever you're ready
are you talking about entities or GO?
either way, both of these operations require being done on main thread
pooling gameobjects is nearly always required if you need to create/destroy a lot of htem
level0' is corrupted! Remove it and launch unity again!
[Position out of bounds!]
hmmm
crash on launch
with build
did you include your scene
in build config
(and not just click include current or whatever the dumb check box that doesn't work says)
level0' is corrupted! Remove it and launch unity again!
i'm confused
this seems to be a unity error
not a build error
oddly enough
I wasn't ever been able to launch game in build
first I get crash related to TRS
now to scene
lol
Is there any explanation on how Dependency is constructed?
let's say I want to manually iterate chunks in IJob
how do I create all required dependencies in this job's JobHandle so I can then apply it to Dependency field of system?
i'm confused about your confusion
whatever mechanic outside of direct pointer access you are using to iterate those chunks in a job
will have the correct dependencies setup
there is no code gen for dependencies
i really need to write down my answer to how dependencies work in entities
i've written up paragraphs for this multiple times
Anytime you call
GetEntityQuery, GetComponentTypeHandle, GetComponentFromEntity etc
it calls
AddReaderWriter(isReadOnly ? ComponentType.ReadOnly<T>() : ComponentType.ReadWrite<T>());
which basically adds the read and write handles to separate unsafe lists stored in the SystemState
{
Assert.IsFalse(type == ComponentType.ReadWrite<Entity>());
if (type.IsZeroSized)
return false;
if (type.AccessModeType == ComponentType.AccessMode.ReadOnly)
return AddReaderTypeIndex(type.TypeIndex, ref reading, ref writing);
else
return AddWriterTypeIndex(type.TypeIndex, ref reading, ref writing);
}
public static bool AddReaderTypeIndex(int typeIndex, ref UnsafeList<int> reading, ref UnsafeList<int> writing)
{
if (reading.Contains(typeIndex))
return false;
if (writing.Contains(typeIndex))
return false;
reading.Add(typeIndex);
return true;
}
public static bool AddWriterTypeIndex(int typeIndex, ref UnsafeList<int> reading, ref UnsafeList<int> writing)
{
if (writing.Contains(typeIndex))
return false;
var readingIndex = reading.IndexOf(typeIndex);
if (readingIndex != -1)
reading.RemoveAtSwapBack(readingIndex);
writing.Add(typeIndex);
return true;
}```
If you have a lot of dependencies in your system this linear check for Contains can be quite costly especially outside of burst
hence caching ComponentTypeHandle and calling Update(this) is significantly faster and why Unity added it
After the first call it does nothing except burn clock cycles
Anyway so you now have a list of read/write dependencies that exist for every system
Ok so in BeforeOnUpdate on a system it simply writes a bool
NeedToGetDependencyFromSafetyManager = true;
and the first time you read from Dependency in a frame it resolves the systems dependencies using the UnsafeLists of read/write types
{
get
{
if (NeedToGetDependencyFromSafetyManager)
{
var depMgr = m_DependencyManager;
NeedToGetDependencyFromSafetyManager = false;
m_JobHandle = depMgr->GetDependency(m_JobDependencyForReadingSystems.Ptr,
m_JobDependencyForReadingSystems.Length, m_JobDependencyForWritingSystems.Ptr,
m_JobDependencyForWritingSystems.Length);
}
return m_JobHandle;
}
set
{
NeedToGetDependencyFromSafetyManager = false;
m_JobHandle = value;
}
}```
If you read between the lines on this you notice something very important
Dependency management is PER SYSTEM not per job
this is why people often get in trouble with 2nd+ jobs in a system
Once you're inside your system, dependency management is manual - you are responsible for passing dependencies between jobs
Anyway once you've done all that, after OnUpdate is done you've written your Dependency back and AfterOnUpdate is called
{
AfterUpdateVersioning();
// If outputJob says no relevant jobs were scheduled,
// then no need to batch them up or register them.
// This is a big optimization if we only Run methods on main thread...
var outputJob = m_JobHandle;
if (((JobHandleData*)&outputJob)->jobGroup != null)
{
JobHandle.ScheduleBatchedJobs();
m_JobHandle = m_DependencyManager->AddDependency(m_JobDependencyForReadingSystems.Ptr,
m_JobDependencyForReadingSystems.Length, m_JobDependencyForWritingSystems.Ptr,
m_JobDependencyForWritingSystems.Length, outputJob);
}```
simply writing back your new job handle back tot he dependency
uh huh
so it's hidden internal logic
based on what you access
guessing if I try to pass type handles between systems I'll be able to skip dependency building part
but then I won't have a Dependency that contains all dependencies of types job might use
think of it like this
public Dictionary<int, Dependency> WriteDependencies; // where int is TypeIndex
public JobHandle GetDependency(List<int> readDependencies, List<int> writeDependencies)
{
JobHandle jobHandle = default;
foreach(var typeIndex in readDependencies)
{
var dependency = ReadDependencies[typeIndex]
jobHandle = JobHandle.CombineDependencies(dependency, jobHandle);
}
foreach(var typeIndex in writeDependencies)
{
var dependency = WriteDependencies[typeIndex]
jobHandle = JobHandle.CombineDependencies(dependency, jobHandle);
}
return jobHandle;
}```
(this is not the code, i'm simply writing it in most explainable way)
yeah, that's what I thought
and then write would be something like
{
foreach(var typeIndex in readDependencies)
{
ReadDependencies[typeIndex] = JobHandle.CombineDependencies(dependency, ReadDependencies[typeIndex]);
}
foreach(var typeIndex in writeDependencies)
{
WriteDependencies[typeIndex] = JobHandle.CombineDependencies(dependency, WriteDependencies[typeIndex]);
}
}```
I hope they will implement some kind of a way to actually build dependency yourself
(again not remotely actual code but understanding the combining isn't needed)
yes
oh ok
every time a system update first call to Dependency gets handle, AfterOnUpdate writes back your new handle
I worried for a bit, that if I do way too many calls in OnCreate, it might clog dependency
a jobhandle is just a pointer to a job group
but yeah if you want to start inspecting stuff it's all native
and i don't think any of that would be important anyway imo
just understanding that dependencies are per system and the basic concept of read/write is enough
soo again:
dependencies are built only during OnUpdate call?
Through typeHandle.Update/GetComponentData and etc?
there is only 1 dependency in a system
yes accessing a system and doing entity logic on it
is actually a very common dependency breaking issue
it won't have the proper dependencies setup
so I guess CreateEntityQuery is totally ok
it's just that some feeling told me, I should always use GetEntityQuery instead
kek
CreateEntityQuery is fine
it basically needs to be used if you aren't doing work in a systems OnUpdate
queries are cached as well
or you can just dispose it
what about GetEntityQuery in OnCreate?
all GetEntityQuery does is add the read/write dependency to the system
does it affect Dependency in any way?
it just adds the dependencies to the system
once you add the typeindex to the dependency list in a system you can't remove it
so there are actually times you might want to use CreateQuery to avoid adding your dependency to the system
if it's just a single call to set something up
and you dont want the system to actually have a dependency on a component
{
ref var handles = ref EntityQueries;
for (var i = 0; i != handles.Length; i++)
{
var query = handles[i];
if (query.CompareComponents(componentTypes, count))
return query;
}
var newQuery = EntityManager.CreateEntityQuery(componentTypes, count);
AddReaderWriters(newQuery);
AfterQueryCreated(newQuery);
return newQuery;
}```
this is all GetEntityQuery does
it checks if a query already exists, otherwise just creates it via entity manager
yyep
adds dependencies and AfterQueryCreated just stores it
pretty much every GetX method in a system does this
adds dependencies then calls EntityManager version
Personally, if I was Unity dev
I'd add special attribute on every method that does it
so it would be clear whether something does smth else besides it's name
this is an interesting topic because as i mentioned at the start i've explained it maybe a dozen times now to various people
i'd say at least half my team at work (the other half except 1 would still not understand it)
but i always leave it to the point of someone asking me and having a related question why something isn't working
yeah, manual is not good enough in this regard
because i think it's something that is kind of, confusing to someone new and learning
but i do think an advanced topics page in manual about this would be very useful
because it is something you should understand at some point
man, i move something from one job to another. gain 1.5ms, lose 2ms.
how can the first implementation be so damn solid! what is this??
trust yourself
spoken like a true monk
costs me like 2ms. full memcpy is 3ms. i'm gonna test moving the final stats to the local entity
I'd further work with the dedicated spellstats struct but i want to implement a feature that can override stat calculation for spells. like taking another power value or another value for crit, etc ..
or i need to rethink using floats and take something smaller
or even better, support more than 1 data type. i usually go bonkers with stats and need doubles anyway lol
oh yeah, I have similiar problem upon me
and I consider doing Buffer
to which multiplier for some stat will be written
for example: if there's some stat that needs recalculation: special modifier entities fill buffer with their own multiplier (or adds)
and then when you add some special tag RecalculateStat
i need to come up with a system that only writes relevant stats for the calculation. i have 35 stats currently, not all are relevant for calculation and i had hopes the pointer access would be good enough but it's pretty slow
buffer is read and emptied
tertle and me recently worked on this to recalc stats on changes. worked out pretty great. now i'm on the next step, actually using those values ^^
and the stats array is so much slower than a dedicated (small and tightly packed) struct (obviously)
and yeah, i used buffers. afaik tertle rolled his own memory system
chunk dbs are pretty okay for this
@rotund token you showed us connectivity test (video) are you using something beyond HR and DOTS Physics?
basic question but GetComponent<>() outside of a job is readonly isn't it?
it's EntityManager call
GetComponentData<>
yeah only I'm doing this but its not working ๐
var itsmeworld = GetComponent<LocalToWorld>(theent);
var physmas = GetComponent<PhysicsMass>(theent);
var physveloc = GetComponent<PhysicsVelocity>theent);
var farcevect = itsmeworld.Up * 3000 * timmydelt;
physveloc.ApplyLinearImpulse(physmas, farcevect);```
I can't use SetComponent with physveloc so I guess I can only use ApplyLinearImpulse() inside a job
what isn't working? the gets? because you don't set. it's just written back to the local struct
but physveloc doesn't return anything
thats what I mean I can't see a way to set the main value this way
check dots hierachy what the value of physveloc is
on main thread: EntityManager.SetComponent
hehe you're welcome
oh man
in Build (development one, not even release) my game gives 1500 fps kek
time to stress test it
hmmm, it seems like certain entities during corvesion cause crash
due to some position problem
sharedassets0.assets' is corrupted! Remove it and launch unity again!
[Position out of bounds!]
Crash!!!
I figured it's 100% related to certain entities
but I can't figure how it's related
how are you building the project? Using the soon to be deleted build pipeline or the standard build settings?
ah, now that I'm also using subscenes, i'm gonna have to build that way as well.
SerializationException: Failed to deserialize Property=[Value] for Type=[Unity.Collections.FixedString128Bytes]. The default constructed instance does not match the deserialized type. The property needs to be writable, default constructed with the correct type, or ignored by serialization using [DontSerializeAttribute]
hmmmm
I dont think the build pipeline was updated with 0.50 release. I know a lot of things with code gen broke a lot of the old code
0x00007FFC7D31E9AD (lib_burst_generated) Ordinal0
0x00007FFC7D31E477 (lib_burst_generated) Ordinal0
0x00007FFC7D31EF34 (lib_burst_generated) Ordinal0
0x00007FFC7D320082 (lib_burst_generated) Ordinal0
0x00007FFC7D31D256 (lib_burst_generated) Ordinal0
0x0000017439E39168 (Mono JIT Code) (wrapper managed-to-native) object:wrapper_native_00007FFC7D39A300 (intptr,int,intptr,int,int)
0x00000174953DB6CA (Mono JIT Code) (wrapper delegate-invoke) <Module>:invoke_void_intptr_int_intptr_int_int (intptr,int,intptr,int,int)
0x00000174953DB5ED (Mono JIT Code) Unity.Entities.ECBInterop:_forward_mono_ProcessChainChunk (void*,int,Unity.Entities.ECBChainPlaybackState*,int,int)
0x00000174953DB523 (Mono JIT Code) Unity.Entities.ECBInterop:ProcessChainChunk (void*,int,Unity.Entities.ECBChainPlaybackState*,int,int)
0x000001747E3B30F3 (Mono JIT Code) Unity.Entities.EntityCommandBuffer/EcbWalker`1<Unity.Entities.EntityCommandBuffer/PlaybackProcessor>:WalkChains (Unity.Entities.EntityCommandBuffer)
0x000001747E3B28D3 (Mono JIT Code) Unity.Entities.EntityCommandBuffer:PlaybackInternal (Unity.Entities.EntityDataAccess*)
0x000001747E3B265B (Mono JIT Code) Unity.Entities.EntityCommandBuffer:Playback (Unity.Entities.EntityManager)
0x000001747E3B219B (Mono JIT Code) Unity.Entities.EntityCommandBufferSystem:FlushPendingBuffers (bool)
0x000001747E3B2013 (Mono JIT Code) Unity.Entities.EntityCommandBufferSystem:OnUpdate ()
0x000001747E3B0E22 (Mono JIT Code) Unity.Entities.ComponentSystem:Update ()
0x000001747E3B1C84 (Mono JIT Code) Unity.Entities.ComponentSystemGroup:UpdateAllSystems ()
0x000001747E3B18A3 (Mono JIT Code) Unity.Entities.ComponentSystemGroup:OnUpdate ()
hmmm
crashes
crashes
and more crashes
worst of all, it's in ECB
and I feel like there's no chance to figure what's up
Try il2cpp?
no way
I want mono
*AssertionException: Assertion failure. Values are equal.
Expected: -1 != -1
at UnityEngine.Assertions.Assert.Fail (System.String message, System.String userMessage) [0x00043] in <dba7a848da99437a9658d2869d2d534a>:0
at UnityEngine.Assertions.Assert.AreNotEqual[T] (T expected, T actual, System.String message, System.Collections.Generic.IEqualityComparer1[T] comparer) [0x0005c] in <dba7a848da99437a9658d2869d2d534a>:0 at UnityEngine.Assertions.Assert.AreNotEqual[T] (T expected, T actual, System.String message) [0x00009] in <dba7a848da99437a9658d2869d2d534a>:0 at UnityEngine.Assertions.Assert.AreNotEqual (System.Int32 expected, System.Int32 actual) [0x00009] in <dba7a848da99437a9658d2869d2d534a>:0 at Unity.Entities.EntityQueryManager.AddArchetypeIfMatching (Unity.Entities.Archetype* archetype, Unity.Entities.EntityQueryData* query) [0x000b6] in F:\UnityProjects\Space Tycoon\Library\PackageCache\com.unity.entities@0.51.0-preview.32\Unity.Entities\Iterators\EntityQueryManager.cs:687 at Unity.Entities.EntityQueryManager.AddAdditionalArchetypes (Unity.Collections.LowLevel.Unsafe.UnsafePtrList1[T] archetypeList) [0x00022] in *
ok, Development build gave more info
What's the Unreal Engine equivalent to DOTS?
Assert.AreNotEqual(-1, typeComponentIndex);
hmmm
Unreal MASS
sooo, looks like I instantiate ComponentType
when I shouldn't
which works ok in editor, but not in build
is there any general rule of thumb for this?
test it and see if it explodes. Regularly build
not like you're gonna find any documentation on this
it crashes
log is from build
there you go. and you found what was causing it. You can now fix it. Works as intended.
comment out all components until it stops crashing, then uncomment to figure out what causes it
if this is a development build, there should be an option for full stack traces that state the line that causes the error anyways
Might as well just rewrite game from scratch ๐
well yeah, I found it
but problem is
it's called from ECB
meaning some system
out of dozen
dozens*
shipped an instruction to ECB
never trust ecbs, devils tools
with invalid component type
You do have the code stripping set to "Off" right?
where is it?
project settings, player, scroll all the way down, managed stripping -> "Disabled"
it is disabled
alright, no clue then
im gonna try building my own project then, see if anything explodes
is this in an icomp?
oh fuck, the build UI still doesnt work
but nvm this, I need to fix ComponentType problem first
kek
feels so bad, building was broken for my project for a while
because of some internal bug that causes crahses
now it's so hard to figure out what's wrong
build daily, make some build script. it's so annoying finding bugs after a few days of coding
yeah, that was the purpose of this build, hehe
what the fuuuuuuuck
nah, same crash
i can see my lamp flicker from the power draw of my computer
with -1 == -1
i built my stress test scene and my lamp light is flickering from the GPU demand on my computer
attached to the same extension cord as my laptop
@rotund token do you happen to know what can cause ComponentType.ReadOnly<T>() to return type with -1 index?
anyways, no issue with dots or building of dots projects on my side. Just stress test scene very expensive, as intended
ok
I figured it
turns out
you can't store ComponentType in readonly static field
works in editor, crashes build
oof
I'm glad I tested it before I overused it
hmm
Can build pipeline can be somehow connected to profiler?
ah
that was fairly simple
Profiler literally sees it as option itself, kek
is there a way to use ECB with ISystem?
or do you need to create your own unmanaged version?
Creation of it is not burst compatible so you create at it startup. Then set the ECB flag to "multiple playbacks".
Yea, it's an option at ECB creation under PlaybackPolicy
I dont see anything in the actual playback method that would block it from being burst compiled. Cant be run in a job of course.
I wonder
if using multipleplaybacks always
is faster than creating new every update
creating an ECB probably isnt that expensive. The main cost is adding to it dynamically (requiring dynamic resizing and mem copies) and playing it back to the entity storage
I'm more worried that
since it'll be multiple
it'll probably be checked by ECB system
every frame
or not
not sure
if you play it back manually following a job or whatever adds to it, it'll never interact with the ECB systems
Ya know, I just read the forums after a few days of ignoring it and I see that the 0.51 announcement post comments has once again gotten spicy. Gotta love the forums @viral sonnet
Just physics netcode and hr
Did you solve your component type issue
I see that you at least realised your mistake
(you need to store stable hash if you're serializing component types)
Multiple playbacks doesn't allow you to write to it in multiple frames
Just allows you to replay what you've written to it. Useful if you cache say creation of a really complex entity instantiation. You can just playback again to create a new one rather than thing through the setup.
oh, i misunderstood what it meant then. Thanks for the correction
Anyone a physics wizard here?
How can I make a thing rotate under gravity, like it has a mass distribution?
I'm thinking I can just add some joints and masses but wondering if there is a built in way using this inertia tensor doodad?
can I do RaycastCommand in DOTS Physics?
confused by question? do you mean replicate this: https://docs.unity3d.com/ScriptReference/RaycastCommand.html
because you don't need this for DOTS physics you can just raycast from a job yourself
public CollisionWorld CollisionWorld;
just pass in the collision world to a job
and do whatever you want on it
like, CastRay
in same manner as here? https://docs.unity3d.com/Packages/com.unity.physics@0.51/manual/collision_queries.html
nvm ๐ there is a sample at the bottom
but will it be at least of same performance as RaycastCommand?
I mean in situation where you want to make x raycast per character for n characters
before ECS I was gathering every cast in huge array
in ECS I can gather it even more efficiently
ecs raycasts are faster with burst as far as i'm aware
(though I've never hard profiled it so take that with a grain of sand)
but there's no need to do it like raycast command
you can skip the whole gathering step
and just do it willynilly as required
you could test with a custom mass distribution in your physics shape
sorry Physics Body
Running into this same issue myself, digging into the training DOTS pages show that Unity is gonna introduce a singleton such as BeginSimulationEntityCommandBufferSystem.Singleton that you can query for in burst. That singleton will contain a method called CreateCommandBuffer(state.WorldUnmanaged) that will present a command buffer that will be completed in the CBS all in burst compiled code. Just not in 0.51 currently.
i wrote an unmanaged ecb system if you really don't want to wait...
#archived-dots message
huh, neat. Sure, dont mind if I do.
Ya know, after spending a few weeks in shader world, why does c# need the "new" tag?
Skip the new, write the class constructor, life easier
just a heads up i don't really use it as my game is pretty much completely static archetypes now and i'm just sticking to systembase for the systems I instantiate new entities.
I did test it worked though
Yea. I'm testing out the ISystem as it seems to be the way forward coming down the pipeline from Unity
was more just a challenge because people were sating it couldn't be done
90% of my project is ISystem now
im getting that impression seeing the training samples being written right now.
Is the 10% just entity instantating?
and just things i haven't converted yet
things that were still relying on physics world instead of my proxy component etc
or just input managers
etc
(or managed code for like animating on client)
Ah. Alright. You cant burst the input get axis but why not ISystem? I was thinking of converting my movement to ISystem from SystemBase.
all my movement is in isystems
Actually, this might be burstable
i just have 'input systems' that write the new inputsystem events to components
Ah, events
i have a whole input state system
input is clearly defined per state in my game
and it never has to check if it's in the right state
Do you use IJobEntitys with ISystem or old faithful IJobEntityBatch/IJobChunk?
nearly all my code is written in IJobEntityBatch
i rely heavily on change filters and just other general per chunk optimizations
Ah, okay. Probably wise but I just run all my jobs every frame. Mine's current GPU limited so I havent played around with optimizing my job execution yet.
A bit annoying that profiler doesn't show bursted ISystems as green
Is there any need in making bursted ISystems?
Currently I store all of them in LateSimulation
Along with unbursted system bases
(All of them have to run on mainthread)
yeah that would be nice
bruuuh
standard URP shaders don't support GPU Instancing
"Universal Render Pipeline/2D/Sprite-Unlit-Default"
at least that one doesn't
foreach (var ltw in ltws)
{
Graphics.DrawMesh(MeshDatabase.Quad, ltw, _mat, 0, null);
}
Graphics.DrawMeshInstanced(MeshDatabase.Quad,
0,
_mat,
ltws.Reinterpret<Matrix4x4>().ToArray(),
ltws.Length,
new MaterialPropertyBlock(),
ShadowCastingMode.Off,
false,
0,
null);
top one works
bottom one doesn't
ok, non-sprite one works
really pog
reduced draw time for 2k lines from 1.5ms to 0.01ms
hmmm, is there any way to split arrays in 2 halfs through pointers?
or not actually halves
but batches of 1024
1023*
do you actually want gpu instancing tho? that disables the SRP batcher which is better
it's unique kind of drawing
that shows entitiy's path
SRP batching in no way can be faster than this
also, iirc anything MaterialPropertyBlock is kinda deprecated
it's not?
that's literally the way how you make instancing work with properties per object
Instancing is way faster than any sort of batching
you are simply limited to what you can instance
thus can't instance everything
and sometimes batching is indeed faster
the SRP batcher batches on both tho. material and mesh
but it's not faster
for me it actually is
from what I noticed- it is faster in cases, when you have a lot of combinations of mesh/materials
but when you have a lot of same mesh and materials
instancing is just woof
srp batcher should be faster for /most/ cases
1 call for all
+1
so is srp batcher?
yep
but in case of instancing
you make a batch yourself
which is already faster even if managed
but here you have jobified baking
and I think this is where profit comes in
well if it is on your end. ๐คท whatever works
but i've only seen gpu instancing be slower than srp batcher, not faster.
var ltws = _query.ToComponentDataArray<LocalToWorld>(Allocator.TempJob).Reinterpret<float4x4>();
new BakeMatricesJob
{
ltws = ltws, gtps = _query.ToComponentDataArray<GetToPoint>(Allocator.TempJob).Reinterpret<float2>()
}.Run(ltws.Length);
this is how it looks for me
not an expert here but from the limited i understand instancing is fast with identical materials and not using a property block
literally grabbing ready to draw matrix from query
meanwhile in case of SRP, I'll have to ship individual matrix on each
which internally will probably store it dynamically somehow
ah yeah right here: material property block:
Note that this is not compatible with SRP Batcher. Using this in the Universal Render Pipeline (URP), High Definition Render Pipeline (HDRP) or a custom render pipeline based on the Scriptable Render Pipeline (SRP) will likely result in a drop in performance.
likely what makes your srp batcher version slow
maybe
what do you mean?
how do you draw for SRP batcher?
I might be confused here
are you talking about drawing with Graphics.DrawMesh vs Graphics.DrawMeshInstanced?
yes
well your use case might just fall into this limited range: If you want to render many identical meshes with the exact same material, GPU instancing can be more efficient than the SRP Batcher. To use GPU instancing, you must either:
yeah, 1023 per call
may
SRP batcher is for built in shaders using g shader graph.
GPU instancing is what you want to use is you're rendering low level
DrawProcedural
how do you convert to procedural?
it requires some kind of bounds...
meanwhile all I have is float4x4 array
That maps straight to driver API draw call. Dynamic vertex and index count from buffers and you can specify the number of render instances from the script.
I recommend you take a look at vulkan and openGL documentation. Graphics maps 1 to 1 with it.
Not that difficult to understand once you get the hang of it
Depending on your rendering target, you dont need to specify bounds. Drivers already fulcrum full at rasterization (between vertex and fragment).
Occlusion culling must be implemented manually though. There are plenty of tutorials for depth passes.
DrawMeshInstancedProcedural
Is there a Now version?
Let me check the docs. These calls requiring bounds and stuff will go through unity rendering. Applying lighting and anti aliasing and such.
If you want to skip those and go right to the actual draw calls, use the "Now" versions. Let me find the right one.
I need those
You need lighting?
meh
MSAA is driver level. Should be an option on your render texture or camera. Dont know if it works with draw calls though. Definitely doesnt work with the raw draw calls
I'll just batch to 1023
Or that.
This is Unity's "mid level" solution. A replacement for the DrawX that are not "Now" low level calls.
Completely new in 2021 so its undocumented and no tutorials but seems straight forward
It should allow you to not set certain things but I dont know how that would affect rendering
maybe just .Reinterpret() it?
it has no such method
maybe cast it to NativeList and reinterpret it?
i'm just guessing here. but maybe
i mean you could always do manual pointer manipulation
((Matrix4x4*) UnsafeList<float4x4>().GetUnsafePtr()) and then memcopy into a matrix4x4 array
yep.
Or just create the array as matrix4x4 in the first place
nah i don't think that would be wise
turns out I have tertle's extension
matrix4x4 isn't burst optimized
var array = new List<Matrix4x4>(count);
unsafe
{
array.AddRangeNative(list.Ptr, count);
}
hehe
If you're not doing any complex math operations to it in Burst, you dont need to cast to 4x4.
let's see
a lot of math
it's TRS calculation
Ugh
looks like I'm close
kek
all right
10k lines
0.40ms total
baking matrices is tough
let's thread it
0.3ms threaded
it does save some time
Does anyone know how to Instantiate prefabs via script in editor mode into a subscene? I have a scene Core which has a subscene (World). World has a component called WorldBehaviour. Inspector button triggers a method in WorldBehaviour to load a save file, read it, and instantiate all objects. But I want them all to be in the scene that the WorldBehaviour is attached to.
Otherwise it instantiates them into scene "Core", which is a no no for me
How do I do that in my situation?
my subscene has this spawner entity
which converts GameObject prefab manually, and it contains all SubScene link components
as simple as that
?? I don't think that was what I was going for...
that's just how you create prefab that is linked to SubScene
with that you can do it however you want
all isntantiated entities
will be attached to subscene
You're not talking about Runtime are you?
My question was specific only to editor mode, (not play mode)
oh
I don't need to convert to entity. I need to instantiate from editor into a specific subscene (so that it will look like they are parented to that subscene gameobject).
I see
But if you do Instantiate, it will attach it only to the root scene
don't you just parent GameObject to SubScene GO?
You can't. that's not how that works.
subscene has transform though
SubScene really is a scene, even though it looks like a GO with a transform that you can parent to.
If you parent to that scene and hit run, they will be hidden, and NOT converted.
hm
They have to exist within the actual World.unity scene file.
Yes! That's my question...how?
well, how to get reference no idea
how to instantiate - it has parameter from what I remember
just for Scene
hm
Can you send me docs on that?
Oh please remember where, I need to know!
maybe that's what you need
set subscene active
then back to your previous
spawn all you want inbetween
Hmm...ok. I think I got no choice until something less hacky can be found ๐
that's not really hacky
that's how ppl have been doing it in classic Unity development afaik
Thx
10k entities with AI
all drawn at once
each has it's own movement line rendered
pog
wow
i7 10700f
1060 6gb
so same gpu as me
let me load something up quick
is that drawing with graphics instancing per frame?
you could definitely draw those lines faster than instancing
if you simply made it a single mesh
how so?
my draw system draws everything under a single mesh
and it's just based off a lot of lines
handles a few million verts easy enough
yeah, but how?
then it just uses CommandBuffer.DrawMesh
1 call for lines
1 call for text
1 call for solids
pretty much
systems just fire events with what they want to draw
and it just combines it all
so it's all white
hence the 3 above draw calls mentioned
unique or per call?
i current support all this
yeah, I get the idea
everything up to text32 is lines
oh man, I might come up with smth similiar
text is just the alphabet on a texture and uv'd
i frequently recommend people use aline
Can't purchase it, sadly
if you dont have some type of drawing tool from burst in your library you're making a mistake
besides
the ability to debug from drawing data saves so much time
I still need a material for actual non-debug runtime
my movement lines are supposed to be fancy
and 10k is just stress test
in reality it'll be no more than 100
or unless some modders will decide that's not enough, kek
still, it'll supposed to be fancy, material based drawing
yeah sorry give me a sec still updating a library i havent opened in ages
I Just mean, that this library doesn't have my use outside of debugging (in my case at least)
but since game is meant to be moddable, debugging is supposed to be runtime
oh i 100% agree
you've probably seen my debug toolbar in screenshots i've posted
i try to build all my debugging tools in game
no, I don't remember any of that
but I am implementing debugging tools atm kek
some knid of
spawns entities in pointer position
custom cameras for looking around, custom physic drawer + all my debug drawing systems
etc etc
inspired by overgrowth
yeah ok just testing rendering 100,000 capsules in one of my demos
and seems to match pretty well with your results
thought it was faster
so what is fps on 10k?
keep in mind tho
it's not only capsules
it's also sphere in head part
and quads on every moving one of them
yeah not a fair comparison anyway
these guys are all navigating around them
i just remember this demo being amazingly fast
and it is - if i ignore the cpu being blocked waiting for gpu
๐ข
need a better gpu
oh sorry closed project didnt record it without my systems running
i think it would be around 110-140
im not sure why i have that dip every few frames
so, pretty much same result I'd say
btw, do you happen to know whether it's possible to preview List elements in UI Builder?
for ListView
i havent used ui builder in a couple of months but last i remember listview was pretty unusable in it
it is usable... just not in UI Builder
yeah thats what i mean
it works completely fine
but just in ui builder apart from simply adding it
you can't do much with it
ugh, my approach to it is that I create template VisualElement nearby and then just copy all styles from it
Works shitty, kek
let's say I have 2 full chunks with 6 entities each
If I remove 5 from one and 5 from another.
Will entities get stored in one chunk?
nnnah, I'd rather figure better approach I think
wow the one time im looking up sth on stackoverflow its down lol.
im wondering if there is a goto algorithm to iterate over all neighbors of a cell in a grid. ofc its easy to do but im wondering if i should look for some easy performance increases in the way i iterate.
what can be easier than index offset array?
sry can you clarify?
just have an array of indices for offset cells
like, if you want north west sound and east
It'll be Vector2.up, Vector2.left and etc
there's even algorithms for radial checks
that literally go in circles from starting point
ah yeah sure. thats what i wanna build up. essentially the question is how i best build this array dynamically for neighbors X cells away.
im probably overthinking this. i just thought there should be a standart best way to do this
I did index array
I used it in gas spreading algorithm
check nearby cells, fill them with gas
yes im doing something like this in another context. but lets imagine the gas spreads with different speed to neighbors 1 tile away and neighbors 2 tiles away. im basically creating a Matrix that stores those different speed values and apply that matrix everytime i spread the gas. As this is done quite often i just wanna make sure im not leaving low hanging perforamance fruits.
oh you have gas too? xD
ill probably flatten that "SpreadingMatrix" into a dynamic buffer. but i guess ill always have to iterate over all neighbors in the grid
I had a large grid
as i said its a different context but i applied it to your gas example ^^
ah, ok
So I worked without burst back then, it was all managed
but proven to be somewhat fast
I had a float[] array for all density of gas
size of array was size of whole map
and I had HashSet for active gas tiles
its for runtime mapgeneration. needs to be fast. burst is a requirement ill always set myself ^^
Basically where it exists
and then I simply iterated over all HashSet
processing every time one by one
problem is that I couldn't think of how to make it parallel
so it was all mainthread
but still very efficient
hmm you still could have scheduled it even if not parallel. but yes spreading gas is not easy to do in parallel. my case is easier
fun fact: most of the really abusable bugs in "Oxygen not Included" come from those raceconditions introduced by spreading liquids and gases
It was back when I had no burst or anything
It was mod for a game
right now I would rather just process whole grid alltogether
with burst it'll be fast I think
skipping 0 values
in all 16 threads should be fast
How big is this grid?
smth like 300x300 in my case
IIRC a full gas / liquid simulation can be done in parallel with iteration to approximate a few of the differential equations. So it can be done in parallel.
I tried my hand at it, a real time box no interior surfaces could get a 512x512 box where each pixel was a gas cell in 144fps.
how do you all make statistics? I mean do you make component with value and it's max value or do you split?
or maybe do you have max values in some sort of unit/character definition somewhere in a blob?
what kind of statistics?
health in example
or any other that has max or base value for that matter
can I do something like this with interface?
new EntityQueryDesc
{
All = new[]
{
ComponentType.ReadOnly<Health>(),
},
None = new[]
{
ComponentType.ReadOnly<IActionComponent>()
}
}
to sort out that entities which have some sort of XXXActionComponent : IActionComponent, IComponentData on it?
no
you can use reflection tho to get that Array of components
I personally also think about implementation of stats system
and I came up with this concept:
there's health component which tracks current hp
And there's maxHealth component with written max value for hp for this entity
Now there's also a buffer of Entity type on this entity
I think @rotund token said something about that inheritance works in queries but I can't recall it
and everytime you need to recalculate stats you go and add such tags to all entities in that buffer
and those entities on their end
go calculate their own multiplier or offset for max health value
and then write it to main entity's maxHealth component
but in this way you have value that don't change on the enitity so your chunk has less of them
sorry, I don't get what you mean
you can have max value in a blob, and keep only multiplier of it in the component
but what if you want different max value based of different multipliers (buffs, debuffs)?
also why have it in blob
if it's probably just 4 bytes of float/int
unnecessary random access
to not have readonly data on the entity as you also have multiplier
well, if it's readonly
why not just have SharedStatic value?
it's burstable static pointer to value
as a ISharedComponentData?
but from my point of view max health is not mutable
is it data per all entities?
i mean, I can have multiplier for it from buffs etc. but one type of character/unit will always have same base max value
so if you have buffs then you want to have component for it
managing blobs per entity is probably hell, kek
it's not blob per entity, it's a blob with every unit definition
but every time unit gets buffs, max value changes for this unique unit
but you need that max value only when creating or healing unit
so... pretty much every time you change health
i think what Issue is saying is normally you'd increase/decrease maxHealth based on buffs or negative buffs, normally, so that value would likely change from one unit to the next
if you have a bunch of never changing data, definitely i think blobs are the way
I just don't get the point of avoiding it on entity
managing it will be way too overcomplicated
personally, i'd just have a health component, with a curhealth and maxhealth value on it
so unless your max health value is huge chunk of data, I don't see a reason why do it any other way, but just component field
because you are thinking about only health, add 20 other values to it
health was only an example
well maybe you just need to separate logic between several entities?
like
instead of having literally all on main entity
make a buffer of entities on that entity and pass certain data to them
so every time you interact with entity you actually get value of other Entity to interact with certain system
I plan on doing it with Rendering first
and I don't understand what's so complicated in keeping "base definition" of the unit type in a blob, access to it is like blob.units[typeID].stats[statID].value
separate render entity and "brain" entity
it's because of creation of blobs and disposing of them
it is a bit complicated
stats are okay in blobs but throw in buffs and you'd need something else
I create blob once, at the beginning
well, if it fits you, I can't really argue against it then
main argument aginst it as you said it before is random access
but it's random access vs entity size
how does accessing blobs in a system affect cache friendlyness etc
blobs also store memory, hehe
i really have no idea about this
blob reference I mean
blobs are a cache miss because it's a pointer
ah i see, so just a flat out cache miss
same goes for BlobArray/BlobPtr. one additional cache miss most likely
be interesting to test blob array access vs just packing that data into a component or buffer
it is different ,kek
i can tell you comps and chunk buffer is fastest. everything else is not local, so slow
what du mean chunk buffer?
a shared component?
a DB that stays in the chunk. one that doesn't exceed internalBufferCapacity
how do you allocate a dynamic buffer to a chunk?
it's actually the default behaviour. when you don't set the cap it's 8
so 8 elements are reserved in chunk
which makes DBs that don't have this tag set set quite large
how's the type is called?
fastest way to destroy chunk capacity
oh
