special_ed

Members
  • Content count

    3
  • Joined

  • Last visited

  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.
  2. I've spent the past two years using JavaScript almost exclusively. Before JavaScript, I spent about 8 years working mostly with Java, C, C++, and Python. Here are my own recommendations, based on these past 2 years: #1 Don't take anyone's word as gospel. Don't take my word as gospel either. JS is a very flexible language. There's a lot of freedom to do things in a lot of different ways. No one is in agreement about JavaScript best practices. Very smart, popular people within the community will oftentimes directly contradict each other or just change their minds. Don't think that you're not a newb because you read a book, read a tutorial, or watched a video where the author promised to take you from beginner to intermediate, or intermediate to advanced - none will. You'll have to take in around a dozen of those resources and work on at least half a dozen significant projects before you're not a newb. #2 Learn functional programming. To a certain degree, this is essential for JS developers because a lot of it's power comes from it's functional aspects. To a certain degree, it's not that essential because of the aforementioned flexibility and ability to write in or mimic multiple paradigms. Anyway, just do it, if for no other reason than the fact that your first language was likely an object-oriented language with classical inheritance like Java or Python. In which case, you may struggle when you brush up against functional concepts or codebases - don't act like you already know everything. The functional programming priesthood will say that classical inheritance, the "new" keyword, mutable state, and impure functions are the devil. I'm not sure if that's the case and I find a lot of their arguments about it kind of porous. Regardless, you should definitely at least learn how to do what their espousing and recognize when it'll save you from headaches in your own code. #3 Go ahead and start using ES6+. You certainly don't have to.. You can write in ES5 and everything will be fine. The majority of tutorials out there will be in ES5, as will most libraries, frameworks, and codebases. If you're interested in game development, however, then I imagine that you're someone who likes to be ahead of the curve. Using ES6+ will force you to start using things like Node, npm, and the various tools related to transpilation. The ability to create modules is also a default part of the language, and that will help you architect your code base in a fashion similar to other languages that support imports/exports by default. You might also discover that ES6+ is just better than ES5. I'd further recommend using Webpack (with Babel and eslint) and configuring so that everything is compiled and the browser is refreshed every time you save a file. #4 Find an editor or IDE that works for you. I've used many. I don't like most of them. Right now I use Vim and occasionally Atom when I'm feeling lazy. I'd recommend Atom for beginners. I'd recommend Vim for people who quickly discover that they hate most editors and IDEs, making sure to pimp it out with lots of plugins to bring common IDE-like functionality. #5 Go ahead and start using Git and GitHub. Make sure that you know what you're doing. Start committing as often as possible and put the link to your GitHub on your resume, portfolio, or LinkedIn page. If you're not doing these things, then you're going to look dumb to most people if you start shopping around for a job. #6 Don't get too distracted by the JavaScript community. There are a lot of people with a lot of different ideas. There are a lot of frameworks, libraries, and tools. There's more than one version of JS that people are actively using and some people essentially compose their own. People are compiling/transpiling JS from a variety of other languages. People are writing JS for the front end, back end, mobile devices, smart TVs, embedded systems, and more. Front-end web development, however, is where it all started and most within the community still come from that mindset - be wary of them, especially since you want to be a game developer. I personally think that web app development has a lot to learn from the history of game development because web apps are obviously becoming increasingly complex with graphics and interactivity. You might discover that after developing games, you'll have a leg up on other web developers for their own jobs.
  3. Image editors for Mac as of late 2016

    Sorry if this is a relatively beaten to death topic. I've already used the search function. I'm looking for a new image editor to use for editing pixel art and sprite sheets. I'm running OS X Sierra on a Retina MacBook Pro (2.3 GHz quad core, 8 GB Ram, GeForce GT 650m 1GB). I've already ruled out the following commonly recommended editors: Photoshop CC - I consider this the best image editor, all things considered. However, I'm broke, unemployed, and not willing to pay for it. I'm also not willing to install pirated Adobe products. GIMP 2.8 - Before I was an art student and in love with Mac + Adobe, I was a computer science major who exclusively used Linux. Over this period of time, I got acclimated to GIMP and considered it a pretty good, free, and open source alternative to Photoshop. As of 2016, however, it's borderline useless. Most of the functionality I want is theoretically there, but it suffers from performance problems, bugs, and crashes. Earlier today, it crashed about a dozen times when I was editing very, very small sprite sheets and I've finally had enough of it. Krita - This isn't a terrible alternative to GIMP. It doesn't suffer from as many problems on my system, but they're still there. The interface is also not as intuitive as I'd like it to be. I spend way too much time just learning how to use it. What free image editors do you recommend for OS X? If they're geared towards pixel art that would be best. My needs at the moment aren't terribly complex: #1 Draw/erase pixels of various sizes. The tools in many editors default to "fuzzy" or "dynamic" behavior that can be annoying to disable. Managing transparency can get annoying in some cases, so it would help if it defaulted to transparent backgrounds and erasing to transparency. #2 Resizing the canvas/image. It seems simple enough, but GIMP would frequently crash. #3 Selecting rectangular areas and easily cutting/copying/pasting/rotating them within a sheet. #4 Configurable grids. "Snap to grid" behavior for drawing/erasing/selecting. If this isn't present, then #1 and #3 are a pain. #5 Robust color selection. Pick colors from images/area of screen (even in other applications). Save color history. Save palette of colors. GIMP was problematic here.