Jump to content

Search the Community

Showing results for tags 'functional programming'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • HTML5 Game Coding
    • News
    • Game Showcase
    • Facebook Instant Games
    • Web Gaming Standards
    • Coding and Game Design
    • Paid Promotion (Buy Banner)
  • Frameworks
    • Pixi.js
    • Phaser 3
    • Phaser 2
    • Babylon.js
    • Panda 2
    • melonJS
    • Haxe JS
    • Kiwi.js
  • General
    • General Talk
    • GameMonetize
  • Business
    • Collaborations (un-paid)
    • Jobs (Hiring and Freelance)
    • Services Offered
    • Marketplace (Sell Apps, Websites, Games)

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Website URL


Twitter


Skype


Location


Interests

Found 1 result

  1. How many of you have experience developing games with an entity-component-system pattern? How about writing games in general with functional programming? It would be especially interesting to me if you have experience combining both. TL;DR (this is back story, feel free to skip) I have this very simple and crude frogger style game that I've been toying with. I have a plan for turning it into something a lot better, starting as the relatively simple and recognizable game that we're so used to and likely not interested in (all of this functionality is already finished) but then quickly ramping it up in weirdness (which I have well outlined to avoid creeping my own scope). However, some might say that I've been "sidetracked" in the development process because of my desire to experiment with and learn new things.. I've literally rewritten the game from scratch 5 times in the past week. It's sort of okay because it's still small, but it's also one of the first things people tell you not to do when writing games. I, on the hand, am more interested in these rewrites and what I'm learning from them than progressing in the game right away. Part of it is my inclination towards learning and experimentation, and part of it is knowing that it can have practical dividends that might not be apparent because I'm preventing problems that I might have when the project grows in size and complexity. Object-orientation My game started in a very typical ES5 object-oriented style where I used the "new" keyword. My first major revision was porting everything to ES6+ (for built-in module system with import/export, never ending a line with a semi-colon, object spread operator, etc). When doing that I started using ES6s new class syntactic sugar, but something about it reminded me of the idea spread by FP evangelists that we as JS developers should never use the "new" keyword and that class based inheritance is a bad idea.. I then rewrote everything to use functions that return objects (factories) instead of classes. Some object types needed their own custom prototype object and used Object.create() (ones that are created a lot and have shared functions), while others didn't and simply were created by my own function that returned an object literal. This caused me some headaches because of the general lack of consistency in the way I was creating objects and how they were actually structured and accessed. The ones which weren't made with Object.create(customPrototype) required getter functions for methods to access attributes which were block scoped within the factory function by let, while the others didn't and their methods could access similar values through "this". Entity-component-system I then stumbled on the ECS pattern while Googling about why the MVC pattern is rarely employed in games (in the web community, MVC is the only pattern that some people know and they try to religiously apply it to everything). The most interesting aspect of ECS to me is that it was originally devised as a solution to the problems introduced by classical inheritance (which many JS developers also see as a problem), but their solution was radically different than prototypal inheritance (also solving the problems that might be introduced by prototypal inheritance, such as a failed property lookup recursing down the entire prototype chain). The gist of ECS is that an entity is what we might commonly think of as an object. They're really no more than a unique identifier (typically an integer). Despite being nothing more than a number, you can construct "classes", "templates", or "assemblages" for actually associating these numbers to data (components), and groups of related functionality (systems). An entities position, velocity, and acceleration within the game would each be a component. Rendering and physics systems would then operate on these values and more to draw them to the screen and calculate new state. ECS is an abstract idea, and thus wherever you look at implementations, you'll see things understood and coded very different. One common idea is that systems are associated to only one component, such as the rendering system to a "renderable" component with "renderable" being a key in an object. The key could itself be an object with all the values the rendering system needs (thus giving a degree of data privacy if necessary), but others simply have it as a standalone value and require other ways of making sure that the rendering system has access to what it needs and not to what it doesn't (or the latter idea escapes people entirely). Some people also let systems traverse the entire set of all entities each frame in a game loop to see if they have the component of interest. This in particular was disturbing to me, so I opted for the idea of simply adding/removing an entity to a register of entities that a system traverses. On top of cutting down on unnecessary operations, this also allowed me to discard the idea of components such as "renderable", "updateable", and "animatable". This bugged me because of the ambiguity about what their actual value should be and whether or not certain values (such as position) would need to be duplicated in the case that their values would be objects to which that system was restricted. All of these issues hint at another big implementation ambiguity: How do you actually store all of this information, and where? I still haven't quite ironed this out. I also haven't quite ironed out where some of the related functionality will come from (such as having it abstracted to a part of the game engine). Since this is JavaScript, the data structure decision is between objects and arrays. Each has inconsistent performance tradeoffs because of the functions that operate on them and how this varies between browsers. On top of data structures and operational functions, there's also the question of just how many you'll actually need.. One article recommended a wide variety: one for just entities, one for just components, one for entity-component mappings, N (number of components) to store the actual values of the components, and then further ones for all "assemblages" and assemblage/component mappings. This seemed a little unnecessary to me, but after further thought it depends on the particular game and the resources available to the game. That author was coming from the world of MMORPGs, so it makes sense. Here's the article. My game is single player and state, at the moment, is being stored entirely in memory. Regardless of how much further I progress the game, it will never reach the point where I'm dealing with even hundreds or thousands of entities. I'm therefore not too interested in having all of these data structures floating around. Keeping one for all entities and all components seems like a prudent thing to do even if they're unnecessary, and I'm currently thinking that it could be stored along with generalized entity and component functions within a part of my engine (in the same manner that I store cached resources in the engine itself). What I'll almost certainly need access to frequently is a mapping of entities to components along with their values with the "primary key" being either entities or components (depending on everything else). Conceptually, to me this is a 2D jagged array: indexed by entity, with each index pointing to a list of component-value pairs. Of course, this is JavaScript, so an array would have an integer index making it more suitable for a component->entity:value type of arrangement (since entities will likely come and go while component definitions remain static). At the moment, there's no need to query by entity to get all components, which would be slow if the entity weren't the primary key. This would slow down a systems ability to look up the value of a component if a quick way to access it isn't registered. I'm thinking that any given system should generally know what components it needs to access (exceptions to this are certainly possible). A general registration process should be capable of handling everything. For instance, a rendering system might require an entities "position" component, but how do we know it knows the right name and that the name is in fact the right name? This points towards the need for either verification in the process of creating an "assemblage" (good for larger projects, especially if they have a custom interface for non-technical people to compose assemblages, which was one of the original goals of the pattern), or through a process of registration with the system (good in my case). I could get away with doing neither by simply naming everything correctly, but since registration also gives me a form of data privacy for free, I think I'll do it. Functional Programming I'll write more here later, since I have to leave. I've been looking at various aspects of my code and asking myself, "how could I do this more functionally?" This generally means, "how can I store and access state such that I'm not mutating values?" Furthermore, it leads to, "how can I make sure that this doesn't drastically limit performance?" General thinking now is to minimize the impact of state changes (which can be costly because of how often the game loop runs). One idea of mine has been to fragment state into discrete units (3-tuple or even just a pair) so that the common functional method of generating new values rather than mutating old ones is less expensive. Not sure if this will work yet or how to do it if it's possible, but my first guess is this: seed systems that operate on state with initial values during registration, then if there's a change later have them forward an entirely new value to the next iteration of themselves. At first glance, I think this has issues. A 3-tuple might work, but pairs need to be associated. If the system is a single function, then even forwarding new pair values to the next iteration would mean mutating an array or object in which they get their association. I could always forward a new copy of the entire array or object, but that's what I'm trying to avoid. Maybe a creative reorganization of the system itself could work to make pairs possible.. My conception has always been of a system as a collection of functions that iterates through it's register of entities performing operations for each one. An alternative would be the registration process setting up an array of systems to operate. Egh. Gotta go.
×
×
  • Create New...