#archived-dots
1 messages Β· Page 139 of 1
Yeah I was going to ask why that sounds liek dynamic buffer
Because it's not fixed
if you overflow capacity
It will move to heap
and all memory management Unity doing automatically for you
ahh I see
Technically DynamicBuffer it's same as NativeArray
It's also NativeContainer with fixed size and simple pointer
Difference is
until you under initial capacity
you use chunk memory
Buffer has header
and when you read\write data it only use offsets in memory from header
Is it possible to step certain physic bodies in Unity Physics? I'm asking since i want to network the RayCast Car sample, or are there other ways to archieve rollback/prediction on physic bodies?
But after overflow internal capacity it allocates (malloc) Persistent memory
and using pointer to persistent memory instead of header with offset limited by internal capacity in chunk (yes it's also pointer, just different word). Implementation pretty simple
Is it possible to step certain physic bodies in Unity Physics? I'm asking since i want to network the RayCast Car sample, or are there other ways to archieve rollback/prediction on physic bodies?
@north bay Your networking is P2P or through server?
Well all physics calculated on server side guess?
People are going to control the vehicle so having an input delay of ping + interpolation delay isn't really acceptable
It seems like i have to remove it from the physics simulation and step it myself like they did with the character controller, but i thought there would be an easier way
Well it's how all network AAA games works, calc gameplay important physics fully on client not acceptable (acceptable for local things which not correlates with gameplay, like flags and trees affected by some things like bird etc), especially when it not fully deterministic π For cars itself you should definitely calc it on server which will be "true" physic state, clients will have their local simulation but this simulation shouldn't be synchronized, this is just for hiding delay, server will send "true" simulation results π
Well yea, but when the server sends the true state it will be x ticks behind the currently client predicted state and therefor i need to repredict the simluation for those ticks -> step the simluation for that object. Maybe im missing something obvious
Yes and commonly for that using Dead Reckoning
And ususally this covers delay smooth and thus (usually) differences not noticable π
Write good networking is one of trickiest things, for latency sensitive games, in gameplay programming usually π
So many usually
Does anyone have a helper methods for logging inside jobs ?
Would the BurstDiscard attribute work on a proxy function to Debug.Log?
Burst supports Debug.Log now
Oh I guess its the inside jobs part π€
but it is only callable on main thread, so it doesnt work with Schedule, ScheduleParallel
yeah
Hmm you could try pushing the log statement into a parallel container with a timestamp
weird thing is, it logs at first for a while then it gives error that i should call it from main thread
and then flush that container later back on the main thread with the actual log statement to a file or console π€
ive done it before, you can use shared static, write to some sort of stream/queue/whatever and then have it play back on main thread with some sort of hook.
I also wonder if Visual Studio/Code's debugger works with the threads
I remember reading that rider had support sometime ago π€
@mint iron no need now i think π (if your sentence was for me)
is there a need for Burst Discard now ? since it works with burst now
how can this work inside jobs exactly ?
you are just calling Debug.Log inside static methods
π
yeah... thats confusing, if it BurstDiscards, then it not going to run in burst
hemm in jobs from a system, am I sure that any entity struct that I get from a query will stay valid within the chain of jobs/dependencies from that system ?
this might be horibly worded sorry :x
yeah they will stay valid as long as you dont do structral changes
log works thanks Eizen π
kinda weird, if we directly call it its an error but if we indirectly call it then it works π€
Well
problem in Burst usually is string concatenation
which not allowed
like "asdasd" + someVar
with string.Format("Some string {0}", index) right inside job it will work also
but will complain about Debug.Log
Because of how burst compiles things and Debug.Log works
Under hood Debug Log calls new Logger() and new DebugLogHandler() and here is come problem on which burst complains
Becuase of how burst compiles instances and call constructors
Like this:
Don't use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function.```
yea
Anyway it works? Then just s....t up and use that!
π
Joke
hemm in jobs from a system, am I sure that any entity struct that I get from a query will stay valid within the chain of jobs/dependencies from that system ?
this might be horibly worded sorry :x
@zinc plinth well (why I always use that word) if you want schedule chain which in some job check\get some entity, stores it in some native container (for example) and you use that entity for something in other job in this chain yes?
yep
before I had these ```
public NativeArray<GridMemberCoordinates> remainingGridMemberCoordinates;
public NativeArray<InventoryEmitter> remainingInventoryEmitter;
public NativeArray2D<GridMemberCoordinates> remainingNeighborsGridMemberCoordinates;
public NativeArray2D<RoadGroupGridElement> remainingNeighborRoadGroupsGridElements;
public NativeArray<GridMemberCoordinates> activatedGridMemberCoordinates;
public NativeArray<InventoryEmitter> activatedInventoryEmitter;
public NativeArray2D<GridMemberCoordinates> activatedNeighborsGridMemberCoordinates;
public NativeArray2D<RoadGroupGridElement> activatedNeighborRoadGroupsGridElements;``` but I saw that I needed an `Entity` to add a component to an entity so I added ` public NativeArray<Entity> remainingEntities;` and was afraid these structs could become invalid in some other system with the magic of the scheduler while this chain of jobs was still doing it's thing
Yes it will be stable always inside Jobs chain, because inside jobs chain structural changes not possible, they delayed by EntityCommandBuffers. (technically you can do structural changes directly inside job through ExclusiveEntityTransaction, which I described many times in many places, but this thing not for your case). If in a middle of chain you have system which completes jobs, doing structural changes - after that point validity of your entities not guaranteed
Also should mention ECB itself
the structural change is the end of my job chain, so I'm all good
I'm using the EndSimulationCBS
if you have playbacks between your systems (which is structural change) - after that point validity of your entities not guaranteed. For example have multiple ECB systems which buffers used in chain
If you're doing all stuff with your entities before any playback it will be stable
playback ?
But of course you should look at your dependency chain carefuly
because if systems use that array but not in same dependency chain it's again will be not guaranteed point
I'm taking care of my deps π
playback ?
@zinc plinth All entity command buffers playbacks - call Playback which....playback recorded commands chain (through burstable function pointers now btw)
hooo that
didn't really know the sense for that word ^^'
You have tape
You record your voice commands in to that
then you press play button on your tape recorder and all your recorded voice commands playbacks
Huh need to go sleep, but there is still so many work (3 AM in Russia, Witching hour) π¦ You guys distracting me π
^^
Hi guys.
I have a NativeMultiHashmap<Entity,int> and I need to do something in a Parallel Job with each entity and the sum of all INTs.
Those entities don't have anything in common and I cant use a query to loop through them.
Is there a known workaround or tip to do something like this?
can't you get the key array from the multi hash map and use a IJobParralelFor ?
wait, do you mean the sum of all the ints, or just the ints relative to one key ? @chilly halo
Just realized you cant put normal C# objects to entities thru AddComponentObject, i is sad
@zinc plinth The sum of all ints of each key.
And yes... I can do that but the thing is that the NMHM is being built in another job , and getting the array of unique keys must be done in the main thread, and I would prefer to dont do that.
you can just get it in another job 
which runs only once
did quite alot more jobs than I anticipated following this principle but I think it's worth it imo (compared to Complete()) https://i.imgur.com/odIHR2N.png
Just realized you cant put normal C# objects to entities thru AddComponentObject, i is sad
@opaque ledge class (not struct) IComponentData
ah true, why i didnt think of that
you know this reminds me, if we can just make class IComponentDatas and add that to Entities, why do we need AddComponentObject for ? π€
@zinc plinth The sum of all ints of each key.
And yes... I can do that but the thing is that the NMHM is being built in another job , and getting the array of unique keys must be done in the main thread, and I would prefer to dont do that.
@chilly halo Write native counter and sum concurrently
(except TextMeshPro stuff, build fails if so)
Also werent you going to sleep, its 04:14 π
Fixing build
well you still have to do that in a previous job @storm ravine
you'll end up with an NativeArray<int> sizes
can't remember how to get the thread index in to Entities.ForEach, anyone?
and I don't know how you could do that concurrently within one key
can't remember how to get the thread index in to Entities.ForEach, anyone?
@mint iron int nativeThreadIndex as one of lambda arguments
ah in ForEach, nvm
and I don't know how you could do that concurrently within one key
@zinc plinth through written native counter
yes, but how do you split an array of value from one key between parralel instance
from a NativeMultiHashMap
you only have Next
afaik 
you can parralel between keys, but not split the set of values of one key between multiple instances
public class LoggingTestSystem : SystemBase
{
protected override void OnUpdate()
{
Entities.ForEach((Entity entity, int nativeThreadIndex) =>
{
NativeDebugger.Log(nativeThreadIndex, FixedString.Format("The entity is {0}{1}", entity.Version, entity.Index));
}).ScheduleParallel();
}
}
``` https://gist.github.com/jeffvella/ede829d9b6b8290009f083d6b7aa6604
@zinc plinth IJobNativeMultiHashMapVisitKeyValue
huuuuh
But it's just abstraction, under hood it's key per thread and it's what you need. Split one VALUE per thread will be bad, and reduce performance instead of give you gains
With multi threading you always should process buckets of data, but not one value per thread in general
Only case where you set 1 per thread is some heavy algorythm and you just should run one calculation instance per thread
otherwise performance of parallelization will be opposite and can be slower that single thread
@opaque ledge This thread might help you with logging n' debugging in jobs https://forum.unity.com/threads/as-debug-log-is-a-problem-in-job-i-made-this-simple-trick.860464/ Also this video https://www.youtube.com/watch?v=nou6AIHKJz0&feature=emb_title
Simple but useful
public static class JobLogger
{
[BurstDiscard] public static void Log(T segment) =>...
Quick guide and some additional notes on the new native debugging support for Burst. Available from package version 1.3.0-preview.4. Timestamps are below for convenience.
Timestamps:
[0:13] Quick guide to debugging
[1:29] Current Limitations
[1:33] Threaded Debuggin...
π
when you do ECB.AddComponent, what happens if the entity already has that component ? does it replace it or ? 
yes, it replaces it
alright, thx!
remember the good old days when it would just error out π
It not replace but will ignore after first AddComponent
AddComponent not replace any thing it's not the same as AddComponentData for ECB
ah right, i assumed AddComponentData
Ah stop
I'm sleeping already
It's I missed
for ecb it's exactly AddComponent
AddComponentData it's for EM
yeah that made me go looking for a new addcomponentdata π€
yeah i guess i am sleeping as well lol
For ecb AddComponent with instance yes latest override previous and now I'll go sleep
I wonder if AddComponent causes a structral change if it already exists π€
No
It first execute AddComponentWithValidation
which check HasComponent
and after that it just set value
it only add on first AddComponent call
what are the reasons a system could not show up in the entity debugger ? 
not in one of root groups
ahh nvm, it was because it wasn't ran and it hides it by default ^^'
yea if the dependencies arent met on system initial run they're not registered to run so it doesn't appear in the entitydebugger π€
@chilly halo you got your answer π
@zinc plinth @storm ravine Sorry I was dining
So... I have my NativeMultiHashMap<Entity,int> and the idea is to end up with a parallel job able to do something with each entity in that NMHM and the sum of all int, so....
Run a IJobNativeMultiHashMapVisitKeyValue for the NMHM and build a NativeArray<Entity> and a NativeArray<int> with the same sizes , where the second NativeArray is the sum of each int[] inside a NMHM.
What I dont get is how to use IJobNativeMultiHashMapVisitKeyValue for that. IJobNativeMultiHashMapVisitKeyValue only has a ExecuteNext, no index and is executed N times as values has each key. How can I use it to build those arrays?
Sorry if the question is a bit obvious, I think I'm missing something big here.
In order to add some more context I will write the full story here... I case is happening an XY problem of some sorts .
I'm simulating fluids in a voxel world. I have a 3D Grid where I have an entity for each cell. In a given time I add some of those entities a new component [LiquidCompoenent].
The way I simulate that liquid is first fetch all entities with [LiquidCompoenent] but without the [SettledComponent] (that compoenent is added to entities with liquid that dont need to be updated) saving them in a NativeHashSet to use it later.
Then there is a second job that goes through those entities again but this time creates a new struct of data that has a cache of all relevant values for each valid NEIGHBOUR.
Then I go one more through every "simulated liquid voxel" to simulate the liquid movement using the struct of data created in the previous step. In this job I create two NMHM<Entity,int>, one with the differences of liquid generated (in and our flow) and one with a settled counter.
Then Lastly I should go through every entity in those NMHM and apply the sum of that numbers to their components.
is it bad to use a cached monobehaviour in a system to change job parameters at runtime? like when the system is created, i get and save the monobehaviour as a property, then in the system's update i use public properties in the monobehaviour (exposed in the inspector) and pass them into the job?
i just feel like it'll be a lot quicker to test things rather than changing a single number, waiting to recompile, then seeing if the number even works
this component type is
classIComponentData, not struct
@storm ravine wait what, a class deriving from IComponentData and not a struct? Native container inside IComponentData?
Can I use burst with a Class? Or are you making a query for the singleton, save the values that you want in local variables and then use them inside Entities.Foreach?
Class is a managed type so you cant use burst with it, but you can make ForEach with class in your query but only with WithoutBurst().Run()
Yeah but to write cleaner code I want to use a singleton component instead of making some static variables inside the system, so @storm ravine talked about making the code cleaner
Well, i dont know/remember that context so i just answered your question about if you can use burst with classes
How should I store a list inside a class deriving from IComponentData? With NativeList or with "normal" List? (I don't need burst, I need to query this component to read the data to use in other queries)
You can do it with both
i mean, if you are going to somehow use that list in your other systems then make it NativeList, but if its self-contained then use List or Native
GenerateAuthoringComponent doesn't make NativeList inspectable :(
Should I dispose the native container inside the class deriving from IComponentData in the OnDestroy function of the system that writes to that component?
@storm ravine wait what, a class deriving from IComponentData and not a struct? Native container inside IComponentData?
Can I use burst with a Class? Or are you making a query for the singleton, save the values that you want in local variables and then use them inside Entities.Foreach?
@wide fiber yes class. You canβt work with that inside job/burst. Idea is query that singleton entity, get, for example NativeList, in local context of system OnUpdate and pass that list in to ForEach. No need fields on system for that, no need statics for that.
Ok, that means that I understood correctly
Should I dispose the native container inside the class deriving from IComponentData in the OnDestroy function of the system that writes to that component?
If the component doesn't exist and I query for that inside the OnDestroy() it gives me an error, should I use query.CalculateEntityCount to check if there is a singleton? (Or does a better way exist?)
I don't have this problem inside OnUpdate because I use RequireUpdate(query);
Should I dispose the native container inside the class deriving from IComponentData in the OnDestroy function of the system that writes to that component?
@wide fiber up to you. In my case as I mentioned above I have system which only destroy that containers in OnDestroy by querying that singleton entities
Yep, you need that check if your singleton may not exists
π
@zinc plinth @storm ravine Sorry I was dining
So... I have my NativeMultiHashMap<Entity,int> and the idea is to end up with a parallel job able to do something with each entity in that NMHM and the sum of all int, so....
Run a IJobNativeMultiHashMapVisitKeyValue for the NMHM and build a NativeArray<Entity> and a NativeArray<int> with the same sizes , where the second NativeArray is the sum of each int[] inside a NMHM.
What I dont get is how to use IJobNativeMultiHashMapVisitKeyValue for that. IJobNativeMultiHashMapVisitKeyValue only has a ExecuteNext, no index and is executed N times as values has each key. How can I use it to build those arrays?
Sorry if the question is a bit obvious, I think I'm missing something big here.
@chilly halo now with you
You want TOTAL sum of ALL entities values in to one number yes?
Like you have 10 entities in map and every entity has 3 numbers - collected apple, orange, fish. And you want sum of all food from all entities? (Just as example)
@storm ravine could you avoid the unnecessary pings please >.>
Is there a way to get a random number inside a parallel job? (Foreach.ScheduleParallel())
last i heard you have to create an array of randoms, one for each thread to avoid them producing the same value.
i am using Shared Static for that, and put a Random in there and use that in my bursted jobs
One of my systems has a performance of about 0.20 ms ( Processes about 100 entities )... is this a good ratio ?
It calculates the position each frame
{ return math.acos(math.dot(v1, v2) / (math.length(v1) * math.length(v2))); }```
The problem with that function is that if the angle should be 180Β°, it gives me 0
It gives me always positive values
It's like:
if(angle >= 180f)
angle -= 180f;
Lets say im still using gameobjects for the visuals of my game... those gameobjects do have colliders... how could i code a system for listening to collisions between those gameobjects ?
Yes it's how it works, because dot product
The problem with that function is that if the angle should be 180Β°, it gives me 0
@wide fibervar a = new float2(0,1); var b = new float2(0,-1); Debug.Log(a.AngleDegrees(b));where AngleDegrees is[MethodImpl(MethodImplOptions.AggressiveInlining)] public static float AngleDegrees(this float2 v1, float2 v2) { return math.degrees(v1.Angle(v2)); }
Maybe it's 180.5 that gives me 0.5 instead of 180.5
Yes that expected. Angle is always <= 180 here
Ah stop it should be not 0.5
it should be 179.5
It gave me 0.0197.. when it was at the opposite (so around 180Β°)
Probably the problem is another, I will check other systems
Angle works as expected
var b = new float2(0.01f,-1f);
var c = new float2(0, 1f);
var d = new float2(-0.01f, -1f);
Debug.Log(a.AngleDegrees(b));
Debug.Log(c.AngleDegrees(d));```
179 right side 179 left side
Yeah, it was a problem of execution order, sorry
Now I am doing another thing.
Basically now the projectiles that are shot from weapons are perfectly aligned with the weapon (I am setting the rotation to be equal to the weapon one) but I want to add an offset (based on the precision of the weapon)
How can I add an offset to the Z axis (in Euler) of a quaternion?
You want add scatter?
hello, is there a way to iterate over a NativeHashMap similar to how you can a dictionary. Just something like "foreach(var item in map.values)".
Like you have 10 entities in map and every entity has 3 numbers - collected apple, orange, fish. And you want sum of all food from all entities? (Just as example)
@storm ravine
Something like this...
NMHM a;
Entity e1;
Entity e2;
Entity e3;
a[e1] = [1,2,3,4,5]
a[e2] = [-1,1,-1,1]
a[e3] = [0,0,100,90,-50]
Inside the Job I need :
e1 -- 15
e2 -- 0
e3 -- 140
@storm ravine yes
good morning btw π
A random offset to the rotation of all the projectiles
@warped trail AFAIK that only works with <int,int>
ohπ€
does anyone know the difference between a multihashmap and a hashmap?π€
I tried with IJobNativeMultiHashMapVisitKeyValue but that executes one time for each VALUE, and I need the sum of all of them.
Just to clarify, I need to use the sum to modify a component but also to remove/add components depending on the final value.
does anyone know the difference between a multihashmap and a hashmap?π€
@thorny halo
HashMap= Dictionary <N,T>
MultiHashmap = Dictionary <N,T[]>
@chilly halo thanks
is there a way to iterate over NativeHashMap values in a job? I only see IJobNativeMultiHashMap interfaces.
@chilly halo there is IJobNativeMultiHashMapMergedSharedKeyIndices
@warped trail Deprecated. Only interface I mentioned above will continue exist (with mutable version)
Looks like its updated with the latest entities version π
@storm ravine Good to know about that, before I start beating my brain out to see how to implement that Interface
I have enough try to find a way to sum all ints in a NMHM in a parallel job.
Is this possible or am i barking up the wrong tree?
public struct ItemBlobAsset
{
public BlobArray<ItemBlobData> data;
public ref ItemBlobData getById(string id)
{
for (int i = 0; i < data.Length; i++)
{
if (data[i].name.Equals(id))
{
return ref data[i];
}
}
return ref default(ItemBlobData);
}
}
Looking for a way to grab items in a blob array by a FixedString ID, but I need to pass back a ref, and I need to have a catch for there not being a result
mmm i dont think compiler will let you return a ref default, it will require a valid field or ptr source
Yeah this is my issue. I'm thinking of adding a "null" item as 0 when creating the database and returning the data[0] and checking for that
yeah that might work!
i've used a workaround like this before
public ref struct TryResult<T> where T : struct
{
public bool HasValue;
internal void* Ptr;
public ref T Value => ref UnsafeUtilityEx.AsRef<T>(Ptr);
}
or i could be more verbose and have it look for the index, and then just sue that, but both would be mroe painful
I saw something similar when looking up the issue, though i wasn't sure if they would play well with Blobs
blobs have been doing some unexpected things that's for sure.
Well they let me store meshes so they let me be lazy :p
try this
public struct ItemBlobAsset
{
public BlobArray<ItemBlobData> data;
public unsafe TryResult<ItemBlobData> getById(string id)
{
for (int i = 0; i < data.Length; i++)
{
if (data[i].name.Equals(id))
{
return new TryResult<ItemBlobData>
{
Ptr = (byte*)data.GetUnsafePtr() + i * UnsafeUtility.SizeOf<ItemBlobData>()
};
}
}
return default;
}
}
public unsafe ref struct TryResult<T> where T : struct
{
public bool HasValue;
internal void* Ptr;
public ref T Value => ref UnsafeUtilityEx.AsRef<T>(Ptr);
}
Would the Value and HasValue not also need to be set there?
And would it not be cleaner to just have a TryResult that contains only a ref to a ItemBlobData and a HasValue?
mmm yeah you would want to set HasValue, so you can know not to call the exploding value
i dont think you can store a ref as a struct field, even in a ref struct, they only let u do that with Span<T>
Yeah i just gave that a try and it didn;t like it
Seems to work, though as per usual with me I cower at the use of "unsafe"
And for some reason it's having a hissy fit over this way of getting the name and casting it to string as opposed to when referencing the data index by its int id
this data[i].name.Equals(id) ? or something else
nvm im being stupid
there's also FixedString.Format("The entity is {0}{1}", entity.Version, entity.Index) if its useful for embedding strings in jobs, but only seems to work if its directly in the job root.
my issue was just with the search query string not the result, because jobs are a dick and strings are apparently the devil even when coming from outside the job
As for some reason a FixedString32 inside a blob referenced inside a job is fine to use ToString but a FixedString32 just inside the job can't use ToString
ToString method returns string tho, which is a class hence managed
Hey, so I'm trying to make my noise generation code multithreaded but it for some reason generates some strange looking lines
code here https://pastebin.com/RFaHA59H
im not sure if this is the right place to ask but, if i understand this right, if you use unity pro at all, and make a game using the Havok physics engine library, which you pay for (200 anual) and ship your game out as a standalone exe, and decide to cancel the license, the way Havok license reads is you must also remove all copies of your game featuring it too right?
i think you should ask this question to DOTS/Physics forum, havoc people is there answering stuff
maxNoiseHeight is set to float.minValue and minNoiseHeight is set to float.maxValue
hmm, do I need to dispose arrays from ArchetypeChunk.GetNativeArray myself or ?
im almost certain the problem is from me setting the minNoiseHeight and maxNoiseHeight in each execute
but not sure how to solve it
i never did anything to do with noise but perhaps something about "x" variable ?
perhaps there is something weird going on with modulo and division
maybe, though the lines are only caused by the InverseLerp
and without the lerp it looks like this
ah okay, something about lerping then
yeah, I think the minNoiseHeight and maxNoiseHeight variables are the problem but not sure
because the lerp did work without this job version
do those variables reset back to what they were after one Execute?
nvm it seems they dont
hmm, do I need to dispose arrays from
ArchetypeChunk.GetNativeArraymyself or ?
@zinc plinth no. Because this is direct reference to chunk memory, this is why you can change values in array and they immediately applied to chunk.
hooo ok
cant figure this out at all
@odd cipher you're setting the min and max inside of a job and not waiting on it, so it's updated over the course of the entire run of the job over the array. You would need to split it so you've recalculated the min-max over the entire texture before you start using them
because right now what you're seeing is how the job is executing
well im not using those variables afterwards, only changed in the job
should you perhaps be having the min-max variables local to the function, and not the job?
well they are needed for the job, and only used in the job
not sure what youre suggesting
He mean
That one Execute sets value and other execute calls use that value
instead of initial float.Max\Min
And because it's parallel
every execute get random min\max which was set from one of other Executes
Simple example - you set initial value 0 and expect that it will be 0 for every execute, but it wouldn't.
Reason for that is how job collect data for executes. Under hood it just get IntPtr (through JobScheduleParameters from your job data void* pointer (which in turn get by simple AddressOf) ) to your initial struct which as result shared across all executes.
it shouldnt be reset though, the original code that worked didnt do that.
the new set value should be carried on to the next execute
this is the original code https://pastebin.com/NYD3k09t
Yeah, I guess I'm just having a hard time wrapping my head around this
or how to fix it, I have a pretty poor understanding on how this noise generation works in the first place
I feel like it should work but it just doesnt
@storm ravine do you mean that the order of execution is random and therefore creating these weird lines?
Yes
Because all Execute runs in parallel
Mathf.InverseLerp(minNoiseHeight, maxNoiseHeight, output[index]); this part produces unexpected result because of random minNoiseHeight\maxNoiseHeight overwritten by other Executes
gotcha
Why you tying do that parallel? And not just main threaded\single threaded with burst. Which size of your map will be?
So, should I just do a IJobFor instead of IJobParallelFor?
Seems you trying noise generation implementation by Sebastian Lague. It runs on main thread fine (not the best but fine) Just use single bursted IJob \ Job.WithCode
IJobFor is same as IJobParallelFor but with two implementations of Schedule - all Execute runs sequentially on worker thread and ScheduleParallel - same as IJobParallelFor Schedule - batch size per thread
Yeah, a IJob works just fine
is there a way to do something like this but Burst compatible? System.Random prng = new System.Random(settings.seed);
Yeah, that works
6 milliseconds out of 26 is now gone with this new method, only took like 5 hours to figure out :p Thank you
That sounds pretty heavy for perlin
Because of big octaves count and world size definitely
Well you can parallelize that.
Is the link above the code you run in the jobs?
no I mean, 20 milliseconds for the noise and terrain generation with noise AND setting each pixel corresponding on what terrain
Yeah that sounds very long
I interested in noise part only
well I dont know what the best way would be to time a multithreaded piece of code
Well for test
im currently using a System Stopwatch
return parallel schedulind
64 batch size
comment inverse part and if (noiseHeight > maxNoiseHeight) { maxNoiseHeight = noiseHeight; } else if (noiseHeight < minNoiseHeight) { minNoiseHeight = noiseHeight; }
@odd cipher even for single threads, this quite high
noise generation time takes 0-1 millseconds
float2 sample = new float2((x - worldSize.x / 2) / settings.scale * frequency + octaveOffsets[i].x, (y - worldSize.y / 2) / settings.scale * frequency + octaveOffsets[i].y); A lot of this is duplicated work every octave iteration
You are also iteration in columns, instead of rows,.
noiseHeight += perlinValue * amplitude; This can be replaced with an math.madd intrinsic
noiseMap[x,y] = noiseHeight;
noiseMap[x,y] = Mathf.InverseLerp(minNoiseHeight, maxNoiseHeight, noiseMap[x,y]);
Yeap rows first, for reducing false sharing
This stores a value, only the read it again for a transformation.. and overwrite it?
He is doesn't need that inversion here tbh
I mean the whole thing takes 1 millisecond
It can be faster with suggestions above
The code for updating min and max could likely be replaced with some nice simd select methods
The focus is to have as your octaves look be as few cycles as possible, and the writes afterwards to be sequentian
min\max can be dropped here completely π
float2 point = new float2(x,y);
float2 sample = (point - worldSize / 2) / settings.scale * frequency + octaveOffsets[i]);
You might have to ensure that scale and frequency are also float2
Note that you can move worldSize / 2 outside of the octaves loop as well
Hell, the whole thing can move out, except for the * octaveOffsets[i])
You could probably rewrite the PerlinNoise function as well using the new mathematics package, in a much faster method
doesnt seem to work the same
Ah sorry, I swapped a + for a *
ah yeah that fixed it
Hell, the whole thing can move out, except for the
* octaveOffsets[i])
@stiff skiff not only.frequencynot fixed
this is how it looks like right now, with burst https://pastebin.com/dgPqTcGH
reorder for loops, rows first
is that faster?
(point - worldSize / 2) / settings.scale move out of octaves loop
is that faster?
@odd cipher yes, because of false sharing
when x loop first you going through array not linearly
And processor cache refill cache lines every time
when rows first you use cache lines effectively
@storm ravine I think it works atm because they are using the [x,y] method of storing
This will break once you move to a single NativeArray<float>(Width * Height)
and not get new values every time but rarely, because they already in cache
@storm ravine I think it works atm because they are using the [x,y] method of storing
@stiff skiff you mean float2 implementation here which used in his array?
@odd cipher Looks good, but do swap the x and y loops
I only just saw your burst job link π sorry bit behind
@odd cipher I wonder if it might be faster to move the checks for min and max noise outside of the loops
So instead of doing them for every pixel. You do a loop over the output array at the end and update the min and max. Should unroll the loop and SIMD it
Just remove them. They can be dropped here without any problem.
Though I'm not sure how smart burst is at doing this
well I need some alternative to doing the same thing those two variables are doing
after dropping that he can easily parallelize that
unwrap XY loop and just calculate octaves part
ill have to continue tomorrow its 2:30 am and I have to get some sleep :p
π
no sleep, only coding π
What's the proper way to use an enum with IComponentData? I tried this:
https://pastebin.com/rnjCU3pJ
But I'm not sure how to actually set the tileType variable
@nimble reef ? (I haven't understood the problem, do you want to make it show up in the inspector?)
No, I just want to set each entity's TileComponent's tileType to some value from that enum
Also, how would I find a specific entity once they've all been created? Like if I want to update one of them
I think maybe I'm misunderstanding what ECS can/cannot do. But that's what I'm trying to learn here. I'm basically trying to represent the grid in a 2d game via ECS, so I thought I'd make each tile in the grid an entity
that is doable, you just get Entity reference somehow
but it all depends on how you struct your stuff
i am guessing each tile has 2 ints, x and y positions, you could put all the grid entities to a buffer, and select the grid entity you want from that buffer
i am not sure what to say about tile Type, you just simply set it, like
new TileComponent{tileType = yourEnum}
@stiff skiff how would you suggest getting rid of the min/max variables?
hey im looking at the docs and i dont understand, because it doesnt say, and the samples are confusing to me, but this isn't working at all:
entityManager = new EntityManager();
Entity _newEntity = entityManager.CreateEntity();
it throws a NullReferenceException error
every world has their own Entity Manager, you have to access world's entity manager
World.DefaultInitializationWorldSomethingSomething.EntityManager
How do I actually install DOTS in Unity 2020?
ok let me fix my code and i'll see if it works
I can't see it in the list of packages, and the "show experimental packages" option is gone from the advanced settings in the package manager
I'm on the latest alpha, 2020.2.0a9
show experimental packages escaped to Project Settings->PackageManager
Ah, goodies. Thanks!
Any update on Physics Event handling? I want to receive the OnTrigger "event" without making an IJobIDontRememberTheName. But using SystemBase
nah, we dont have those right now, maybe they will integrate to ForEach one day
i mean you can still call it in SystemBase, you just make the job thats all, instead of ForEAch
why isnt my Entity debugger seeing my entities
my list shows they are there, but the debugger doesnt see them
Entity _newEntity = entityManager.CreateEntity();
managerEntityList.Add(_newEntity);
that works, but it doesnt see them in the Entity Debugger
oh nevermind i figured it out...
Is there any good way for two systems to add entity references to a dynamicBuffer from created entities with commandBuffer?
you have to create a workaround, since entity that is returned from commandBuffer isnt viable yet
my workaround is this, i put a RegisterComponent to new entity and put 'parent' entity in it, i have a system that queries for RegisterComponent and child adds itself to parent and then delete the RegisterComponent
Hi π Quick question: I've created an entity that has been converted from a prefab (so it already has a physics body component on it), but I need to only update ONE aspect (linear velocity) of the component. If I use setComponentData, will the component be replaced? In other words, will I have to supply all the other configurations that I did on the prefab (gravity etc) just to set the linear velocity?
how would you suggest getting rid of the min/max variables?
@odd cipher I guess itβs question to me? π
Just remove them and inversion. Use amplitude for reducing βwhole blackβ
@gusty comet Yes, the data of the component will be replaced with what you supply. So if you somehow was able to add angular velocity in your authoring it would be set to what you send in when you send in your linear velocty by SetComponent with PhysicsVelocity component.
@mystic mountain OK, thanks! π
@mystic mountain actually, I realized my mistake - I thought while I wrote the question that there was a 1-to-1 mapping between physics body and the component I needed to update, but since I only need to update the "PhysicsVelocity" component it's not that big of a deal π
@storm ravine So instead of InverseLerp I use amplitude somehow?
Hey, I just came across something counter-intuitive. If I call
localToWorld.Rotation, I would expect to get a quaternion that considers only the rotation of the object. Instead,localToWorld.Rotationalso considers the Scale of the object. I would consider this a bug, but am I misunderstanding something here?
For instance, two objects with Scale 0.1 and Scale 1:
And for completeness:
public class DebugRotationSystem : SystemBase
{
protected override void OnUpdate()
{
Entities.ForEach(
(ref LocalToWorld localToWorld) =>
{
Debug.Log(string.Format("localToWorld.Rotation={0}", localToWorld.Rotation));
}).WithoutBurst().Schedule();
}
}
(Should probably add using Entities 0.9.1)
@last jasper If I'm not really bad at my maths here. LocalToWorld.rotation is be the full rotation, scale is not part of it, from local space to world space. I.e. if you have it nested, it will be the full rotation to world space, equivilent to transform.rotation in the old system.
yup, that's what I expected. Instead, localToWorld.Rotation is affected by the Scale. The two entities in the above example are not nested for simplicity, but still show this behaviour.
Really can't tell from the images what you have done wrong.
Me neither π
You will need to show the full hierarchy or setup.
Sure, I'll make a forum post
If you simply do some wolfram alpha of your quaternions you'll see that your first rotation is something like 10-20 degrees
yeah
that's exactly the point though, both have the same rotation
but localToWorld.Rotation returns a different quaternion for both of them
sorry for slow reply, I'm trying to add a bit more detail for the forum post π
here is the post https://forum.unity.com/threads/localtoworld-rotation-affected-by-entity-scale.882133/
You can see that Rotation is the same for both entities, neither has a parent, both are at the origin, but LocalToWorld.Rotation returns different quaternions. The only thing different between them is Scale
What's the current best point of reference for pure DOTS design?
I've been looking at documentation and samples, and it's all a jumble.
I'm most interested in pure ECS, I can't say I like the idea of mixing GameObjects and Monobehaviours in, but if that's the intended workflow then I suppose I can hold my nose and cope.
What I really wonder about is really architecture. I'm sure I can get a few thousand cubes bouncing around on the screen, but that's not really going to help me understand how I'm supposed to handle stuff like input from multiple players, game sessions, asset pipelines and yada-yada
Am I asking a question with no real answer yet? Are batteries definitely not included?
What's the best point of reference for pure Monobehaviour design? π - you're right though, resources are thin on the ground. DOTS samples are partially supposed to be fulfilling this role but often criticized for their scope.
It's a tough one. I currently have a single mono behavior to handle loading the entities and storing an array of location data for all Systems to reference for collision
The best point of reference for monobehaviour design is don't but I get your point
Yeah, ok, so I should expect to use Monobehaviours to orchestrate the ECS
My current preferred development practice is to just use a single Monobehaviour to send update signals and deltatime into my own stack, so the idea sounds just dandy to me
Yea I do something like this for now:
GameObject->Pure is the workflow that's here to stay, at least for the next n years. If you're interested in getting as pure as you can, Tiny is where it's at.
Main.cs is the only Monobehavior
@dawn badge What do you use for collisions?
It's 2D so I just do a simple cast:
private static bool isColliding(float aX, float aY, float bX, float bY) {
var radius = 1f;
var deltaX = aX - bX;
var deltaY = aY - bY;
return ((deltaX * deltaX) + (deltaY * deltaY)) <= (radius * radius);
}
that's in my CollisionSystem
ah, right
I got my own very simple SAT-based collision system written using the new maths lib that I was hoooooping to use
I expose the "grid" from Main via a static method
and meshes/materials..not sure it's great but it works
Right, so you just load in materials and meshes and keep them in the Main, then whoever needs them looks them up from there?
So before you start your big rendering foreach in each rendering system, you just fetch the mesh and material references from Main and ta-da?
Wait, so you have arrays with IDs aligned with the rendering components so you can slice into them?
Yea I just call Graphics.DrawMesh( after pulling the meshes with Ioe.Main.GetPlayerMesh() and Ioe.Main.GetPlayerMaterial()
exactly so while my Entities.ForEach filters I can still ForEach through my LocationData and update the correct Ids
Can you actually call Graphics.DrawMesh from a big parallel foreach?
Ok, so it's a single-thread burst job
It's a raw compsystem but it runs after a burst job
so take your wins where you can π
the job sets up everything, then the compsystem that depends on the job brrrrrrs through?
yep!
Is that your general architecture? Jobs prep data for a compsystem that goes brrrrr?
And the dependencies decide order of execution?
[UpdateAfter(typeof(SomeScheduledSystem))]
"beautiful"
The UpdateAfter is a life saver
you can really orchestrate to optimize where possible
unity: c++ is bad we don't want users to deal with all that shit
also unity: haha we made c# into games-oriented erlang
haha well if you ever did erlang/elixir it's not terrible in comparisson. Similar to GenServers (mentally) just not purely sync which is nice
this is how I am learning C# and Unity and I am not having too hard a time
I'm unfortunately from extremely imperative side of things
the docs need work though..like relying on intellisense and source definitions is pretty raw
Is there any material on how using Adressables with DOTS yet?
@dawn badge I noticed. Good to hear that it doesn't have to be tremendously complicated.
So thanks! That sorta allayed my fears a bit.
Isn't there a conversion script for that? I saw some people just telling Unity to convert to entity?
@outer swift yea it's doable! just be ready to yell at clouds π
my yellinator is set to cloud
Fortunately decided to clone an easy game for practice
Gonna clone myself some Every Extend: https://www.youtube.com/watch?v=bWrCwZFro40
Every Extend is a unique little... shooter I guess you'd call it. Very short, but addictive and replayable, it uses an original concept and pokes fun at Ikaruga along the way :D
The premise is this: You can only attack by self-destructing. Each self destruct takes one life ...
Looks like a great candidate for ECS
Is there any material on how using Adressables with DOTS yet?
@mystic mountain not yet. Subscenes + addressables will be first step on unity near plan. Currently we use addressables with dots without problem. At app start loading all required stuff asynchronous, convert and store maps on entities (note: we use own persistent unique id for every resource, for excluding references to unity internal solutions and serialization which breaks from time to time)
Is there a way to access the shared component of a random entity inside an IJobChunk?
I'm doing the CombatBees ECS project, and need to see if 'this' bees target resource is held by a bee on the other team, and I store teams in SharedComponents. Open to change the use of SharedComponents of anyone has any other ideas.
To rephrase, the problem is essentially: I have an entity, which targets another entity, I need to know the SharedComponent of the other entity.
Is there a way to access the shared component of a random entity inside an IJobChunk?
I'm doing the CombatBees ECS project, and need to see if 'this' bees target resource is held by a bee on the other team, and I store teams in SharedComponents. Open to change the use of SharedComponents of anyone has any other ideas.
@gentle osprey Not directly. You can only get SCD index, because itself they not stored in chunk, chunk only store index to unique SCD in global map
The SCD index is the same for all entities with the same shared component though? So, in this case I would only need to see if the other entities SCD is different from "mine".
@storm ravine So you wait with the whole conversion before you've loaded all stuff?
@mystic mountain well that content local and load fast in our case. And it loads at app start right in intro scene with copyrights etc. π
The SCD index is the same for all entities with the same shared component though? So, in this case I would only need to see if the other entities SCD is different from "mine".
@gentle osprey Yes
But there's no easy ways to get access to the SCD index of a random entity? Like, there's no SharedComponentDataIndexFromEntity or similar?
@storm ravine I see, what I want to do is load stuff based on map loaded and what other clients who joins map has chosen as visuals. π€ I've not gotten my hands dirty with adressables yet, so not sure if I should just wait for their solution to show up.
Well addressables part itself async, thus wouldn't stall main thread and can be wrapped in to nice loading π
Conversion pretty fast, but you should convert batches, not one by one which inefficient. One of ways create hidden GO when every thing loaded, pass GO prefabs to that GO and using declare reference prefabs add them to conversion list and convert to entity in Convert, and store references to prefabs where you need. Or if don't need prefabs and just immediately instantiate content workflow will be similar, just without that utility GO.
But there's no easy ways to get access to the SCD index of a random entity? Like, there's no SharedComponentDataIndexFromEntity or similar?
@gentle osprey you can get SCD index on main thread by EntityManager and use that, or you can GetSharedComponentIndex from chunk to which entity belong
a word of warning on that, runtime conversion is not going to be supported according to topher; the answer to all my issues was pretty much 'don't do it`. Conversions with IConvertGameObjectToEntity within a SubScene are fine, but hes talking about instantiating a go, and triggering a conversion at runtime.
For example i had an issue where i instantiate a GO at runtime, it converts and tries to create Entity prefabs based on referenced assets, but in the case of parent/child conversions, there's no guarantee that parents will have been converted before their children which for me broke everything. The process worked in earlier versions of Entities but it broke when they refactored to include assets other than GOs in conversion.
It seems that the intention now is to use Addressables to pull in an entire SubScene (a pre-converted blob of stuff that gets shoved right into the world).
So I will need a subscene for each asset? π€
no the subscene would contain all your entity prefabs, already converted.
Parent\child conversion works without problems, but you'll get result only on next frame, before that you only operate "hierarchy" through LinkedEntityGroup
@mint iron Hmm right,.. but how would you go about; have a wide range of characters and only load the ones that are used? Would you chunk them into subsets and make subscenes of them?
For example after instantiation I want to get some things from child parts of complex prefabs, I use LinkedEntityGroup for that, because it's already here after GameObjectExportGroup run
that's a good question; i haven't gotten that far yet; i gave up and went onto other things after being told it wasn't going to be supported.
afaik the ultimate plan is to kill convert & inject, ultimately everything will be scene conversion or conversion system
https://discordapp.com/channels/489222168727519232/497874303463850004/686924098730983426
After the game loads that prefab is instantiated, the conversion script
Runtime conversion is not supported
And not something we want to support
https://discordapp.com/channels/489222168727519232/497874303463850004/689161934616133644
https://discordapp.com/channels/489222168727519232/497874303463850004/686924098730983426
https://discordapp.com/channels/489222168727519232/497874303463850004/689161934616133644
@mint iron conversion system IS runtime conversion. Convert and inject is will deprecated part.
Conversion system is how Convert to entity processed π convert and inject just temporary dirty hack π
i think hes referring to anything that's not pre-converted
He speak about hybrid workflow
conversion system supposed to run at editor time only?
thats what it seems like he was saying, that conversion system/world would eventually not even exist at runtime. you can of course make your own to do that same thing, but they dont want to support it, is what i took away.
Only about convert and inject part
Iβll ask Fabrice
He is working on that part of dots
okay well then his response to me was irrelevent, i would have the same issue with convert+inject as with a conversion system, becuse its a flaw in the underlying systems.
For clarifying and excluding βguessingβ π
please, some clarity there would be great
Yep. Until that, just my thoughts:
Runtime conversion
I mean pure convert to entity should be anyway π subscenes for everything not cover that.
Simple example is some procedural things
You definitely wouldnβt have all variations of things π
Yes you can predefine some parts and use subscenes
@storm ravine do you use shared components or chunk components in your project?
But IMO convert some things at runtime (not hybrid GOβs) will be here long time π
@storm ravine do you use shared components or chunk components in your project?
@vagrant surge yes, SCD for filtering
Chunk component in todo list for some things π
But not yet, it will be on pre release and final optimisations
This is probably a dumb C# question rather than a Blob one but, any reason why I'd get the following error when trying to use BlobBuilderArrray as a variable in a custom delegate?
The type 'BlobBuilderArray<T>' may not be used as a type argument
BlobBuilderArray is a ref struct https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/struct#ref-struct
Damn well that ideas downt he drain
As far as im aware there would not be a way to do this then
public class DatabaseBLobAssetConstructor<T> where T : struct, IDatabaseitem
{
public BlobAssetReference<DatabaseBlobAsset<T>> reference;
public DatabaseBLobAssetConstructor(List<T> rawData, AssetConversionAction<BlobBuilder, BlobBuilderArray<T>> dataConversion)
{
BlobBuilder blobBuilder = new BlobBuilder(Allocator.Temp);
ref DatabaseBlobAsset<T> itemBlobAsset = ref blobBuilder.ConstructRoot<DatabaseBlobAsset<T>>();
BlobBuilderArray<T> data = blobBuilder.Allocate(ref itemBlobAsset.data, rawData.Count);
dataConversion(ref blobBuilder, ref data);
reference = blobBuilder.CreateBlobAssetReference<DatabaseBlobAsset<T>>(Allocator.Persistent);
blobBuilder.Dispose();
}
}
AssetConversionAction being my delegate
where does dataConversion come from
what about this
public interface IDatabaseBuilder<T> where T : struct, IDatabaseitem
{
void Build(ref BlobBuilder blobBuilder, ref BlobBuilderArray<T> builderArray);
}
public class DatabaseBLobAssetConstructor<TBuilder, TItem>
where TBuilder : struct, IDatabaseBuilder<TItem>
where TItem : struct, IDatabaseitem
{
public BlobAssetReference<DatabaseBlobAsset<TItem>> reference;
public DatabaseBLobAssetConstructor(TBuilder builder, List<TItem> rawData)
{
BlobBuilder blobBuilder = new BlobBuilder(Allocator.Temp);
ref DatabaseBlobAsset<TItem> itemBlobAsset = ref blobBuilder.ConstructRoot<DatabaseBlobAsset<TItem>>();
BlobBuilderArray<TItem> data = blobBuilder.Allocate(ref itemBlobAsset.data, rawData.Count);
builder.Build(ref blobBuilder, ref data);
reference = blobBuilder.CreateBlobAssetReference<DatabaseBlobAsset<TItem>>(Allocator.Persistent);
blobBuilder.Dispose();
}
}
or
public class DatabaseBLobAssetConstructor<TItem> where TItem : struct, IDatabaseitem
{
public BlobAssetReference<DatabaseBlobAsset<TItem>> reference;
public void Build<TBuilder>(TBuilder builder, List<TItem> rawData) where TBuilder : struct, IDatabaseBuilder<TItem>
{
BlobBuilder blobBuilder = new BlobBuilder(Allocator.Temp);
ref DatabaseBlobAsset<TItem> itemBlobAsset = ref blobBuilder.ConstructRoot<DatabaseBlobAsset<TItem>>();
BlobBuilderArray<TItem> data = blobBuilder.Allocate(ref itemBlobAsset.data, rawData.Count);
builder.Build(ref blobBuilder, ref data);
reference = blobBuilder.CreateBlobAssetReference<DatabaseBlobAsset<TItem>>(Allocator.Persistent);
blobBuilder.Dispose();
}
}
Hummm that might indeed work, even looking at it is confusing me somewhat so I'd not have come up with doing it that way for sure.
The first one looks very...
"This thing is doing more things than one"
The second one looks more readable.
I'm using the second to be fair, i am having to rewrite a chunk as i have two types floating around being converted between in IDatabaseBuilder.Build
but it looks like it should work, and cut out a massive amount of copy and pasting
More than my fix i mean, which was to just use the rest of my templating but have a new Constructor class for each type i needed to convert
Well it could give you some customization if you needed it
But if you don't, then yea, waste of time
That's true, but i can always do both
for ones that just need a conversion script I can use this method and for anything more in-depth just do it the old way
"Always future proof your code, but never try to be too smart" is how I like to look at that π
Being smart is what we have xzjv for
outsourcing, working smart not hard
And if for some reason they're sleeping, which doesn't seem to ever happen, Eizenhorn exists π
But then you have to understand a level higher than your own
Could be harder
π
That is why I am currently resisting the urge to day drink while trying to wrap my head around this while expanding it.
There is that point though
Where the alcohol makes you the genius programmer
galaxy brain
I'm in that lovely grey area of having 24 years coding experience but very little high end C#
I was taught to code realllly young as my dad was a BT engineer and saw it being useful
How old are you though?
32
Ah okay.
whats BT?
British Telecom
i see
I guess starting at 8 is not so bad
In order to understand Blob assets fully and memory management in DOTs i think he needed to have started a few years earlier
Well
Understanding the fundamentals is fairly easy...a bunch of arrays of numbers
But the hard part
Is to understand how to use it to your advantage
For example using 1D arrays to store different kinds of data is completely legitimate. Something other languages are shunned for (like Lua and JavaScript)
Difference is you represent by numbers rather than objects π
Isn't a blob just an arbitrary container of data?
Pretty much yeah, just cotnainers for immutable data accessed via reference
And until someone corrects me I'll pretend I'm right
Lol
whatever works in your head
We all go by this @loud matrix so you're fine:
haha 100%
I personally find i program in eldrich runes. The issue is once the code is written no mortal man can decipher the madness within.
We have comments for that
directories and apt naming are good as well
"If it was made by a human, it means we can analyse and understand it"
- Zelda, Breath of the Wild
π
all systems go in the systems dir
all components go in a components dir
all archetypes go in an archetype dir
trust me it helps
namespaces help too..
I started that way, then had to go with contextual folders
as grouping all movement components and systems together just made it so much easier to find
final project
_final project private
final project (1)
final project 2
Master Project
master project (2)
that is interesting
so domain related?
Player
Systems
Components
FirstLevelBoss
Systems
Components
What about shared systems/things?
In a shared dir?
More general than that for mine
Scripts
Camera
Debugsystem
FollowSystem
TargetEntity
TagMainCamera
Movement
Dampingssytem
PlayerCiontrolSystem
Throttle
Velocity
VelocitySystem
ah gotcha
so camera is camera only stuff, but movement is player and emery related
yea I guess it's just standard with Unity
The only folder that has to be the way it is would be "Assets"
That's it
The rest of the folders in your "Assets" is free game
Editor is one other exception I think
Because the editor looks in that specifically for editor extensions
huh
Don't know if Resources is still necessary to use? It might be
Resources is another special folder that you can use with the Resources loading system in Unity
But it's not like you can't put other things in there too
It's typically a nice place to dump things that can be modded by players
Yea currently in my small project I have
Ioe (master) $ find Assets/Scripts -type f -name '*.cs' | grep -v .meta
Assets/Scripts/EntityBuilders/EnemyEntityBuilder.cs
Assets/Scripts/EntityBuilders/PlayerEntityBuilder.cs
Assets/Scripts/Archetypes/EnemyArchetype.cs
Assets/Scripts/Archetypes/PlayerArchetype.cs
Assets/Scripts/Components/EnemyComponent.cs
Assets/Scripts/Components/PlayerComponent.cs
Assets/Scripts/Main.cs
Assets/Scripts/Systems/EnemyMoveSystem.cs
Assets/Scripts/Systems/PlayerRenderingSystem.cs
Assets/Scripts/Systems/EnemyRenderingSystem.cs
Assets/Scripts/Systems/CollisionSystem.cs
Assets/Scripts/Systems/EnemyAnimationSystem.cs
Assets/Scripts/Systems/PlayerAnimationSystem.cs
Assets/Scripts/Systems/PlayerInputSystem.cs
You use cmd for git?
hopefully it is maintainable..
I am on Mac, but yea I use cmdline for as much as possible
Often ask myself if I can make my structure better x)
ahh well you have a Client and Server!
nice
Oh I use git a lot at work. So UI won't let me cherry pick from a specific branch into a release branch and rebase from a certain point in history
Didn't have a choice lol
I tend to find that all you need to do is have tight namespace organisation. Make sure your namespaces make sense and then make sure to use them properly. If something doesn't fit in a namespace you made, expand it and make sure to move everything in there that now fits it, rather than sorta fits another namespace you did.
@dawn badge Er
I do that in Gitkraken all the time
GUI based tool
And I can almost assure you that a lot of other GUIs also support what you just said
Reason I like ECS, less GUI more code/control haha
cherrypicking
Sure more control, I guess, but also make sure to support the design driven setup that Unity has. Ideally a programmer should make things that designers requests and then sit back and chill or fix bugs.
Help them to help themselves
Glad you like UIs. I can't use them very well for spatial things like Git
Oh I just do this on the side. Learning to make art, I already make music and code. This is what I am trying to do in my free time
"I can't use them very well for spatial things like Git"
Could you elaborate on what this means?
It means GUIs do things you don't 100% know all the time. If I am merging branches from separate remotes and rebasing I don't want to click the wrong button. If the mental model doesn't match the UI I get stuck. I have full control via CLI and can automate to my liking if need be.
hmkay
But yea anyways @mystic mountain your structure seems good
At the end of the day, if you are working on something alone and it makes sense go for it. If you are working on a team, document standards to explain the pattern(s)
I present to you why GIT should only ever be used in GUI form when working in a team
Yeah, that's a nice overview
That's not even the worse we'd had recently
When the language branches come in all hell breaks loose
If everything is a squash merge and master is protected nothing is complicated
but not every team can do 100% trunk based so I get it
I always end up just working on Master for my own work, I bounce back and forth on ideas and systems too frequently to do it properly :p
yea for local work master mostly, then branch if I know it's sketchy haha
but in teams master can only be merged into
That's what i use stashes for, but Unity seems to have a hissy fit when I stash sometimes and decided it needs to change my package versions.
In teams you should always have a git master who is the only one who can merge into master
Only stash while working in your GUI. As soon as you are done with it, pop
And go back in and work
ah stash and unity aren't friends? interesting
oh right..everything has to be generated
Yes
And some times Unity generates after a push
So you get new "changes" (which are non-changes)
And then you have to push meta files that Unity believes it changed
Even if you can compare to last push and see no changes
But Unity will damn keep on believing it did
it feels dirty to push meta files
Yea, but you gotta
but it is what it is I guess..
I don't have issue with meta files
gets nam-like flashbacks with git and meta files
Some scene and project setting stuffs do randomly add missing props though.
What are the meta file changes you are seeing?
Here is a scenario I've experienced a couple of times:
- Do changes in scene. This affects meta files.
- Save the scene and everything in it.
- Go to Git client and commit/push
- Go back into Unity.
- Unity now claims to have made changes to other meta files (or the files you just pushed)
And so you have to save and push again
This is a very common issue
this is perfect use case for git commit --amend assuming you are not on master because it alters history if you have already pushed
but it sounds like a PITA
Problem is you don;t find out until you've done different work
I like pita
oh.. it does it "later"
Yes.
amazing π
π€
Maybe it's just me but I don't have that issue doing exactly what you described.
so your metas in git just get messed up into a knot of what commit they actually belong to. A good use case for Pure ECS though 
And then you get the perpetual .meta commit
It's a type of commit where it keeps telling you that something went missing from a previous commit, so it deletes a meta file. Okay you think, I'll push that. No problem.
You push it, and it shows up again the next time someone makes a push.
It's so infuriating
That would be like having a single code file
It would be better if meta files are not necessary at all
yes that too lol
I remember hearing this as a reason for people moving to GODOT a while back (Well that and pixel precision in 2D)
GoDot has much less "keeping track" files, but still has some. Wish it had native ECS but Vulkan is the focus for 4.0
I guess with ECS I don't get many meta changes
ehh managing the threads?
It is a paradigm, still
That's Job system, has nothing to do with ECS.
A programming paradigm
right but DOTS is nice because it handles a lot for you
Screw it, guys, I have a solution!
brust compiling, job systems, etc..
FLASH!
FLASH!?
Sure, so you wish that Godot had DOTS
yea exactly lol or something similar
Action Script 1, never had these issues back in the day!
Lol
Sure we didn't have version control, but who cares π
ActionScript π€£
Let me go grab my floppy disc 3.5 grandpa
Then you can transfer the code to me
you should make a game in DOTS that lets you write actionscript flash games?
like roblox? but worse? haha
pifft, 8" floppies were where its at
Now if you'll excuse me I need to find my 15 separate Ultima Underworld install floppies.
You need a floppy reader too
Got a USB one
That's cheating man
I've not had a PC case with bay slots in years
Yeah, adds to the challenge
I wonder, can i get a IDE to SATA2 converter
I think this may have been the most off topic this channel has ever managed to get
From my terrible programming, to folder structure, to unity meta issues to floppy disks
slow day at DOTS
yep
@mint iron Well, Joachim answered to me before Fabrice, great thanks to him for that (and whole DOTS team, they really kind and very responsive and helpful) π He don't know if they will deprecate runtime conversion, which confirms what I heard, that only Convert and Inject will be deprecated definitely but not Convert To Entity. But of course general recommendation is use subscenes everywhere if that possible, because off size & memory cost at runtime (which expected of course, with runtime conversion you of course keep everything in memory all the time, where with subscenes you can simply unload things until you need that again). And relates to that we decided use convert to entity with our workflow with Addressables now π But when they will add native support (and they will as they mentioned) we will compare, worth it for us - drop our solution or not π
they do recommend to use subscenes but they still are the most broken part on the dots ecosystem π
awesome, thank you for chasing that up.
like, they work alone, but not that well with other dots packages
also hybrid setup is pain with subscenes as you can't just place cross scene refs even
in the future, definitely
I try them every now and them and after banging my head to the wall for some hours I always give up π
dots physics for one
but latest unity physics does work already better
in past the joints went all bonkers, then some other physics scripts (which I suppose were due to the way they were setup but at the same time, they were directly from ECS sample repo)
joints seemed to work on latest versions btw
but ultimately, going to subscenes makes non-hybrid rendering pain
and currently hybrid rendering v2 isn't faster on typical game scenes
(than old GO rendering)
yeah, I'm aware of the dark days ahead π
well, if you use it like it's supposed to be used, I guess it's not harder
but if you need the old renderer, you'd need to have some way to sync entities to GO transforms and subscenes make it pain
there are ways around it, but it's dirty
I basically just need the GO transform for the entities so can sync them efficiently on jobs
convert and destroy atm but inject would work too if the rendered GO would be on the same object
I'm basically using modified version of the old GameObjectEntity's transform syncing
I just set the transform to different GO, basically I have GO for dots conversion and separate GO for rendering and and animations etc, on conversion I assign the visual GO's transform to the entity that get's converted
it's a messy setup but it lets me get fully functional rendering and old animations
I guess, I've thought about the spawning too as it's going to happen anyway in some form
anyway, I did come up with solution for that in past but there were other dots subscene issues back then
I can look up the case where physics script broke on subscenes but worked fine on convert and destroy (on traditional scene)
I'm still so dots noob that I just try to avoid things that don't work my way π
and I totally understand that things I do are not usually things how Unity wants these things to be used
im wondering if there will be some examples on how to properly use this new subscene stuff that was added with 0.10?π€
if some day hybrid rendering is fully featured, I'll probably consider it again
I'm assuming all scenes on DOTS will eventually be dots subscenes, or using similar structure
I mean it would make sense, considering the serialization benefits
like it was on unity tiny old version
I don't think that will happen any time soon
subscenes definitely will be awesome for the next gen consoles
couse they would be literally instant to load
the direction Unity is going, you still author with conversion, even for dots subscene
I really don't like the conversion scheme at all
for runtime conversion, should we in the future be making our own conversion systems? i assume the conversion world will be around at runtime and run just work the same as if it were in a subscene/editor.
talking of dots editor, is there any chances we could dock the entity conversion preview to where ever we want without it only freezing to single entity's view?
like, you can do that now but it won't track the selected part anymore
I'd love to dedicate it some actual space on the Unity editor
while youre here @digital scarab π i noticed when i updated to 0.10.0 inactive child gameobjects dont get added to a parent's child buffer after conversion, not sure if this is expected or not? the child entities did have the parent component pointing correctly to the parent entity though
in future there should never be a reason for runtime conversion, we need to figure out all the use cases and provide a solution for them
@digital scarab Yep it's definitely final target, that DOTS workflow should feel easy same as legacy workflow, and just give users "performance by default" π
hopefully that perf by default on more than few cores π
yes, I was supposed to send the repro project for that
for the record my main use case is around asset management and remotely configurable system settings. I want to be able to download my stuff with addressables on load from remote server; from that i can dynamically build game elements. They can't all be baked into a downloaded SubScene because not all of the assets are currently convertible (sounds, particle effects), so i've had to do things like storing the addressables Runtime key to be able to link everything.
I still try to get it out to get more feedback on that
err also cc @digital scarab π¬ any view on this? https://forum.unity.com/threads/entities-0-10-bug-future-of-addcomponentobject.879934/
i am guessing each tile has 2 ints, x and y positions, you could put all the grid entities to a buffer, and select the grid entity you want from that buffer
@opaque ledge What kind of buffer? Like a NativeArray?
there is a component type called DynamicBuffer, it gives you the ability to have a 'nativelist' as a component on your entity
Oh interesting! Thanks
Oh thanks @digital scarab - sorry to add to the list π - yes, simple as add component object to an entity and then click on the entity in the inspector
Also... don't suppose you got a chance to sound out the ScheduleAuto / chunk threshold idea? No worries, just wondering.
@nimble reef https://docs.unity3d.com/Packages/com.unity.entities@0.10/manual/dynamic_buffers.html
@opaque ledge Sorry if this seems basic, so with this would I have one entity that holds the references to all the other entities in that buffer?
yes, you can make a buffer that holds Entity field, and then you can put this buffer to an entity and put your referenced entities into that buffer
I see. Thanks again
I tried doing this:
https://pastebin.com/LWPACvmC
But when I run it I get an error "InvalidOperationException: The NativeArray has been deallocated, it is not allowed to access it" on line 16 there where I'm trying to add the entity to the buffer
Because you have synch point after getting buffer. Synch point with structural changes which invalidates your buffer.
I'm not familiar with that term. What does Synch Point mean here?
Place where all jobs completes for making structural changes
Structural changes is thing when chunks data layout changes
Which mean there is shouldn't be any work on chunk memory for excluding race conditions and data corruption
Oh, so me going into a for loop invalidates stuff?
Why this invalidates native arrays? Because they points to chunk memory and after structural changes there is no guarantee it will point to the same thing
In your loop you have CreateEntity
Which trigger structural changes
Every EM call which can change data layout (Add\Remove components, changing SetSharedComponentData value (because it changes entity chunk), Creating\Destroying entities, SwapComponents etc.)
There, database BS finally sorted. Now to stress test it and see how horrific an idea it is to do string based lookups on a blob database for every update 
@storm ravine was wondering if your game uses any of the new SRPs or is it the Standard pipeline? would it be possible going forward to stick with old rendering pipeline and still adapt all of the new DOTS workflow and packages which as implied is sort of essential since subscene is entirely designed around 'pure' ecs workflow and requires hybrid renderer. am i mistaken.?
i have an ongoing project , 2yr into the development. slowly been moving performance critical aspects of it to DOTS land. often i am in more need of the ECS architectural advantage than performance benefit so am ok with hybrid nature of things with managed object sticking to entities here and there. on road ahead will this all be 'non ideal route'? some insights and suggestions would be nice..
It's likely that Unity will be completely DOTS/ECS based in the future under the hood and it won't matter much what you do on top.
But that's likely the really long term plan
We're on built in render pipeline, not using SRP, not using subscenes
so no Hybrid Renderer ?
what specifically have you added/changed to accomodate all your rendering needs , LOD and Culling aside..
gpu animation
i have read a bit on it since thats one of the major challenge trying to do all the 'core' stuff ECS way. dots animation package is apprently no go. i did take a look at a repo on Joacim's github as well , probably from nordeus demo ?
one very simple question since i haven't used HR first hand yet ,in own project , how do you go about updating material properties within ECS?
I only update them in my renderer, for HR I not update any thing, HR used for environment rendering, where I do stuff with my custom shaders, like triplanar mapping, shaking trees etc. which not using per instance properties but using global shader var's
i see. also , are you using light probes , reflection probes , lightmaps in your game. does it all work out of the box with HRV1 for supported shaders like Standard one for eg? or all of that stuff needs to be manually updated as some global params for shaders like standard renderer does..
If we'll require more properties, I just extend animation renderer or write new one
Not using, because everything is procedural generated at runtime
i see. that lends you lot of flexibility from ground up
Well you always can write your own renderer and shaders, and sample lightmap, probes etc by yourself
yea am all ok with that. just want to know if thats the route i need to take or existing solutions are already there.
i have realized ECS needs to be greatly complimented by design to warrant a full move to it. i would settle for core features like physics/rendering/navigation and interface with them via simple hybrid oriented APIs but apparently hybrid is forbidden fruit now.
Wellllll Fu-- (γΰ² ηΰ² )γ彑β»ββ»
So after finally being able to stress test this database implementation. hooo boy does that take a hit on performance
1000 entities flying about referencing their data from a blob, 10fps. Just setting up a component and stuffing the data in on load without lookup, 60fps.
no 10 fps for 1000
Yes but after that he speak about 60 for same entities without his db lookups
Or I misunderstood sentence? π
Yep np
1000 entities both times, 10 with database lookups, 60 with direct data injection no entity creation
and i think my vsync may still be off
Your game GPU bound? Heavy graphic? Because 1000 entities in just 60 fps I can't imagine even with worst chunk layout where every entity in own chunk π
And in editor with all possible sefety checks on
Or if you run it on mobile π
performance by default intensifies
What your profiler tell you?
literaly rendering cubes and yeah its 61-62 with vsync off
Which part consuming performance?
Definitely not what you should expect with that count of cubesπ€
about 1/2 scripts 1/2 others
but i really dont know how to read the profiler
20k tris on screen
Expand jobs
PlayerControl 10ms... need to see if it stuck on semaphore and waiting other job finish
are we just gonna ignore 25ms on editor?
they ignored
iiiiii forgot to switch from run to schedule when fixing something earlier =.=

