groutxo Posted February 22, 2014 Share Posted February 22, 2014 First of all, hello everyone. First time posting, since I started with html5 a bit ago. I'm planning an ECS on JavaScript and, because of my little experience with JS, I'm getting into a few concerns. I'm new to JS, so I may be missing some JS technique that could help me to handle this. Anyway, I'm trying to keep myself informed on JS language inners, so that I can get as much power as I can from it. I suppose everyone knows what an ECS is. Anyway, I'll explain at least how I understand it. An ECS is composed of Entities, Components and Systems. Components are data, entities are bags of components, and systems just operate on entity components it's interested in to apply some kind of logic. It's also well explained on this post. What I currently planned for entities and components was something like this (syntax may not be the correct, but the point is just to show the idea):var NormalShipEntity = { positionComponent: { x: 0, y: 0 }, velocityComponent: {....}, shootComponent: { shootrate: 30, shoottype: derpl }, lifeComponent: { health: 100 },}var InnocentShipEntity = { positionComponent...., velocityComponent...., lifeComponent....}Here, I have created two kinds of entities that both are ships, but one has a shootComponent and the other doesn't, so here is the real sugar of ECS: you can create new entity models by composing them of components, and getting rid of a deep level hierarchy. Now, the question is about systems, that are the real code acting on entity components. There are two main approaches when applying system functionality to entities:Iterate once over all entities and, foreach entity, check all systems against it. This checking implies to know if the system has to process this entity. For example, a MoveSystem needs positionComponent and velocityComponent: if one of them is missing, the MoveSystem doesn't act on that entity. Register each entity in a per-system list, so that each system has the entities that it has to iterate, and the check is made just once, but the iteration over a single entity will for sure be multiple if it has several systems that have to process it.The approach I want to take is the first one. So here's some pseudocodeforeach( entity in entityList ) { foreach( system in systemList ) { if( system.HasToProcessEntity(entity) ) { system.process( entity ); } }} Now, my issue comes within that HasToProcessEntity method within System. The first thing I thought was to use the hasOwnProperty over all components the system needs, and if everyone succeed, then return true and process the entity with that system. I know a pretty straightforward way to make the check is with bitmasks, but there may be a better choice using JS. I'm mainly concerning about performance on hasOwnProperty. Also, if anyone could throw a bit of light on how to accomplish this without using hasOwnProperty, or tell that hasOwnProperty will be just fine, would be appreciated. Thanks in advance. Quote Link to comment Share on other sites More sharing options...
anissen Posted February 23, 2014 Share Posted February 23, 2014 I simply use a filter-function on my list of entities, like this:MotionSystem = { tick: function(entities, deltaTime) { entities.filter(function(e) { return e.position && e.motion; }).forEach(function(entity) { entity.position.x += entity.motion.dx * deltaTime; entity.position.y += entity.motion.dy * deltaTime; entity.position.rotation += entity.motion.drotation * deltaTime; }); }};I am not concerned about performance as of yet - if that becomes an issue at a later point then I'll handle it then Quote Link to comment Share on other sites More sharing options...
groutxo Posted February 23, 2014 Author Share Posted February 23, 2014 Thanks for your response. I think I'm going to do something very similar to what you posted, but iterating over systems foreach entity:Engine = { tick: function() { entities.forEach(function(e){ systems.forEach(function(s){ if(s.performsOver(e)) s.tick(e); }) }) }};MotionSystem = { tick: function(entity, deltaTime){ entity.position.x.... // more }, performsOver: function(e){ return e.position && e.motion; }};Could this perform worst than your approach anyhow? I may be doing something wrong, I'm noob at JS. Anyway, I've just learned a few tricks from you, thanks for that too. Btw, I took a look at ld28, good job with that! I hope I'm also doing stuff early. You code everything by yourself, don't you? I've seen lots of libraries when arrived this territory (sorry for the offtopic ). Quote Link to comment Share on other sites More sharing options...
brejep Posted February 27, 2014 Share Posted February 27, 2014 I don't know if you know Ash (an Actionscript 3 entity-system framework) - https://github.com/richardlord/Ash - but I ported it over to Javascript - https://github.com/brejep/ash-js - and it has an interesting approach to the problem you are describing. In Ash, a system gets a linked list of nodes that it can update. These have already been filtered by the engine. A node is a tick list of components that a system might need to update. For example, a collision system might require references to spaceship collision nodes and bullet collision nodes, where a spaceship collision node has a reference to any entity that has a position component and a spaceship component and a bullet collision node has a reference to any entity that has a position component and a bullet component. For a simple example see: https://github.com/brejep/ashjs-asteroids-example Quote Link to comment Share on other sites More sharing options...
Ezelia Posted February 27, 2014 Share Posted February 27, 2014 I'm presently using an internally developed ECS engine for my games and I'm releasing it's code.I have another approach to identify witch entity have to be updated with witch system.actually. an entity in my implementation is just a holder object with an ID and primitive function to add componnents to.then I have systems (I call them modules in my implementation), each module "watch" one or more components.when an entity adds a component, it is bound to the modules that handles this component.in my main loop, each module have a list of only entities it should update.an first implementation can be found here : https://github.com/Ezelia/eeethis code is a little outdated, but it has the implementation I described above I just started a wiki : https://github.com/Ezelia/eee/wiki the included demo can also help https://github.com/Ezelia/eee/tree/master/demoalso, to have fast entities loops, I use for (; syntaxt instead of for-in , to make this possible I implemented this HashMap https://gist.github.com/alaa-eddine/6317515 witch share properties of both JS arrays (fast loops) and JS objects (key/value access).hope it'll help Quote Link to comment Share on other sites More sharing options...
groutxo Posted March 2, 2014 Author Share Posted March 2, 2014 @brejep: aha, so you check on entity creation if that entity has the components of a node, and if it does, you attach it to the system list that wants those kind of nodes, am I understanding right? I guess that your update is done foreach system. I'll take a look at your code anyway. @Ezelia: first of all, the post you made some time ago about ECS has been what encouraged me to ask here, so I'm not entirely new with your way =). So your approach is, you have Entity being just an ID and components that have the Entity ID associated. Then, on Entity creation (addition of components), you check in which modules (system) the Entity needs to be processed and add it to these modules own list. Anyway, I'll take my time to read your code and your wiki. Thank you two, it's been of great help. I have not still started with my ECS because of not having time, but everytime I coded a line more in my game (that was before I started the post sadly), I couldn't stop thinking about this way of organising stuff, and more if we take into account the JS language, it seems perfect for this approach). I'm also caring about performance just because the game I'm working on, could have ~120 entities, and maybe a max creation/deletion ratio of 2 or 3 per second, so I wanted to stay sure in this. Thanks again, this forum is being a big help =) Quote Link to comment Share on other sites More sharing options...
Ezelia Posted March 3, 2014 Share Posted March 3, 2014 @groutxo : here is an article to start with http://alecmce.com/library/why-use-entity-systems-for-game-engineering, there are so many articles about ECS, but this one is short and explain in a clever way what's ECS and what's it's main differences to OOP hope it can help you.btw, I have a game with around 22000 alive Entities (about 320 entities drawn each frame thank's to viewport cropping), with pretty hight deletion ratio and it works very good ... 60 FPS on modern browsers, and between 30~50 FPS on mobile (depending on models) the slowdown you can get, will not be because of ECS, but of other "classic" performance issues, so if you follow good practices to eliminate them, you'll get good results anyway. EDIT: I'm currently working on a total remake of my game "Germiz" using ECS, it'll support desktop, mobile, cocoonjs wrapper, and everything I learned from this forum to make a multi-platform HTML5 game. thank's to ECS I was able to completely separate the game layer from device adaptation layer ... after the game publication (maybe next weeks ... months depending on my time), I'll publish an article about the game structure and how ECS made some features simple, and some other more complex (or at least less natural for an OOP developer) Quote Link to comment Share on other sites More sharing options...
groutxo Posted March 3, 2014 Author Share Posted March 3, 2014 @Ezelia: it's good to know about your numbers, now I know I'm not mad or anything! Waiting for your article, in the meantime I'll read that last one you posted. So great, I hope I can finally go with JS again and try it (time, time, time... but anyway, a good plan before starting to re-code isn't any bad). My experience with ECS was a bit bitter. I tried some test on C++ but never finished it. Now that I've tried JS and HTML5 a bit, I see how easy it can be achieved here, because of the nature of the language and the ECS itself, and this information is greatly helpful. Also, I'll take a deep read to that link, as you said, there's lots of sites where you can get info about ECS, and this may be confusing (at least to me). Thanks for everything, and go on with your "Germiz" remake and your whole ECS project! P.D.: I've played Germiz for a considerable time by now, it's addictive Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.