Post by Admin on Jul 16, 2016 4:13:03 GMT
Simon Schmid @sschmid Jul 31 2015 04:42
btw, new release: github.com/sschmid/Entitas-CSharp/releases
Maxim Zaks @mzaks Jul 31 2015 05:12
@svdvorak There are multiple options how you can reference entities. You can create a ParentComponent which has Entity property. But this can only work when this reference consist only during simulation and you don't have to persist it as user game state. You also have to be careful not to destroy referred parent entity. For performance reasons entities are pooled, so if you keep a reference in component after the referred parent got destroyed and now reused as something else you are in deep trouble.
Having squad number component is something that you can persist in game state. It is also safe to destroy entities without thinking about where this entity might be references from.
There is only one thing that you might consider adding. You might think about building up a map which lets you query for all units which are in squad "X".
Something like GridBoardCache
github.com/sschmid/Match-One/blob/develop/Assets/Sources/Features/GameBoard/CreateGameBoardCacheSystem.cs
In match one example this map (or index if you like) is build in a system. But you can also make it as a separate class which acts as group observer and updates itself on every group change event.
This concept is close to an index in a typical database. @movrajr has absolutely right, you can think of Entitas as an in memory nosql database. And there for you have to build up your own indexes to be able to query things in a fast manner.
@umaelements not yet as far as I know
umaelements @umaelements Jul 31 2015 05:21
Well, I'm cf
Try again... Well, I'm certainly looking into it. Basics first - getting to grips with MatchOne.
Kamil Chmurzynski @cloudjubei Jul 31 2015 05:33
@svdvorak regarding your question about Unity Test Tools. We use it all the time. Most of our stuff is Unit Tests because it's really easy with Entitas to isolate your systems (if you structure your code right) and only test them so you know exactly what you're expecting. But it's true that in some cases it might be necessary to run some more complicated Unit Tests or maybe even Integration Tests. In my am @mzaks 's project we only have Integration Tests to check that we work correctly with the Backend, but for everything game related we write Unit Tests. As it might be that one system alters/creates some components that another system will react on and you're not sure how it will work - it's definitely a good idea to wrap this dependency in a CompoundSystem and execute it to see how the dependency trickles down. We don't do it, but it would be cool to see how you guys approach it
Remember that we're still trying to make this better and learning as we go - so we don't have the RIGHT answers but we try our best and definitely look forward to all of your feedback!
Andreas Wilcox @svdvorak Jul 31 2015 06:14
@movrajr @mzaks I was kinda figuring that saving entity references might be a risky solution since as you mention, the references may become invalid. I think I'll stick to using an ID for now and see how it holds up further down the line, thinking of it as a database is a good idea. I did see the cache in the Match-One example which looks like a good solution and I'll probably create my own as soon as my game performance starts crawling =)
@cloudjubei I'm running xUnit in a separate test-project, it's so nice to easily be able to test easily in Unity (as long as you separate Unity from game logic)! Regarding integration testing, I'm thinking higher level than just testing Entitas systems but instead running small scenes similar to the Unity integration tests. I'm pretty sure that those test will be much general and somewhat fragile so I'll have to see how that turns out and if it's worth it.
You might not have the right answers (if there are any) but atleast you have experience! I hope I can contribute some knowledge too in the future =)
Brandon Catcho @bcatcho Jul 31 2015 10:28
So I downloaded the latest release and can’t be certain the editor performance when using a DebugSystem much better. I was doing some profiling of the editor code and this seemed to be an issue: imgur.com/28xeyMp
The high shelf is when I had the DebugSystem selected in an inspector window. That being said, this performance issue is only a small concern right now. I’m sure there are more important things to be done
Edit:
Commenting out this line github.com/sschmid/Entitas-CSharp/blob/develop/Entitas.Unity.VisualDebugging/Assets/Entitas.Unity.VisualDebugging/SystemsObserver/Editor/SystemMonitorEditor.cs#L87
can greatly improve editor performance: imgur.com/4uLdEM1
Fredrik Holmström @fholm Jul 31 2015 14:43
hey
interesting frameowrk
Brandon Catcho @bcatcho Jul 31 2015 15:10
@sschmid Instead of complaining I made a pull request to show an example optimization of the SystemMonitorEditor Graph Drawer. It includes a snapshot of the profile before and after: sschmid/Entitas-CSharp#14
I don’t mind if you don’t want to merge it, this is mostly to illustrate my points above.
Fredrik Holmström @fholm Jul 31 2015 15:13
How do you deal with the case of the generated code getting out of sync with the code you write that is used as a base for it?
It seems like a pretty major issue, since of the main unity assembly doesn't compile, the code generator wont be able to update the generate code, etc. basically a catch-22
(or rather, it doesn't seem like this case is handled)
which seems like it would turn into a nightmare for larger projects (or rather, it will turn into a nightmare)
Brandon Catcho @bcatcho Jul 31 2015 15:15
The last dozen or so messages in this conversation relate directly to this issue. There are suggestions of how to mitigate most of the catch-22 above, but by no means is this a solved problem.
Fredrik Holmström @fholm Jul 31 2015 15:16
Okey, I have solved this issue in Bolt for example, which does a metric ton of code generation (a alot more than entitas, easily generates 20k+ LOC for a medium project)
I cant see this discussion, last stuff I see is about performance of DebugSystem
Fredrik Holmström @fholm Jul 31 2015 15:25
@bcatcho yeah I cant find this conversation youre talking abt
Brandon Catcho @bcatcho Jul 31 2015 15:26
Oh, well I meant that this problem is not solved for this framework. If you have solutions they may be welcome. I don't maintain this repo, just interested in it.
Arvid Backman backman Jul 31 2015 15:26
That's weird. I thought gitter allowed you to see messages that was sent before you joined the chat?
Fredrik Holmström @fholm Jul 31 2015 15:26
backman i can, maybe im just blind or gitter is buggy
Brandon Catcho @bcatcho Jul 31 2015 15:26
it should. I can even see old messages on my phone
Fredrik Holmström @fholm Jul 31 2015 15:26
what were any proposed solutions to this problem?
Arvid Backman backman Jul 31 2015 15:27
Now to the generator part.
Yes it can become inconvenient specifically because the generator works with Runtime reflection. So if the code does not compile you can't generate again. In large projects I would suggest to create a separate C# project/solution which contains just component classes and than use generator code so that it will produce generated extensions. This however means that you don't get Unity Menu, you have to do it manually, or write a demon which will trigger on every file change.
Now when you want to go with the standard way there you have to be aware of following caveats:
Renaming Component properties is the easiest one. Just use rename refactoring of your IDE and generate. Things should not break because properties only affect method parameter names in the generated methods. Your code should be safe.
Renaming Component name. Again use rename refactoring of your IDE, but after generate you will get compile errors due to the fact that Component name is reflected in generated Method Names. This is in my experience easily fixable. However if you want to avoid the hassle you can go to the generated class after you rename refactored your component name and than perform rename refactoring on each method name. It is up to 7 method names. It is inconvenient, but not as inconvenient as solving compile errors. Press generate and you are good to go.
Adding new properties to component. This by itself is fine, However after generate you will get compile errors. Because 2 method will get more parameters (AddXXX/ReplaceXXX). If your IDE lets you refactor method signature, than you are good. However if we are reasonable you have to change your code anyways so that you can add and replace components according to new set of properties. In this case having compile errors is actually a good thing.
Removing properties from component. This will directly lead to compilation errors because you probably used it somewhere already or at least the generated classes are using them. In this case you can just comment out implementation inside of (AddXXX/ReplaceXXX) methods of generated classes and fix your code which uses a property which you just removed. Press generate and you are good to go.
Deleting component. Delete the generated class completely, fix your code.
Maybe @sschmid will have some more tips or will come up with some tools for making it even better.
This is however how my team does it in our project.
For reference the project is a bigger simulation game with more that 300 Systems and more than 150 Component classes.
@mzaks
Fredrik Holmström @fholm Jul 31 2015 15:28
ah
Thanks
But that doesn't really solve the issue tho, it's just work-arounds
And to be honest, it's a massive issue, maybe for you guys that built the system it feels "fine", since you know everything about it, but for someone just starting it makes it almost unusable, especially for novice/beginner programmers
*starting using it
Arvid Backman backman Jul 31 2015 15:31
@sschmid also wrote
Hey guys! It's nice to see that you're giving Entitas a try! It will be worth it
There have already been really good answers and I just want to share my take on it. Most of these points have already been made, so it's more like supporting suggestions already been made.
Code Generator
I totally get you guys. When you just got started using Entitas and the Code Generator, there are a few pitfalls, the biggest one beeing to only be able to generate when your solution is compiling. In the beginning I struggled with that issue, too. But, I think it's just an issue in the beginning, when you're playing around and create / delete and rename Components and their fields all the time. Once you got the hang of it and you know what to keep in mind, this issue completely vanishes into the background. Personally, I don't even think about that anymore (and I love renaming and deleting
Also, imagine a plain old Person class with string name and int age which you use everywhere in your game. If you decide to remove the age field, you'd have to fix all the places you use it. So this issue isn't really exclusive to Entitas and the Code Generator - it just feels worse, because you cannot generate anymore until you fixed everything.
Designing levels
Let me explain, how I see this:
For me levels are just data - some configuration where things are and what their state is. E.g. a building at a certain position in the world that can be attacked and has a certain health.
I don't really care if I get this information from a json or a scene from Unity. In both cases I parse the source and create entities based on the data. In this example I'd create an Entity with BuildingComponent, PositionComponent, AttackableComponent, HealthComponent
The cool thing is, when you're designing your level in Unity, you already have the view, too! So when you parse your scene you already can link the actual building GameObject to the Entity by adding a ViewComponent
public class ViewComponent : IComponent {
public GameObject gameObject;
}
Again: a designer is completely free to create a level. He/she can setup e.g. multiple buildings at different positions, with different health and so on... the important part is: All the Monobehaviours on that GameObject should NOT have any game related logic! Only configuration like transform, health, attackable, etc. They might have some View related logic like animating something on the building. The GameObject should be treated as a dumb view with no behaviour! It's just a View
Fredrik Holmström @fholm Jul 31 2015 15:31
I just dont agree with him, the reason it feels fine for him/you guys is that you wrote the system, it's a massive issue imo.
Arvid Backman backman Jul 31 2015 15:31
Yeah, I also kinda feel that it will become a problem as the project gets larger
Fredrik Holmström @fholm Jul 31 2015 15:32
oh sorry, myabe you are not one of the authors
hard to keep track
but yeah the reason it feels fine for them is because they wrote the system
Arvid Backman backman Jul 31 2015 15:32
Aah, no, I am not
Just intrested in the framework
Fredrik Holmström @fholm Jul 31 2015 15:33
yeah same, sort of
Arvid Backman backman Jul 31 2015 15:34
Is there an easy way to solve this problem?
Fredrik Holmström @fholm Jul 31 2015 15:34
well, the best way is to make the generator not reference any code directly
you can also abuse the -firstpass / -mainpass unity compiler
by putting all of the code that is used for generation into first-pass
but thats not really a usable appraoch if you are using a lot third party assets
as they usuallly dont like being put in firstpass
Arvid Backman backman Jul 31 2015 15:36
Okey!
So basically put the library/generated code in "Standard Assets"?
Fredrik Holmström @fholm Jul 31 2015 15:37
yeah or Plugins
actually that wont work, forget I said so
Arvid Backman backman Jul 31 2015 15:37
Haha!
I won't quote you then!
Fredrik Holmström @fholm Jul 31 2015 15:37
Haha good
don't ruin my street cred
the code generator is pretty simple
fairly sure it could be replaced with a small effort
Arvid Backman backman Jul 31 2015 15:40
I wont. I understand you have a rep to protect!
Fredrik Holmström @fholm Jul 31 2015 15:40
with something that doesn't break when the main dll breaks
Arvid Backman backman Jul 31 2015 15:40
That
That's cool!
Fredrik Holmström @fholm Jul 31 2015 15:40
it's funny because I spent like several months working on this exact code gen issue for Bolt
Arvid Backman backman Jul 31 2015 15:41
Ooh, so you're the author of Bolt?
That's awesome, man!
Fredrik Holmström @fholm Jul 31 2015 15:41
yeah
kinda got the rep of bolt wrecked after i sold out to exit games tho lol
Arvid Backman backman Jul 31 2015 15:42
Really?
How come?
Fredrik Holmström @fholm Jul 31 2015 15:42
yeah check the asset store reviews
was only 5 stars, now its like ten 1/5 reviews what whine about exit games
Arvid Backman backman Jul 31 2015 15:42
Haven't used Bolt or Photon
Fredrik Holmström @fholm Jul 31 2015 15:43
anyway i gotta go pick up a load of crayfish for tonight with my son, i'll be back in about an hour
Arvid Backman backman Jul 31 2015 15:43
I was going to ask a question here how you guys would go about doing networking with this framework. maybe you have some ideas?
Fredrik Holmström @fholm Jul 31 2015 15:43
hm
Arvid Backman backman Jul 31 2015 15:43
No need to answer in an instant
If you're in a hurry!
Fredrik Holmström @fholm Jul 31 2015 15:44
meh my son is busy doing something
well the reason i am interested in t hi
*this
is because my current game im working on, is a deterministic simulation that has no concept of Unity at all, and unity is simply a presentation layer
so it's similar to this, tho obviously my game has a lot of speific stuff in it, for example it doesn't use classes at all, and only uses structs + pointers (in C#) for perf reasons, etc.
but that forced me into a solution like this, where the simulation code cant even access the unity engine at all
i suppose i would propose doing something similar if you are using entitas
tie the networking into entitas, and use unity as a presentation layer
Arvid Backman backman Jul 31 2015 15:46
Okey!
Basically what we are doing at the studio I'm working at. Using a custom ECS and Lidgren and just using Unity to render beatuiful 3D
Was just wondering if it would make sense to use UNET, Bolt, or Photon. But that maybe don't make sense you're using Entitas?
Fredrik Holmström @fholm Jul 31 2015 15:48
i think the issue iwth a lot of them
is that they are tied to the monobehaviour way of doing things
all of them, really
with unet you could use the LLAPI, but that's basically lidgren
Arvid Backman backman Jul 31 2015 15:49
Yeah, exactly. That's my concern.
Fredrik Holmström @fholm Jul 31 2015 15:49
same with Photon, you could skip "PUN" and use their raw networking, again ... similar to Lidgren
and the same with Bolt, you could use "UDPKIT" ... but again... similar to lidgren
Arvid Backman backman Jul 31 2015 15:49
Haha!
All them Lidgrens
Fredrik Holmström @fholm Jul 31 2015 15:49
personally i dont like Lidgren, as there's been some pretty major bugs found in it recently
Arvid Backman backman Jul 31 2015 15:50
Ooh.
Fredrik Holmström @fholm Jul 31 2015 15:50
stuff like reliable messages not actually being reliable
check the github issues for it, i think
Arvid Backman backman Jul 31 2015 15:50
Yeah...
If I recall correctly we had that problem
with reliable messages not really getting to the receiver
Fredrik Holmström @fholm Jul 31 2015 15:50
yeah that one
but yeah, i have my own bespoke networking solution for my current game (not Bolt), and the whole thing is basically split into three parts which know almost nohting about each other (with some glue code between)
Simulation / Networking / Rendering
Arvid Backman backman Jul 31 2015 15:51
That's cool
Fredrik Holmström @fholm Jul 31 2015 15:51
which is why entitas interested me
as I could use it for the glue code between the rendering and simulation, as that code is an absolute mess right now
Arvid Backman backman Jul 31 2015 15:52
Haha! I feel you
I personally think that the code you write with Entitas becomes beatiful!
Fredrik Holmström @fholm Jul 31 2015 15:53
personally i dont like the "fluid API" of chaining stuff
but that's just details/preference, and overall I like entitas
Arvid Backman backman Jul 31 2015 15:54
I feel that the code generator makes the code very understandable
and is to write
Fredrik Holmström @fholm Jul 31 2015 15:54
yeah
Arvid Backman backman Jul 31 2015 15:54
easy*
Fredrik Holmström @fholm Jul 31 2015 15:54
i agree with that, again a huge fan of code generation as Bolt does a massive amount of it, and my current game uses code generation to generate the entire struct-hierarchy that represents each simulation frame
time go pick up that crayfish, back in 30 mins
Arvid Backman backman Jul 31 2015 15:55
Good luck with that!!
Fredrik Holmström @fholm Jul 31 2015 16:35
hey
movrajr @movrajr Jul 31 2015 16:36
hey hey
Fredrik Holmström @fholm Jul 31 2015 16:37
lots of europeans in here, nice
Simon Schmid @sschmid Jul 31 2015 16:40
@bcatcho thanks! The 0.19.1 contains optimizations for setting the GameObject names, which was very expensive. I didn't profile the editor yet, but will definitely do so! Actually, it's on the Roadmap github.com/sschmid/Entitas-CSharp/wiki/Roadmap
movrajr @movrajr Jul 31 2015 16:40
Code generation is indeed a pain. What I did was separating components, systems and game controllers into their own folders. Then I delete the generated code, move the systems and game controllers out of the Assets folder and let Unity recompile for a bit. Then I'm ready to hit the Generate button.
dweawyn @dweawyn Jul 31 2015 16:40
Hi guys.
movrajr @movrajr Jul 31 2015 16:40
Now I have to catch up with the latest workarounds
Fredrik Holmström @fholm Jul 31 2015 16:40
@movrajr well I mean, sure, but that's again just a "hack" to solve it, and really messes with your wrokflow, especially in large projects where unity takes 1+ minute to compile
movrajr @movrajr Jul 31 2015 16:41
Completely agree
dweawyn @dweawyn Jul 31 2015 16:42
I also would like to bypass the code generation stuff. I tried to adapt the approach used by the c Sharp port of Artemis.
like so github.com/thelinuxlich/artemis_CSharp/blob/master/Artemis_XNA_INDEPENDENT/Manager/ComponentTypeManager.cs and github.com/thelinuxlich/artemis_CSharp/blob/master/Artemis_XNA_INDEPENDENT/ComponentType.cs
Fredrik Holmström @fholm Jul 31 2015 16:43
also how everything gets grouped under one "entity" class is pretty messy, imho.
there's no way to section things of, etc.
dweawyn @dweawyn Jul 31 2015 16:44
@fholm what do you mean?
Fredrik Holmström @fholm Jul 31 2015 16:45
@dweawyn well all components get generated with helper methods/properties on the Entity class
and when you have a lot of components, etc. that gets messy
dweawyn @dweawyn Jul 31 2015 16:45
I see. You can run into situations like sschmid/Entitas-CSharp#12
Fredrik Holmström @fholm Jul 31 2015 16:45
there's no way to split it into say "UIEntity" and "GameEntity"
yes, and there's no support for namespaces either I think
like if i have
movrajr @movrajr Jul 31 2015 16:47
Oh yeah, I remember some funky code getting generated when I last tried namespaces
Fredrik Holmström @fholm Jul 31 2015 16:47
namespace A { class Foo : Component { } }
namespace B { class Foo : Component { } }
that breaks
not sure why you would have that, but yeah
also no support for generics
dweawyn @dweawyn Jul 31 2015 16:49
About the generic, they said it's for performance reasons. an array is faster than a dictionary of types
Fredrik Holmström @fholm Jul 31 2015 16:49
huh?
no i ment generic classes
*generic components
also yes arrays is faster, but that doesn't exclude using generics
and I really see no reason to have AddFoo and RemoveFoo compared to just having a generic Add<T>(T component) where T : IComponent and Remove<T>() where T : IComponent, again touching on the generic stuff
but it just makes the API a pain to use, since renaming a class you have to go through all of the references and udpate them (as rename-refactoring sometimes does not work reliably with compile errors, depending on how much there are of them)
dweawyn @dweawyn Jul 31 2015 16:50
because you need to link T with the index in the array
Fredrik Holmström @fholm Jul 31 2015 16:50
yes, but that's not really a problem tho
dweawyn @dweawyn Jul 31 2015 16:51
Yep I implemented an alternative
I can do sthg like entity.AddComponent(ComponentType<T>.CType.Id, component);
Fredrik Holmström @fholm Jul 31 2015 16:51
well you can just use the native typehandle to get a unique Id per component
*per component type
and then just do a simple array/linked-list structure of it, as you might have some conflicts, but you get the benefits of both array and dictionary
it feels like the general idea of entitas is great, but the implementation is full of hacks/issues/sacrifices which steers me away from using it
dweawyn @dweawyn Jul 31 2015 16:54
Same here, but there's no alternatives. Unless you are willing to develop your own framework.
Fredrik Holmström @fholm Jul 31 2015 16:54
and the code generation serves almost no purpose other than to get a "nice api", which to me is counter-intuiative, as it the issues it brings with it
@dweawyn I don't do open source anymore, I paid my dues ;p
movrajr @movrajr Jul 31 2015 16:58
That's always the trade-off. Do you spend more time on the framework or do you work on the game? One could spend a lifetime or 2 on developing frameworks. If we could just get the low-hanging annoyances solved, that would be a step in the right direction.
Fredrik Holmström @fholm Jul 31 2015 16:58
Well, sure... but I mean, it's not like this system is like a year of work
Simon Schmid @sschmid Jul 31 2015 16:59
@fholm why do you have the this feeling
"it feels like the general idea of entitas is great, but the implementation is full of hacks/issues/sacrifices which steers me away from using it"
What do you mean with"hacks"?
Fredrik Holmström @fholm Jul 31 2015 17:00
@sschmid the main issue is that the code generation serves no purpose at all other than produce a "simple" API, and brings with it a whole slew of issues.
The way everything is grouped on the main 'Entity' is not suitable for a lot of games, there's no way to break components into sub-classes of entity properly
not to keen on the Group/Matcher stuff, read the code, it looks very inefficient to be honest, as it has to update the group every time it's requested
this could easily be solved with a much simpler approach using a bit set or some other mechanism for flagging group membership on/off, or at least allow some sort of lazy and/or requested update of a group
Fredrik Holmström @fholm Jul 31 2015 17:07
The code generator not using CodeDom but instead a home grown solution just feels like a massive bug waiting to happen (even tho it's decently simple).
Also hard to maintain bespoke code generators, as their complexity tends to explode as more features need to be added (been there, done that... first version of Bolt had a bespoke code generator)
To sum up, yes the general idea of entitas is great, the implementation needs a lot of work before it's ready to be used in a real environment by any other than the authors.
(that is how I feel)
movrajr @movrajr Jul 31 2015 17:09
Darn, now I feel like creating a new ECS framework :/
But good points fholm
Fredrik Holmström @fholm Jul 31 2015 17:11
Also, on the code generator it's almost impossible to extend a home-grown generator without editing the actual code of it in the library, where some people might want to add new generator behaviours, etc.
Using CodeDom is much easier, even tho the API of CodeDom is INSANELY explicit, it's a standardized interface that's easy to work with that doesn't form a bi-direction dependancy with entitas and the user code
Simon Schmid @sschmid Jul 31 2015 17:11
@fholm stupid question, but: have you even used Entitas?
Fredrik Holmström @fholm Jul 31 2015 17:11
*bi-directional
@sschmid for a real game? no, trying to integrate it to replace the glue code between my simulation and UI layer, yes
*simulation and render layer, yes
Simon Schmid @sschmid Jul 31 2015 17:12
when I have time I'd like to respond to all your statments
Fredrik Holmström @fholm Jul 31 2015 17:12
absolutely
by 'a real game' i ment a game that is launched and available for customers, I am working on a "real game", but it's not done, and I tried to use entitas in that.
Fredrik Holmström @fholm Jul 31 2015 17:19
Also I would love if some type of weak reference system existed to other entities/components
So that you can keep a reference around to it in another component, and when the object in the reference gets destroyed/removed/whatever, the reference gets cleared also
Arvid Backman backman Jul 31 2015 18:27
Isn
Isn't there some kind of way to force Unity to recompile?
Fredrik Holmström @fholm Jul 31 2015 18:27
how would it be able to compile if there are compile errors
Arvid Backman backman Jul 31 2015 18:28
Haha
I'm not quite sure how the code generation is done
But if you generate code the file changes?
Fredrik Holmström @fholm Jul 31 2015 18:29
yes but the generate code relies on the assembly being compilled already, to than have the code generate, and then be compiled again
Arvid Backman backman Jul 31 2015 18:29
If that is the case, couldn't you do AssetDatabase.Refresh()?
Fredrik Holmström @fholm Jul 31 2015 18:29
no
Arvid Backman backman Jul 31 2015 18:29
Ooh
Yeah. you're right
My bad!
Fredrik Holmström @fholm Jul 31 2015 18:29
Arvid Backman backman Jul 31 2015 18:29
Forget I said anything.
Or don't! I really don't have any street cred anyways
Fredrik Holmström @fholm Jul 31 2015 18:30
Andreas Wilcox @svdvorak Jul 31 2015 18:47
You guys have been chatty =)
A few thoughts regarding @fholm comments: I personally like the cleaner syntax that the code generation brings, considering most time is spent reading code you'd want it to be as easily readable as possible. But I do agree that you might easily get component creep in the Entity, having 150 components (as @mzaks mentioned before) sounds like it would make things a bit messy. Regarding code generation I'm personally fine with the workarounds for now but would be nice for it to run even when the project is not compiling though. Everything's always a work in progress =)
Fredrik Holmström @fholm Jul 31 2015 18:47
@svdvorak thing is tho, you can have the same clean API without code generation
As in, the code generation adds nothing right now other than overhead and issues
Andreas Wilcox @svdvorak Jul 31 2015 18:50
Generics I'm guessing as you mentioned before?
Fredrik Holmström @fholm Jul 31 2015 18:50
@svdvorak yes, that could be used for example
or just a simpe AddComponent(IComponent component) method
and then possibly have an two GetComponent methods, one generic and one non-generic
Arvid Backman backman Jul 31 2015 18:52
That's basically how we're doing it
With our ECS
Fredrik Holmström @fholm Jul 31 2015 18:53
yeah, it's a lot cleaner and nicer to use
Arvid Backman backman Jul 31 2015 18:54
public void AddComponent<T>(int entityId, T component) where T : Component
´´´
Andreas Wilcox @svdvorak Jul 31 2015 18:54
It's not a huge deal but I think I like entity.AddPosition(0, 0, 0) over entity.AddComponent(new PositionComponent(0, 0, 0)) but it's all preference. Atleast no reason not to have both.
Arvid Backman backman Jul 31 2015 18:54
woops
Andreas Wilcox @svdvorak Jul 31 2015 18:56
Why would you have to supply an entityId? That feels like plumbing leaking out of the API.
Fredrik Holmström @fholm Jul 31 2015 18:56
yeah i dont agree with that
Arvid Backman backman Jul 31 2015 18:56
With our solution the entity is basically just an int
I kinda agree
Fredrik Holmström @fholm Jul 31 2015 18:56
ah
Arvid Backman backman Jul 31 2015 18:56
But that's how we do it
Andreas Wilcox @svdvorak Jul 31 2015 18:56
Ah, gotcha =)
Fredrik Holmström @fholm Jul 31 2015 18:57
backman where do you work? (swedish name ;p)
Arvid Backman backman Jul 31 2015 18:57
I work at Tarhead Studio
Fredrik Holmström @fholm Jul 31 2015 18:57
ah, where in sweden?
Arvid Backman backman Jul 31 2015 18:57
A indie startup based in Skövde
Fredrik Holmström @fholm Jul 31 2015 18:57
Ah, I live close by
Skene (close to borås)
Andreas Wilcox @svdvorak Jul 31 2015 18:58
backman You guys sit in Gothia Science Park?
Arvid Backman backman Jul 31 2015 18:58
We are currently developing a game called Ruin
Fredrik Holmström @fholm Jul 31 2015 18:58
backman ah
Arvid Backman backman Jul 31 2015 18:58
Yeah! We sit in Gothia Science Park
Fredrik Holmström @fholm Jul 31 2015 18:59
I've seen it
backman interesting, I'm working on a similar type of game
Arvid Backman backman Jul 31 2015 18:59
Cool!
Fredrik Holmström @fholm Jul 31 2015 18:59
hopefully go up on greenlight within ~2 months
Andreas Wilcox @svdvorak Jul 31 2015 18:59
Kinda figured, a lot of indies there. Did my examination work at Ludosity Interactive many years ago.
Arvid Backman backman Jul 31 2015 19:00
Btw, forgot to mention. It is possible to add components via the Entity class aswell
Fredrik Holmström @fholm Jul 31 2015 19:00
it's not identical to Ruin, but some of the same concepts transfer and the same perspective/control scheme,e tc.
Arvid Backman backman Jul 31 2015 19:00
public void AddComponent<T>(T component) where T: Component
That's cool @fholm ! Is there anything you can show?
Fredrik Holmström @fholm Jul 31 2015 19:01
backman there is, but I am trying to keep myself detached form the game, as I don't want to be personally associated with it (did that mistake with Bolt, the fucking pain.. lol)
I'll show once it goes up on greenlight
Arvid Backman backman Jul 31 2015 19:01
Cool!
Sorry guys for getting of track from the channel topic!
Fredrik Holmström @fholm Jul 31 2015 19:02
Haha
backman you guys built your own networking solution yeah?
Arvid Backman backman Jul 31 2015 19:11
Yes, we did! We're using Lidgren do synchronize compnent data
Correction. We use Lidgren everywhere
Fredrik Holmström @fholm Jul 31 2015 19:34
backman cool
Maxim Zaks @mzaks Jul 31 2015 20:55
Hi guys,
I see we have a lot of discussion going on
I have however one favour to ask. Please try to keep it more to the point and less small talk conversational because if someone comes in and sees couple of dudes chatting around it feels like a chatroom and not like a professional forum anymore where you actually can get answers to specific questions.
I think we all would like this place to be informative. Today it kind of got out of hand
Anyways, I would like to address the most important point which was raised by @fholm the code generation and inconvenience that it brings with it.
First of all the code generator is not only about nice API it is also about performance. We had the generics based API before, and I still do in my Swift port of Entitas. However in with generic based API you have to do Dictionary lookups and they are slower than direct array access. But let's say that we ignore this small performance impediment. And we implement a generic methods.
In this case for being able to actually replace components in the entity, and you want to replace(remove and than add) component to the entity because of the observer pattern you would have to create a new component each time. Which means that old components will be garbage collected. And this is a performance hit that you don't want to have. You already mentioned somewhere that you use struct because of performance. Which helps because structs are less garbage. However garbage is garbage and you have to clean it up. The generated methods take care of the reuse of the components for you. So that we don't have garbage collector kicking in. This is a huge benefit. You can achieve it by writing a lots of boilerplates yourself. And this is actually what we did 9 months ago. Than we started generating methods which encapsulated all eh boilerplate stuff that you have to do for memory management. Just have a look at a generated ComponentExtension and you will see what I mean.
We will give some more answers on the questions, it's just hard right now to distill actually questions from casual conversation between couple of dev. That's why also my favour for keeping this chat as to the point as possible.
In the end we either have to take time to answer the questions or just searching for them
However we got the main takeaway. Code generation is hard specially when you are starting so we are thinking about solutions. And everybody is welcome to sketch a solution and create a pull request.
Arvid Backman backman Jul 31 2015 21:02
Thanks for the write-up @mzaks . And again, sorry for the off topic chatting :worried:
dweawyn @dweawyn Jul 31 2015 21:07
Regarding the performance with generics, I attempted to "cache" the index in a ComponentType<T> where T : IComponent. See here: github.com/dweawyn/Entitas-CSharp/tree/generics/Entitas/Entitas/Extensions
Maxim Zaks @mzaks Jul 31 2015 21:07
backman no worries
And I pocked around in old commits and here is an example of nice API which don't need code generation
github.com/sschmid/Entitas-CSharp/blob/0.1.0/Entitas/Entitas/Entity.cs
dweawyn @dweawyn Jul 31 2015 21:07
It's not much faster than a Dictionary<Type,int>
Simon Schmid @sschmid Jul 31 2015 21:11
Great to see the all your involvement! I’d like to respond to all the suggestions and opinions, but the chat starts to get a little bit messy. That's why I'd like to introduce some guidelines, trying to keep this chat informative and instructive, like it was just two days ago
I think it’s important to keep the chat clean, so also new ppl joining can pull some useful information out of it.
Please take your time and describe your questions / issues / suggestions / opinions
Check the github issues or scroll up, maybe your questions have already been answered, but of course feel free to pick up already discussed topics again, when you still have questions
If you have suggestions / improvements / doubts, keep on letting us know in the chat and maybe open a new github issue to discuss a specific problem / feature
Keep on pointing out things, that can be improved. If you have a solution for problems, even better: make a pull request.
Learning new things always takes time. We want to help you, to answer your questions, but please don’t state things, that are wrong or are only based on your „gut feeling“ rather than measurements, as this will confuse other users.
Move conversations about your lunch or your work to private chats and try to keep topics Entitas related
Fredrik Holmström @fholm Jul 31 2015 22:30
@sschmid Gotta say the attitude you and @mzaks have is a bit off-putting, people will always chat about off-topic stuff is medias like this, it's just the nature of it, being told off to basically shut up about it when it's was only me and backman talking and no one else was saying a word is well... off-putting.
And really, "please don't state things based on your gut-feeling", I mean... lol, who decides what is gut-feeling or not? Learn to take criticism of your library instead of responding with basically telling people to "shut up".
Anyway, this attitude is a good way of loosing early adopters and what not, I'm out. Take care.
Simon Schmid @sschmid Jul 31 2015 22:38
There will be a respond addressing all the points, but that will take some time. In the meantime I wanted to introduce guidelines to keep this chat focused.
Fredrik Holmström @fholm Jul 31 2015 22:39
That's good, but I'm out bye!
Simon Schmid @sschmid Jul 31 2015 22:40
That's fine! bye
Maxim Zaks @mzaks Jul 31 2015 22:40
@fholm Sorry if you take it personal, but the rules make sense so that every one can benefit from this chat.
zyzyx @zyzyxdev Jul 31 2015 22:46
hi! would entitas be suited for GUI heavy mobile apps? are there plans for doing a more gui focused example project?
Simon Schmid @sschmid Jul 31 2015 22:49
@zyzyxdev I think @mzaks can you tell you more about this. He actually build a mobile app for iOS with entitas for swift, which was UI only
Maxim Zaks @mzaks Jul 31 2015 22:52
@zyzyxdev we can think about an example for C#. In the iOS App, I used the data part of Entitas combined with Observer mechanics. In UI heavy application you don't necessary need systems which are executed on each tick in the run loop.
here is the link to the iOS App I did for a conference I am co-organizing.
github.com/UIKonf/uikonf-app
It's not a beauty and it's in Swift but maybe that helps somehow
zyzyx @zyzyxdev Jul 31 2015 22:53
thanks!
I come from a mvvm background so this is quite a new way of thinking
Maxim Zaks @mzaks Jul 31 2015 22:59
Well in MVVM view model is basically a way of representing view in a logical way. If you have a flexible way of representing data you don't need this separate abstraction. You can have just different components on one entity, some are data related some are view related. It might feel like you mixing concern but in reality you don't. The code working on different components should be separated.
Hm I guess it is a bit harder to explain. I wrote a Blog series where I tried to address this ideas
medium.com/@icex33/think-different-about-data-model-7c0ca0879864
zyzyx @zyzyxdev Jul 31 2015 23:04
I see, thanks again!
Simon Schmid @sschmid Jul 31 2015 23:05
btw, added a wiki page for the roadmap. A few things we discussed are already listed
github.com/sschmid/Entitas-CSharp/wiki/Roadmap
movrajr @movrajr Jul 31 2015 23:30
Regarding Roslyn, that might be a can of worms: forum.unity3d.com/threads/c-6-0.314297/
btw, new release: github.com/sschmid/Entitas-CSharp/releases
Maxim Zaks @mzaks Jul 31 2015 05:12
@svdvorak There are multiple options how you can reference entities. You can create a ParentComponent which has Entity property. But this can only work when this reference consist only during simulation and you don't have to persist it as user game state. You also have to be careful not to destroy referred parent entity. For performance reasons entities are pooled, so if you keep a reference in component after the referred parent got destroyed and now reused as something else you are in deep trouble.
Having squad number component is something that you can persist in game state. It is also safe to destroy entities without thinking about where this entity might be references from.
There is only one thing that you might consider adding. You might think about building up a map which lets you query for all units which are in squad "X".
Something like GridBoardCache
github.com/sschmid/Match-One/blob/develop/Assets/Sources/Features/GameBoard/CreateGameBoardCacheSystem.cs
In match one example this map (or index if you like) is build in a system. But you can also make it as a separate class which acts as group observer and updates itself on every group change event.
This concept is close to an index in a typical database. @movrajr has absolutely right, you can think of Entitas as an in memory nosql database. And there for you have to build up your own indexes to be able to query things in a fast manner.
@umaelements not yet as far as I know
umaelements @umaelements Jul 31 2015 05:21
Well, I'm cf
Try again... Well, I'm certainly looking into it. Basics first - getting to grips with MatchOne.
Kamil Chmurzynski @cloudjubei Jul 31 2015 05:33
@svdvorak regarding your question about Unity Test Tools. We use it all the time. Most of our stuff is Unit Tests because it's really easy with Entitas to isolate your systems (if you structure your code right) and only test them so you know exactly what you're expecting. But it's true that in some cases it might be necessary to run some more complicated Unit Tests or maybe even Integration Tests. In my am @mzaks 's project we only have Integration Tests to check that we work correctly with the Backend, but for everything game related we write Unit Tests. As it might be that one system alters/creates some components that another system will react on and you're not sure how it will work - it's definitely a good idea to wrap this dependency in a CompoundSystem and execute it to see how the dependency trickles down. We don't do it, but it would be cool to see how you guys approach it
Remember that we're still trying to make this better and learning as we go - so we don't have the RIGHT answers but we try our best and definitely look forward to all of your feedback!
Andreas Wilcox @svdvorak Jul 31 2015 06:14
@movrajr @mzaks I was kinda figuring that saving entity references might be a risky solution since as you mention, the references may become invalid. I think I'll stick to using an ID for now and see how it holds up further down the line, thinking of it as a database is a good idea. I did see the cache in the Match-One example which looks like a good solution and I'll probably create my own as soon as my game performance starts crawling =)
@cloudjubei I'm running xUnit in a separate test-project, it's so nice to easily be able to test easily in Unity (as long as you separate Unity from game logic)! Regarding integration testing, I'm thinking higher level than just testing Entitas systems but instead running small scenes similar to the Unity integration tests. I'm pretty sure that those test will be much general and somewhat fragile so I'll have to see how that turns out and if it's worth it.
You might not have the right answers (if there are any) but atleast you have experience! I hope I can contribute some knowledge too in the future =)
Brandon Catcho @bcatcho Jul 31 2015 10:28
So I downloaded the latest release and can’t be certain the editor performance when using a DebugSystem much better. I was doing some profiling of the editor code and this seemed to be an issue: imgur.com/28xeyMp
The high shelf is when I had the DebugSystem selected in an inspector window. That being said, this performance issue is only a small concern right now. I’m sure there are more important things to be done
Edit:
Commenting out this line github.com/sschmid/Entitas-CSharp/blob/develop/Entitas.Unity.VisualDebugging/Assets/Entitas.Unity.VisualDebugging/SystemsObserver/Editor/SystemMonitorEditor.cs#L87
can greatly improve editor performance: imgur.com/4uLdEM1
Fredrik Holmström @fholm Jul 31 2015 14:43
hey
interesting frameowrk
Brandon Catcho @bcatcho Jul 31 2015 15:10
@sschmid Instead of complaining I made a pull request to show an example optimization of the SystemMonitorEditor Graph Drawer. It includes a snapshot of the profile before and after: sschmid/Entitas-CSharp#14
I don’t mind if you don’t want to merge it, this is mostly to illustrate my points above.
Fredrik Holmström @fholm Jul 31 2015 15:13
How do you deal with the case of the generated code getting out of sync with the code you write that is used as a base for it?
It seems like a pretty major issue, since of the main unity assembly doesn't compile, the code generator wont be able to update the generate code, etc. basically a catch-22
(or rather, it doesn't seem like this case is handled)
which seems like it would turn into a nightmare for larger projects (or rather, it will turn into a nightmare)
Brandon Catcho @bcatcho Jul 31 2015 15:15
The last dozen or so messages in this conversation relate directly to this issue. There are suggestions of how to mitigate most of the catch-22 above, but by no means is this a solved problem.
Fredrik Holmström @fholm Jul 31 2015 15:16
Okey, I have solved this issue in Bolt for example, which does a metric ton of code generation (a alot more than entitas, easily generates 20k+ LOC for a medium project)
I cant see this discussion, last stuff I see is about performance of DebugSystem
Fredrik Holmström @fholm Jul 31 2015 15:25
@bcatcho yeah I cant find this conversation youre talking abt
Brandon Catcho @bcatcho Jul 31 2015 15:26
Oh, well I meant that this problem is not solved for this framework. If you have solutions they may be welcome. I don't maintain this repo, just interested in it.
Arvid Backman backman Jul 31 2015 15:26
That's weird. I thought gitter allowed you to see messages that was sent before you joined the chat?
Fredrik Holmström @fholm Jul 31 2015 15:26
backman i can, maybe im just blind or gitter is buggy
Brandon Catcho @bcatcho Jul 31 2015 15:26
it should. I can even see old messages on my phone
Fredrik Holmström @fholm Jul 31 2015 15:26
what were any proposed solutions to this problem?
Arvid Backman backman Jul 31 2015 15:27
Now to the generator part.
Yes it can become inconvenient specifically because the generator works with Runtime reflection. So if the code does not compile you can't generate again. In large projects I would suggest to create a separate C# project/solution which contains just component classes and than use generator code so that it will produce generated extensions. This however means that you don't get Unity Menu, you have to do it manually, or write a demon which will trigger on every file change.
Now when you want to go with the standard way there you have to be aware of following caveats:
Renaming Component properties is the easiest one. Just use rename refactoring of your IDE and generate. Things should not break because properties only affect method parameter names in the generated methods. Your code should be safe.
Renaming Component name. Again use rename refactoring of your IDE, but after generate you will get compile errors due to the fact that Component name is reflected in generated Method Names. This is in my experience easily fixable. However if you want to avoid the hassle you can go to the generated class after you rename refactored your component name and than perform rename refactoring on each method name. It is up to 7 method names. It is inconvenient, but not as inconvenient as solving compile errors. Press generate and you are good to go.
Adding new properties to component. This by itself is fine, However after generate you will get compile errors. Because 2 method will get more parameters (AddXXX/ReplaceXXX). If your IDE lets you refactor method signature, than you are good. However if we are reasonable you have to change your code anyways so that you can add and replace components according to new set of properties. In this case having compile errors is actually a good thing.
Removing properties from component. This will directly lead to compilation errors because you probably used it somewhere already or at least the generated classes are using them. In this case you can just comment out implementation inside of (AddXXX/ReplaceXXX) methods of generated classes and fix your code which uses a property which you just removed. Press generate and you are good to go.
Deleting component. Delete the generated class completely, fix your code.
Maybe @sschmid will have some more tips or will come up with some tools for making it even better.
This is however how my team does it in our project.
For reference the project is a bigger simulation game with more that 300 Systems and more than 150 Component classes.
@mzaks
Fredrik Holmström @fholm Jul 31 2015 15:28
ah
Thanks
But that doesn't really solve the issue tho, it's just work-arounds
And to be honest, it's a massive issue, maybe for you guys that built the system it feels "fine", since you know everything about it, but for someone just starting it makes it almost unusable, especially for novice/beginner programmers
*starting using it
Arvid Backman backman Jul 31 2015 15:31
@sschmid also wrote
Hey guys! It's nice to see that you're giving Entitas a try! It will be worth it
There have already been really good answers and I just want to share my take on it. Most of these points have already been made, so it's more like supporting suggestions already been made.
Code Generator
I totally get you guys. When you just got started using Entitas and the Code Generator, there are a few pitfalls, the biggest one beeing to only be able to generate when your solution is compiling. In the beginning I struggled with that issue, too. But, I think it's just an issue in the beginning, when you're playing around and create / delete and rename Components and their fields all the time. Once you got the hang of it and you know what to keep in mind, this issue completely vanishes into the background. Personally, I don't even think about that anymore (and I love renaming and deleting
Also, imagine a plain old Person class with string name and int age which you use everywhere in your game. If you decide to remove the age field, you'd have to fix all the places you use it. So this issue isn't really exclusive to Entitas and the Code Generator - it just feels worse, because you cannot generate anymore until you fixed everything.
Designing levels
Let me explain, how I see this:
For me levels are just data - some configuration where things are and what their state is. E.g. a building at a certain position in the world that can be attacked and has a certain health.
I don't really care if I get this information from a json or a scene from Unity. In both cases I parse the source and create entities based on the data. In this example I'd create an Entity with BuildingComponent, PositionComponent, AttackableComponent, HealthComponent
The cool thing is, when you're designing your level in Unity, you already have the view, too! So when you parse your scene you already can link the actual building GameObject to the Entity by adding a ViewComponent
public class ViewComponent : IComponent {
public GameObject gameObject;
}
Again: a designer is completely free to create a level. He/she can setup e.g. multiple buildings at different positions, with different health and so on... the important part is: All the Monobehaviours on that GameObject should NOT have any game related logic! Only configuration like transform, health, attackable, etc. They might have some View related logic like animating something on the building. The GameObject should be treated as a dumb view with no behaviour! It's just a View
Fredrik Holmström @fholm Jul 31 2015 15:31
I just dont agree with him, the reason it feels fine for him/you guys is that you wrote the system, it's a massive issue imo.
Arvid Backman backman Jul 31 2015 15:31
Yeah, I also kinda feel that it will become a problem as the project gets larger
Fredrik Holmström @fholm Jul 31 2015 15:32
oh sorry, myabe you are not one of the authors
hard to keep track
but yeah the reason it feels fine for them is because they wrote the system
Arvid Backman backman Jul 31 2015 15:32
Aah, no, I am not
Just intrested in the framework
Fredrik Holmström @fholm Jul 31 2015 15:33
yeah same, sort of
Arvid Backman backman Jul 31 2015 15:34
Is there an easy way to solve this problem?
Fredrik Holmström @fholm Jul 31 2015 15:34
well, the best way is to make the generator not reference any code directly
you can also abuse the -firstpass / -mainpass unity compiler
by putting all of the code that is used for generation into first-pass
but thats not really a usable appraoch if you are using a lot third party assets
as they usuallly dont like being put in firstpass
Arvid Backman backman Jul 31 2015 15:36
Okey!
So basically put the library/generated code in "Standard Assets"?
Fredrik Holmström @fholm Jul 31 2015 15:37
yeah or Plugins
actually that wont work, forget I said so
Arvid Backman backman Jul 31 2015 15:37
Haha!
I won't quote you then!
Fredrik Holmström @fholm Jul 31 2015 15:37
Haha good
don't ruin my street cred
the code generator is pretty simple
fairly sure it could be replaced with a small effort
Arvid Backman backman Jul 31 2015 15:40
I wont. I understand you have a rep to protect!
Fredrik Holmström @fholm Jul 31 2015 15:40
with something that doesn't break when the main dll breaks
Arvid Backman backman Jul 31 2015 15:40
That
That's cool!
Fredrik Holmström @fholm Jul 31 2015 15:40
it's funny because I spent like several months working on this exact code gen issue for Bolt
Arvid Backman backman Jul 31 2015 15:41
Ooh, so you're the author of Bolt?
That's awesome, man!
Fredrik Holmström @fholm Jul 31 2015 15:41
yeah
kinda got the rep of bolt wrecked after i sold out to exit games tho lol
Arvid Backman backman Jul 31 2015 15:42
Really?
How come?
Fredrik Holmström @fholm Jul 31 2015 15:42
yeah check the asset store reviews
was only 5 stars, now its like ten 1/5 reviews what whine about exit games
Arvid Backman backman Jul 31 2015 15:42
Haven't used Bolt or Photon
Fredrik Holmström @fholm Jul 31 2015 15:43
anyway i gotta go pick up a load of crayfish for tonight with my son, i'll be back in about an hour
Arvid Backman backman Jul 31 2015 15:43
I was going to ask a question here how you guys would go about doing networking with this framework. maybe you have some ideas?
Fredrik Holmström @fholm Jul 31 2015 15:43
hm
Arvid Backman backman Jul 31 2015 15:43
No need to answer in an instant
If you're in a hurry!
Fredrik Holmström @fholm Jul 31 2015 15:44
meh my son is busy doing something
well the reason i am interested in t hi
*this
is because my current game im working on, is a deterministic simulation that has no concept of Unity at all, and unity is simply a presentation layer
so it's similar to this, tho obviously my game has a lot of speific stuff in it, for example it doesn't use classes at all, and only uses structs + pointers (in C#) for perf reasons, etc.
but that forced me into a solution like this, where the simulation code cant even access the unity engine at all
i suppose i would propose doing something similar if you are using entitas
tie the networking into entitas, and use unity as a presentation layer
Arvid Backman backman Jul 31 2015 15:46
Okey!
Basically what we are doing at the studio I'm working at. Using a custom ECS and Lidgren and just using Unity to render beatuiful 3D
Was just wondering if it would make sense to use UNET, Bolt, or Photon. But that maybe don't make sense you're using Entitas?
Fredrik Holmström @fholm Jul 31 2015 15:48
i think the issue iwth a lot of them
is that they are tied to the monobehaviour way of doing things
all of them, really
with unet you could use the LLAPI, but that's basically lidgren
Arvid Backman backman Jul 31 2015 15:49
Yeah, exactly. That's my concern.
Fredrik Holmström @fholm Jul 31 2015 15:49
same with Photon, you could skip "PUN" and use their raw networking, again ... similar to Lidgren
and the same with Bolt, you could use "UDPKIT" ... but again... similar to lidgren
Arvid Backman backman Jul 31 2015 15:49
Haha!
All them Lidgrens
Fredrik Holmström @fholm Jul 31 2015 15:49
personally i dont like Lidgren, as there's been some pretty major bugs found in it recently
Arvid Backman backman Jul 31 2015 15:50
Ooh.
Fredrik Holmström @fholm Jul 31 2015 15:50
stuff like reliable messages not actually being reliable
check the github issues for it, i think
Arvid Backman backman Jul 31 2015 15:50
Yeah...
If I recall correctly we had that problem
with reliable messages not really getting to the receiver
Fredrik Holmström @fholm Jul 31 2015 15:50
yeah that one
but yeah, i have my own bespoke networking solution for my current game (not Bolt), and the whole thing is basically split into three parts which know almost nohting about each other (with some glue code between)
Simulation / Networking / Rendering
Arvid Backman backman Jul 31 2015 15:51
That's cool
Fredrik Holmström @fholm Jul 31 2015 15:51
which is why entitas interested me
as I could use it for the glue code between the rendering and simulation, as that code is an absolute mess right now
Arvid Backman backman Jul 31 2015 15:52
Haha! I feel you
I personally think that the code you write with Entitas becomes beatiful!
Fredrik Holmström @fholm Jul 31 2015 15:53
personally i dont like the "fluid API" of chaining stuff
but that's just details/preference, and overall I like entitas
Arvid Backman backman Jul 31 2015 15:54
I feel that the code generator makes the code very understandable
and is to write
Fredrik Holmström @fholm Jul 31 2015 15:54
yeah
Arvid Backman backman Jul 31 2015 15:54
easy*
Fredrik Holmström @fholm Jul 31 2015 15:54
i agree with that, again a huge fan of code generation as Bolt does a massive amount of it, and my current game uses code generation to generate the entire struct-hierarchy that represents each simulation frame
time go pick up that crayfish, back in 30 mins
Arvid Backman backman Jul 31 2015 15:55
Good luck with that!!
Fredrik Holmström @fholm Jul 31 2015 16:35
hey
movrajr @movrajr Jul 31 2015 16:36
hey hey
Fredrik Holmström @fholm Jul 31 2015 16:37
lots of europeans in here, nice
Simon Schmid @sschmid Jul 31 2015 16:40
@bcatcho thanks! The 0.19.1 contains optimizations for setting the GameObject names, which was very expensive. I didn't profile the editor yet, but will definitely do so! Actually, it's on the Roadmap github.com/sschmid/Entitas-CSharp/wiki/Roadmap
movrajr @movrajr Jul 31 2015 16:40
Code generation is indeed a pain. What I did was separating components, systems and game controllers into their own folders. Then I delete the generated code, move the systems and game controllers out of the Assets folder and let Unity recompile for a bit. Then I'm ready to hit the Generate button.
dweawyn @dweawyn Jul 31 2015 16:40
Hi guys.
movrajr @movrajr Jul 31 2015 16:40
Now I have to catch up with the latest workarounds
Fredrik Holmström @fholm Jul 31 2015 16:40
@movrajr well I mean, sure, but that's again just a "hack" to solve it, and really messes with your wrokflow, especially in large projects where unity takes 1+ minute to compile
movrajr @movrajr Jul 31 2015 16:41
Completely agree
dweawyn @dweawyn Jul 31 2015 16:42
I also would like to bypass the code generation stuff. I tried to adapt the approach used by the c Sharp port of Artemis.
like so github.com/thelinuxlich/artemis_CSharp/blob/master/Artemis_XNA_INDEPENDENT/Manager/ComponentTypeManager.cs and github.com/thelinuxlich/artemis_CSharp/blob/master/Artemis_XNA_INDEPENDENT/ComponentType.cs
Fredrik Holmström @fholm Jul 31 2015 16:43
also how everything gets grouped under one "entity" class is pretty messy, imho.
there's no way to section things of, etc.
dweawyn @dweawyn Jul 31 2015 16:44
@fholm what do you mean?
Fredrik Holmström @fholm Jul 31 2015 16:45
@dweawyn well all components get generated with helper methods/properties on the Entity class
and when you have a lot of components, etc. that gets messy
dweawyn @dweawyn Jul 31 2015 16:45
I see. You can run into situations like sschmid/Entitas-CSharp#12
Fredrik Holmström @fholm Jul 31 2015 16:45
there's no way to split it into say "UIEntity" and "GameEntity"
yes, and there's no support for namespaces either I think
like if i have
movrajr @movrajr Jul 31 2015 16:47
Oh yeah, I remember some funky code getting generated when I last tried namespaces
Fredrik Holmström @fholm Jul 31 2015 16:47
namespace A { class Foo : Component { } }
namespace B { class Foo : Component { } }
that breaks
not sure why you would have that, but yeah
also no support for generics
dweawyn @dweawyn Jul 31 2015 16:49
About the generic, they said it's for performance reasons. an array is faster than a dictionary of types
Fredrik Holmström @fholm Jul 31 2015 16:49
huh?
no i ment generic classes
*generic components
also yes arrays is faster, but that doesn't exclude using generics
and I really see no reason to have AddFoo and RemoveFoo compared to just having a generic Add<T>(T component) where T : IComponent and Remove<T>() where T : IComponent, again touching on the generic stuff
but it just makes the API a pain to use, since renaming a class you have to go through all of the references and udpate them (as rename-refactoring sometimes does not work reliably with compile errors, depending on how much there are of them)
dweawyn @dweawyn Jul 31 2015 16:50
because you need to link T with the index in the array
Fredrik Holmström @fholm Jul 31 2015 16:50
yes, but that's not really a problem tho
dweawyn @dweawyn Jul 31 2015 16:51
Yep I implemented an alternative
I can do sthg like entity.AddComponent(ComponentType<T>.CType.Id, component);
Fredrik Holmström @fholm Jul 31 2015 16:51
well you can just use the native typehandle to get a unique Id per component
*per component type
and then just do a simple array/linked-list structure of it, as you might have some conflicts, but you get the benefits of both array and dictionary
it feels like the general idea of entitas is great, but the implementation is full of hacks/issues/sacrifices which steers me away from using it
dweawyn @dweawyn Jul 31 2015 16:54
Same here, but there's no alternatives. Unless you are willing to develop your own framework.
Fredrik Holmström @fholm Jul 31 2015 16:54
and the code generation serves almost no purpose other than to get a "nice api", which to me is counter-intuiative, as it the issues it brings with it
@dweawyn I don't do open source anymore, I paid my dues ;p
movrajr @movrajr Jul 31 2015 16:58
That's always the trade-off. Do you spend more time on the framework or do you work on the game? One could spend a lifetime or 2 on developing frameworks. If we could just get the low-hanging annoyances solved, that would be a step in the right direction.
Fredrik Holmström @fholm Jul 31 2015 16:58
Well, sure... but I mean, it's not like this system is like a year of work
Simon Schmid @sschmid Jul 31 2015 16:59
@fholm why do you have the this feeling
"it feels like the general idea of entitas is great, but the implementation is full of hacks/issues/sacrifices which steers me away from using it"
What do you mean with"hacks"?
Fredrik Holmström @fholm Jul 31 2015 17:00
@sschmid the main issue is that the code generation serves no purpose at all other than produce a "simple" API, and brings with it a whole slew of issues.
The way everything is grouped on the main 'Entity' is not suitable for a lot of games, there's no way to break components into sub-classes of entity properly
not to keen on the Group/Matcher stuff, read the code, it looks very inefficient to be honest, as it has to update the group every time it's requested
this could easily be solved with a much simpler approach using a bit set or some other mechanism for flagging group membership on/off, or at least allow some sort of lazy and/or requested update of a group
Fredrik Holmström @fholm Jul 31 2015 17:07
The code generator not using CodeDom but instead a home grown solution just feels like a massive bug waiting to happen (even tho it's decently simple).
Also hard to maintain bespoke code generators, as their complexity tends to explode as more features need to be added (been there, done that... first version of Bolt had a bespoke code generator)
To sum up, yes the general idea of entitas is great, the implementation needs a lot of work before it's ready to be used in a real environment by any other than the authors.
(that is how I feel)
movrajr @movrajr Jul 31 2015 17:09
Darn, now I feel like creating a new ECS framework :/
But good points fholm
Fredrik Holmström @fholm Jul 31 2015 17:11
Also, on the code generator it's almost impossible to extend a home-grown generator without editing the actual code of it in the library, where some people might want to add new generator behaviours, etc.
Using CodeDom is much easier, even tho the API of CodeDom is INSANELY explicit, it's a standardized interface that's easy to work with that doesn't form a bi-direction dependancy with entitas and the user code
Simon Schmid @sschmid Jul 31 2015 17:11
@fholm stupid question, but: have you even used Entitas?
Fredrik Holmström @fholm Jul 31 2015 17:11
*bi-directional
@sschmid for a real game? no, trying to integrate it to replace the glue code between my simulation and UI layer, yes
*simulation and render layer, yes
Simon Schmid @sschmid Jul 31 2015 17:12
when I have time I'd like to respond to all your statments
Fredrik Holmström @fholm Jul 31 2015 17:12
absolutely
by 'a real game' i ment a game that is launched and available for customers, I am working on a "real game", but it's not done, and I tried to use entitas in that.
Fredrik Holmström @fholm Jul 31 2015 17:19
Also I would love if some type of weak reference system existed to other entities/components
So that you can keep a reference around to it in another component, and when the object in the reference gets destroyed/removed/whatever, the reference gets cleared also
Arvid Backman backman Jul 31 2015 18:27
Isn
Isn't there some kind of way to force Unity to recompile?
Fredrik Holmström @fholm Jul 31 2015 18:27
how would it be able to compile if there are compile errors
Arvid Backman backman Jul 31 2015 18:28
Haha
I'm not quite sure how the code generation is done
But if you generate code the file changes?
Fredrik Holmström @fholm Jul 31 2015 18:29
yes but the generate code relies on the assembly being compilled already, to than have the code generate, and then be compiled again
Arvid Backman backman Jul 31 2015 18:29
If that is the case, couldn't you do AssetDatabase.Refresh()?
Fredrik Holmström @fholm Jul 31 2015 18:29
no
Arvid Backman backman Jul 31 2015 18:29
Ooh
Yeah. you're right
My bad!
Fredrik Holmström @fholm Jul 31 2015 18:29
Arvid Backman backman Jul 31 2015 18:29
Forget I said anything.
Or don't! I really don't have any street cred anyways
Fredrik Holmström @fholm Jul 31 2015 18:30
Andreas Wilcox @svdvorak Jul 31 2015 18:47
You guys have been chatty =)
A few thoughts regarding @fholm comments: I personally like the cleaner syntax that the code generation brings, considering most time is spent reading code you'd want it to be as easily readable as possible. But I do agree that you might easily get component creep in the Entity, having 150 components (as @mzaks mentioned before) sounds like it would make things a bit messy. Regarding code generation I'm personally fine with the workarounds for now but would be nice for it to run even when the project is not compiling though. Everything's always a work in progress =)
Fredrik Holmström @fholm Jul 31 2015 18:47
@svdvorak thing is tho, you can have the same clean API without code generation
As in, the code generation adds nothing right now other than overhead and issues
Andreas Wilcox @svdvorak Jul 31 2015 18:50
Generics I'm guessing as you mentioned before?
Fredrik Holmström @fholm Jul 31 2015 18:50
@svdvorak yes, that could be used for example
or just a simpe AddComponent(IComponent component) method
and then possibly have an two GetComponent methods, one generic and one non-generic
Arvid Backman backman Jul 31 2015 18:52
That's basically how we're doing it
With our ECS
Fredrik Holmström @fholm Jul 31 2015 18:53
yeah, it's a lot cleaner and nicer to use
Arvid Backman backman Jul 31 2015 18:54
public void AddComponent<T>(int entityId, T component) where T : Component
´´´
Andreas Wilcox @svdvorak Jul 31 2015 18:54
It's not a huge deal but I think I like entity.AddPosition(0, 0, 0) over entity.AddComponent(new PositionComponent(0, 0, 0)) but it's all preference. Atleast no reason not to have both.
Arvid Backman backman Jul 31 2015 18:54
woops
Andreas Wilcox @svdvorak Jul 31 2015 18:56
Why would you have to supply an entityId? That feels like plumbing leaking out of the API.
Fredrik Holmström @fholm Jul 31 2015 18:56
yeah i dont agree with that
Arvid Backman backman Jul 31 2015 18:56
With our solution the entity is basically just an int
I kinda agree
Fredrik Holmström @fholm Jul 31 2015 18:56
ah
Arvid Backman backman Jul 31 2015 18:56
But that's how we do it
Andreas Wilcox @svdvorak Jul 31 2015 18:56
Ah, gotcha =)
Fredrik Holmström @fholm Jul 31 2015 18:57
backman where do you work? (swedish name ;p)
Arvid Backman backman Jul 31 2015 18:57
I work at Tarhead Studio
Fredrik Holmström @fholm Jul 31 2015 18:57
ah, where in sweden?
Arvid Backman backman Jul 31 2015 18:57
A indie startup based in Skövde
Fredrik Holmström @fholm Jul 31 2015 18:57
Ah, I live close by
Skene (close to borås)
Andreas Wilcox @svdvorak Jul 31 2015 18:58
backman You guys sit in Gothia Science Park?
Arvid Backman backman Jul 31 2015 18:58
We are currently developing a game called Ruin
Fredrik Holmström @fholm Jul 31 2015 18:58
backman ah
Arvid Backman backman Jul 31 2015 18:58
Yeah! We sit in Gothia Science Park
Fredrik Holmström @fholm Jul 31 2015 18:59
I've seen it
backman interesting, I'm working on a similar type of game
Arvid Backman backman Jul 31 2015 18:59
Cool!
Fredrik Holmström @fholm Jul 31 2015 18:59
hopefully go up on greenlight within ~2 months
Andreas Wilcox @svdvorak Jul 31 2015 18:59
Kinda figured, a lot of indies there. Did my examination work at Ludosity Interactive many years ago.
Arvid Backman backman Jul 31 2015 19:00
Btw, forgot to mention. It is possible to add components via the Entity class aswell
Fredrik Holmström @fholm Jul 31 2015 19:00
it's not identical to Ruin, but some of the same concepts transfer and the same perspective/control scheme,e tc.
Arvid Backman backman Jul 31 2015 19:00
public void AddComponent<T>(T component) where T: Component
That's cool @fholm ! Is there anything you can show?
Fredrik Holmström @fholm Jul 31 2015 19:01
backman there is, but I am trying to keep myself detached form the game, as I don't want to be personally associated with it (did that mistake with Bolt, the fucking pain.. lol)
I'll show once it goes up on greenlight
Arvid Backman backman Jul 31 2015 19:01
Cool!
Sorry guys for getting of track from the channel topic!
Fredrik Holmström @fholm Jul 31 2015 19:02
Haha
backman you guys built your own networking solution yeah?
Arvid Backman backman Jul 31 2015 19:11
Yes, we did! We're using Lidgren do synchronize compnent data
Correction. We use Lidgren everywhere
Fredrik Holmström @fholm Jul 31 2015 19:34
backman cool
Maxim Zaks @mzaks Jul 31 2015 20:55
Hi guys,
I see we have a lot of discussion going on
I have however one favour to ask. Please try to keep it more to the point and less small talk conversational because if someone comes in and sees couple of dudes chatting around it feels like a chatroom and not like a professional forum anymore where you actually can get answers to specific questions.
I think we all would like this place to be informative. Today it kind of got out of hand
Anyways, I would like to address the most important point which was raised by @fholm the code generation and inconvenience that it brings with it.
First of all the code generator is not only about nice API it is also about performance. We had the generics based API before, and I still do in my Swift port of Entitas. However in with generic based API you have to do Dictionary lookups and they are slower than direct array access. But let's say that we ignore this small performance impediment. And we implement a generic methods.
In this case for being able to actually replace components in the entity, and you want to replace(remove and than add) component to the entity because of the observer pattern you would have to create a new component each time. Which means that old components will be garbage collected. And this is a performance hit that you don't want to have. You already mentioned somewhere that you use struct because of performance. Which helps because structs are less garbage. However garbage is garbage and you have to clean it up. The generated methods take care of the reuse of the components for you. So that we don't have garbage collector kicking in. This is a huge benefit. You can achieve it by writing a lots of boilerplates yourself. And this is actually what we did 9 months ago. Than we started generating methods which encapsulated all eh boilerplate stuff that you have to do for memory management. Just have a look at a generated ComponentExtension and you will see what I mean.
We will give some more answers on the questions, it's just hard right now to distill actually questions from casual conversation between couple of dev. That's why also my favour for keeping this chat as to the point as possible.
In the end we either have to take time to answer the questions or just searching for them
However we got the main takeaway. Code generation is hard specially when you are starting so we are thinking about solutions. And everybody is welcome to sketch a solution and create a pull request.
Arvid Backman backman Jul 31 2015 21:02
Thanks for the write-up @mzaks . And again, sorry for the off topic chatting :worried:
dweawyn @dweawyn Jul 31 2015 21:07
Regarding the performance with generics, I attempted to "cache" the index in a ComponentType<T> where T : IComponent. See here: github.com/dweawyn/Entitas-CSharp/tree/generics/Entitas/Entitas/Extensions
Maxim Zaks @mzaks Jul 31 2015 21:07
backman no worries
And I pocked around in old commits and here is an example of nice API which don't need code generation
github.com/sschmid/Entitas-CSharp/blob/0.1.0/Entitas/Entitas/Entity.cs
dweawyn @dweawyn Jul 31 2015 21:07
It's not much faster than a Dictionary<Type,int>
Simon Schmid @sschmid Jul 31 2015 21:11
Great to see the all your involvement! I’d like to respond to all the suggestions and opinions, but the chat starts to get a little bit messy. That's why I'd like to introduce some guidelines, trying to keep this chat informative and instructive, like it was just two days ago
I think it’s important to keep the chat clean, so also new ppl joining can pull some useful information out of it.
Please take your time and describe your questions / issues / suggestions / opinions
Check the github issues or scroll up, maybe your questions have already been answered, but of course feel free to pick up already discussed topics again, when you still have questions
If you have suggestions / improvements / doubts, keep on letting us know in the chat and maybe open a new github issue to discuss a specific problem / feature
Keep on pointing out things, that can be improved. If you have a solution for problems, even better: make a pull request.
Learning new things always takes time. We want to help you, to answer your questions, but please don’t state things, that are wrong or are only based on your „gut feeling“ rather than measurements, as this will confuse other users.
Move conversations about your lunch or your work to private chats and try to keep topics Entitas related
Fredrik Holmström @fholm Jul 31 2015 22:30
@sschmid Gotta say the attitude you and @mzaks have is a bit off-putting, people will always chat about off-topic stuff is medias like this, it's just the nature of it, being told off to basically shut up about it when it's was only me and backman talking and no one else was saying a word is well... off-putting.
And really, "please don't state things based on your gut-feeling", I mean... lol, who decides what is gut-feeling or not? Learn to take criticism of your library instead of responding with basically telling people to "shut up".
Anyway, this attitude is a good way of loosing early adopters and what not, I'm out. Take care.
Simon Schmid @sschmid Jul 31 2015 22:38
There will be a respond addressing all the points, but that will take some time. In the meantime I wanted to introduce guidelines to keep this chat focused.
Fredrik Holmström @fholm Jul 31 2015 22:39
That's good, but I'm out bye!
Simon Schmid @sschmid Jul 31 2015 22:40
That's fine! bye
Maxim Zaks @mzaks Jul 31 2015 22:40
@fholm Sorry if you take it personal, but the rules make sense so that every one can benefit from this chat.
zyzyx @zyzyxdev Jul 31 2015 22:46
hi! would entitas be suited for GUI heavy mobile apps? are there plans for doing a more gui focused example project?
Simon Schmid @sschmid Jul 31 2015 22:49
@zyzyxdev I think @mzaks can you tell you more about this. He actually build a mobile app for iOS with entitas for swift, which was UI only
Maxim Zaks @mzaks Jul 31 2015 22:52
@zyzyxdev we can think about an example for C#. In the iOS App, I used the data part of Entitas combined with Observer mechanics. In UI heavy application you don't necessary need systems which are executed on each tick in the run loop.
here is the link to the iOS App I did for a conference I am co-organizing.
github.com/UIKonf/uikonf-app
It's not a beauty and it's in Swift but maybe that helps somehow
zyzyx @zyzyxdev Jul 31 2015 22:53
thanks!
I come from a mvvm background so this is quite a new way of thinking
Maxim Zaks @mzaks Jul 31 2015 22:59
Well in MVVM view model is basically a way of representing view in a logical way. If you have a flexible way of representing data you don't need this separate abstraction. You can have just different components on one entity, some are data related some are view related. It might feel like you mixing concern but in reality you don't. The code working on different components should be separated.
Hm I guess it is a bit harder to explain. I wrote a Blog series where I tried to address this ideas
medium.com/@icex33/think-different-about-data-model-7c0ca0879864
zyzyx @zyzyxdev Jul 31 2015 23:04
I see, thanks again!
Simon Schmid @sschmid Jul 31 2015 23:05
btw, added a wiki page for the roadmap. A few things we discussed are already listed
github.com/sschmid/Entitas-CSharp/wiki/Roadmap
movrajr @movrajr Jul 31 2015 23:30
Regarding Roslyn, that might be a can of worms: forum.unity3d.com/threads/c-6-0.314297/