Chief

Members
  • Content count

    62
  • Joined

  • Last visited

  • Days Won

    1

Chief last won the day on November 26 2016

Chief had the most liked content!

1 Follower

About Chief

Profile Information

  • Gender
    Not Telling
    1. Show previous comments  1 more
    2. The Pop Punk Pizza Pirate
    3. jcsnider

      jcsnider

      Reported to Google as a site containing ransomware, malware, and music that causes ears to bleed.

    4. MCADAMS
  1.  

    1. The Pop Punk Pizza Pirate

      The Pop Punk Pizza Pirate

      Why do you do this shit to me? This shit was so fucking cheesy.

  2. I added you on skype through my business account, hit me up when you're free. I got some node questions for you.

  3. I made a thing (Image)LCmNbLT.jpg

    1. Dr.House
    2. The Pop Punk Pizza Pirate

      The Pop Punk Pizza Pirate

      phen just tried to one up you in his status.

  4. Thinking about it now, I think one component per attribute is the right way to go about it. It makes it super easy to generate a game from data. In other news, I've completely rewritten everything. I've turned it into a library that you can find here: https://github.com/eclipse-games/encosy -- the following are real, working examples, utilizing the library: Component (Position) import { Component } from '@eclipse-games/encosy' export default new Component({ x: Component.types.number, y: Component.types.number, z: Component.types.number }); Entity (Character) import { Entity } from '@eclipse-games/encosy'; import Position from '../components/position'; import Size from '../components/size'; import Texture from '../components/texture'; export default new Entity({ position: Position, size: Size, texture: Texture }); System (Render) import { System } from '@eclipse-games/encosy'; import state from '../core/state'; import Position from '../components/position'; import Size from '../components/size'; import Texture from '../components/texture'; export default new System([ Position, Size, Texture ], (world, entity) => { const position = world.components.get(Position).get(entity); const size = world.components.get(Size).get(entity); const texture = world.components.get(Texture).get(entity); state.drawContext.drawImage(texture.data, texture.clip.x, texture.clip.y, texture.clip.width, texture.clip.height, position.x, position.y, size.width, size.height ); }); I think I got the concept fully down now, and am pretty pleased with the outcome of this weekend curiosity. Definitely let me know your thoughts on ECS vs OOP.
  5. I've made some modifications to my concepts to improve performance. The first is of entities; they are no longer each their own class; now they're just a module with a create method that instantiates an Entity; making all entities an instance of a single class allows the JS engine to optimize storing them in memory, and also simply means less classes. import Entity from '../core/entity'; import Position from '../components/position'; import Size from '../components/size'; import Texture from '../components/texture'; export default { create (world, { position, size, texture }) { const character = new Entity(); world.entities.add(character); world.components.get(Position).set(character, new Position(position)); world.components.get(Size).set(character, new Size(size)); world.components.get(Texture).set(character, new Texture(texture)); return character; } } The next optimization is of services. You now instantiate a Service with a list of required components and a function that will be called if all required components exist for that entity. I also made it so services only take one entity at a time so you need to loop through all entities beforehand, which means looping over them far less frequently, increasing runtime performance. import System from '../core/system'; import Position from '../components/position'; import Size from '../components/size'; import Texture from '../components/texture'; export default new System([ Position, Size, Texture ], (world, entity) => { const position = world.components.get(Position).get(entity); const size = world.components.get(Size).get(entity); const texture = world.components.get(Texture).get(entity); world.state.get('drawContext').drawImage(texture.data, texture.clip.x, texture.clip.y, texture.clip.width, texture.clip.height, position.x, position.y, size.width, size.height ); }); As you can see, the first argument is an array which contains the required components. You run a system by calling its run method, which will check for the existence of components of an entity, like so: export default class System { constructor (mask = [ ], action = (() => null)) { this.mask = mask; this.action = action; } run (world, entity) { const { components } = world; if (this.mask.reduce((prev, next) => prev && components.get(next).has(entity), true)) { this.action(world, entity); } } } No modifications have been made to components, as they're still just data. The next concept I want to explore is instead of having one component per character attribute (health, experience, magic, etc), finding some way to have a generic Attribute component, but I'm not sure how that will work quite yet.
  6. In the past, I have always written games/engines in full-on OOP, but I stumbled upon an architecture that purports to be widely used when it comes to games, which I'm sure you are all aware of, but I was not. Entity/Component architecture is supposed to help with issues of having large hierarchies of inheritance when it comes to entities, like a character. Following this article from Gamedev.net (https://www.gamedev.net/resources/_/technical/game-programming/implementing-component-entity-systems-r3382), I've recreated what I understand to be an Entity/Component architecture in JavaScript. First of all, the article created a core World object that contains a list of all current entities in the game, and then weak maps (I'll explain this momentarily) of the components of each entity. In JavaScript, this looks like the following: import Position from '../components/position'; import Size from '../components/size'; import Texture from '../components/texture'; const { Map, Set, WeakMap } = global; export default class World { options = new Map(); state = new Map(); entities = new Set(); components = new Map([ [ Position, new WeakMap() ], [ Size, new WeakMap() ], [ Texture, new WeakMap() ] ]); } As you can see, components is a Map of <ComponentClass, WeakMap>. What a WeakMap allows, is that if the key exists nowhere else in memory, the WeakMap will allow it to be garbage collected. The WeakMap is essentially <Entity, Component>, so if the entity is deleted from the world's entities Set, then it will automatically be garbage collected, preventing memory leaks. The second part of this architecture is a Component. Components are strictly made up of data, and combined together as a group, make up an Entity. A simple example of one in JavaScript would be as follows: export default class Position { constructor ({ x, y, z = 0 }) { this.x = x; this.y = y; this.z = z; } } The third concept, of course, is an Entity. Now, an Entity isn't actually anything more than an identifier that components reference in order for services to work (I'll cover services next). Basically, Entity/Component architecture prefers composition, so I have a create method that takes configuration, and creates components. In JavaScript, this looks like: import Position from '../components/position'; import Size from '../components/size'; import Texture from '../components/texture'; export default class Character { static create (world, { position, size, texture }) { const character = new Character(); world.entities.add(character); world.components.get(Position).set(character, new Position(position)); world.components.get(Size).set(character, new Size(size)); world.components.get(Texture).set(character, new Texture(texture)); return character; } static delete (world, character) { world.entities.delete(character); } } You can see that Character is still a class, and is instantiated inside of the static create method, but this is simply to create a unique entry in memory that the services can correctly find all of the components of an entity. The most complicated (it's not complicated) part of this architecture are the services. Services are just functions that you call that act upon entities. An example of a render services looks as follows: import Position from '../components/position'; import Size from '../components/size'; import Texture from '../components/texture'; export default function render (world) { const { components, entities, state } = world; for (const entity of entities) { const position = components.get(Position).get(entity); const size = components.get(Size).get(entity); const texture = components.get(Texture).get(entity); if (!position || !size || !texture) { continue; } state.get('drawContext').drawImage(texture.data, texture.clip.x, texture.clip.y, texture.clip.width, texture.clip.height, position.x, position.y, size.width, size.height ); } } As you can see, for each entity, it checks if that entity has the required components, which in this case are Position, Size, and Texture. If all three exist, it uses the data from those components to draw the entity onto our canvas, using the drawContext. To all who are familiar with this architecture and OOP; does this seem right to you? Have you used Entity/Component architecture before? Do you prefer OOP?
  7. Node JS

    PM sent; thanks for offering your help!
  8. Node JS

    Anybody else want to help? This is the last call; I'll be opening the forums for a more public alpha in a couple of weeks.
  9. Looking for Work

    Dyldo2 is the best programmer I know. If funds weren't so tight right now (just dropped 3k on adult bills and car things), I would totally hire him.
  10. Node JS

    PM sent to you both as well
  11. Node JS

    I'm gonna address a couple of the bugs/features that others have called out so far, then I will send you a PM
  12. Node JS

    Messages sent to you both; I have no reason to not let anybody help me out; I just don't want it to seem like I'm just posting in order to advertise; that's not my goal. I really just want help testing my site.