OttoRobba Posted November 13, 2014 Share Posted November 13, 2014 Hi fellas! I wrote a quick tutorial introducing the basics of ECS (entity component system) focusing on game design and javascript, it is something that I wish I had understood way (way) earlier and I thought it might be helpful for others. Let me know what you guys think! Sir_Everard, Paolo Di Stefano and d13 3 Quote Link to comment Share on other sites More sharing options...
d13 Posted November 13, 2014 Share Posted November 13, 2014 I really like your approach: extremely clean and simple.Most of the other ECS examples for JavaScript that I've seen port a whole bunch of labyrinthine, ceremonial OOP from Java or C++ that just isn't necessary. But your system is extremely clear and exact:Entities: Plain old object literals.Components: Plain old decorator (mixin) functions.Nice and simple OttoRobba 1 Quote Link to comment Share on other sites More sharing options...
OttoRobba Posted November 13, 2014 Author Share Posted November 13, 2014 I really like your approach: extremely clean and simple.Most of the other ECS examples for JavaScript that I've seen port a whole bunch of labyrinthine, ceremonial OOP from Java or C++ that just isn't necessary. But your system is extremely clear and exact:Entities: Plain old object literals.Components: Plain old decorator (mixin) functions.Nice and simple Does that first example work?Or should it be:var Hero = function() {//...}; Wow thanks EDIT: Ah, I see the mistake (I was in a hurry when I read your reply). Fixed it! Quote Link to comment Share on other sites More sharing options...
Sir_Everard Posted November 15, 2014 Share Posted November 15, 2014 Nice article. I like your writing style. Perhaps your next tutorial could expand this model to include prototypes and a form of inheritance.Good work OttoRobba 1 Quote Link to comment Share on other sites More sharing options...
Bruno Assarisse Posted November 19, 2014 Share Posted November 19, 2014 I like your approach. I'm using a self-made ECS on my game too, but it isn't simple as this one =/ Just one js nitpick: I'd change the check for health (this.health !== null) to use the typeof operand. Quote Link to comment Share on other sites More sharing options...
OttoRobba Posted November 19, 2014 Author Share Posted November 19, 2014 Nice article. I like your writing style. Perhaps your next tutorial could expand this model to include prototypes and a form of inheritance.Good work I definitely want to expand on it, bit short on time now (working on a few cool things to use with Phaser) but will do later I like your approach. I'm using a self-made ECS on my game too, but it isn't simple as this one =/ Just one js nitpick: I'd change the check for health (this.health !== null) to use the typeof operand. The simplicity behind this system is mostly for education's sake - I'm applying it to Phaser and the nature of the build tools and the framework itself demanded a few changes. Provided your self-made ECS works, you are fine.Also, you are right about the typeof operand, it is a good fit here! I'll fix the post later Quote Link to comment Share on other sites More sharing options...
Felipe Posted November 19, 2014 Share Posted November 19, 2014 Really nice tutorial. Thanks for sharing it!I've been using ECS for a while now and I really enjoy using it for large projects as it's very modular. One thing that I added to my own engine is that you can pass components to the entity contructor. Currently what I have is something like this: var bindFunc = function (func, object) { if (typeof func.bind === 'function') { return func.bind(object); } else { return function () { return func.apply(object, arguments); } } }, Entity = function () { var components = Array.prototype.slice.call(arguments), init = function () { components.forEach(function (component) { if (typeof component === 'function') { component(entity); } }); }, entity = { /*Have what ever you want here*/ }; init(); return entity; }, Component = function (name, properties) { return function (entity) { entity[name] = entity[name] || {}; Object.keys(properties).forEach(function (key) { if (typeof properties[key] === 'function') { entity[name][key] = bindFunc(properties[key], entity); } else { entity[name][key] = properties[key]; } }); return entity; }; };var Render = Component('render', { draw: function (graphics) { // draw stuff! } }), Position = Component('position', { x: 0, y: 0 }), myEntity = Entity(Render, Position);myEntity.render.draw(myGraphics); OttoRobba 1 Quote Link to comment Share on other sites More sharing options...
OttoRobba Posted November 21, 2014 Author Share Posted November 21, 2014 Your code is really interesting, quite different from what I would do, thanks for sharing, I learned quite a bit from it!It is quite clever. I applied some of what I learned from it into a gistvar componentsList = {}; function Component(name, func) {componentsList[name] = func;} //Components are created like this:Component('flying', function(o) {o.flying = true;}); var entitiesIDs = []; function addComponent() {for (var i = 0; i < arguments.length; i++) {if (typeof arguments[i] === typeof []) {for (var j = 0; j < arguments[i].length; j++) {componentsList[arguments[i][j]](this);}} else {componentsList[arguments[i]](this);}}} function Entity() {var obj = {addComponent: addComponent,id: entitiesIDs.length};entitiesIDs.push(obj.id);addComponent.apply(obj, arguments);return obj;} //Entities are created like this:var user = Entity('flying'); //Bundles are made with arrays:var orcs = ['health', 'collision', 'enemy', 'ai', 'armed', 'green'];var enemy1 = Entity(orcs); //You can combine multiple bundles and strings:var enemy2 = Entity(orcs, 'rage', undead, 'axe'); 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.