π
And even with Run
if it bursted (even if not)
it should be faster
What consuming 10ms in your player control?
most of the logic currently in the game
All logic inside PlayerControlSystem ?
i don;t have much to show for myself after 6 weeks ok π
I have a cube that flys around
It's a very good cube, but he is somewhat lacking in gameplay
player control is my take in input and add onto velocity that's then taken into velocity system, and as i wasn't moving the velocity system didn't have much to do.
I mean - PlayerControlSystem takes 10ms in profiler
This simple logic you described can't take that much time
Show not timeline but hierarchy view
or send your profiler snapshot here
You mean this?
This is definitely something wrong in system OnUpdate
because this OnUpdate itself takes 11ms
Not waiting jobs etc, code in PlayerControlSystem OnUpdate takes 11ms π²
not the best utilization of jobs from what little i understand
Thats because its just using Run
No
is it Bursted code ?
withoutburst
This is because code inside doing something wrong if it that simple as you describes π
You told that it just input and velocity
clearly fundamental logic is computationally heavy
whatever is happening in that system
it's pretty much just taking the velocity components two float3's and adding to it with some clamps. shouldn;t be anything in there that bad, unless my pc has a bitcoin miner in the background i don't know about
Show OnUpdate here
what you describes can't take 11ms
even without burst, job etc.
why mixed Mathf/math use? just stick to one , preferrably the new math one. general observation.
Is there only one ActivePlayerShip?
Don't think there was a moveTowards in the new mathamatics library (when i was looking for it)
no currently all 1000 are
just so they all took in movement data for testing
Aaaaaah
Now it's clear
I have a cube that flys around
I tought you have only 1 cube here flying around as you told
you can do pos += dir*speed*deltaTime , simple move towards , maybe with clamp.
That would not take into account the rotation
can do same for rotation , calculate manually
@storm ravine So is 10ms not an insane time?
anyways dont think without jobs/burst you gonna gain anything out of maths
@storm ravine So is 10ms not an insane time?
@loud matrix in that case without burst - no
1000 of those math ops ,non burst , non jobs , seems ok..
Here is not 1000
I was a quick bit of code @naive parrot, not optimised yet, obviously :p
I'm currently trying to make it run on schedule, but it is complaining that Ship is using IComponentData and thus not allowed
strip all those if/else use math.select/math.step and , enable burst and jobs. you have a winner.
And merge that in to 1 ForEach, there is no need iterate same loop again and again
yeah
You increase your loop iteration x3 here as I mentioned above
and instead one loop through 1000 you iterating 3000...
just that merging will give you ~x3 (of course it depends on inner loop logic one loop heavy than another etc. but you can see what the problem here) boost in that exact case without changing other parts
why the hell is my ship a class....
It's of course I event not mention that thing π
Merge loop, use struct ICD and check again and you'll see big performance boost
Then use burst
one more BIG boost
then use off tread job
On moree BIG boost
and then optimize inner loops
I thought i had burst on
use simd friendly instructions, etc.
I speak only about your code posted above π
If you already removed .WithoutBurst() I don't know that π
yeah took it out with the run and converted to schedule
with minimal changes mentioned above it will give you more ms savings
A single foreach now and ... 0 performance boost, I've been lied to
Well because you now bursted and on worker thread
It's just not noticeable π
But you should see that at scale
just disable render mesh system (for exclude GPU bounds) and check how 3 loops work on 50k in comparison with 1 loop π through jobs timeline, you'll see ms difference for that job
I assume when you say off thread job you mean one of the job worker threads?
My poor render mesh system is taking up a whole 2.3ms
Ahh k, just wanted to make sure there wasn;t some other terminology I was unaware of π
My poor render mesh system is taking up a whole 2.3ms
@loud matrix your? I see only HR hereπ€
Yeah that takes it from 170-190 up to 345
sorry that's what i meant
Not all of us are writing custom rendering engines
Yeah that takes it from 170-190 up to 345
@loud matrix 50k with 1 and 3 loops? π
