March 10, 2017
The biggest reason Arman and I (Abstract Studio) chose HTML5 for our engine is that we wanted to avoid compatibility issues between different operating systems as well as skip annoying processes such as download and installation. After this ideology inspired the platform for our first web game, Calcfighter, we wanted to formalize what we had learned from the development process into an actual engine, with which we could write further games.
Based on both trial and error as well as a significant amount of reading about game design patterns, the engine is composed of one two main loops and four primary components. The loops, of course, are the tried and tested render and update loops, which run in separate, callback-based threads in order to rely on native, optimized looping. The components, on the other hand, are a little less traditional, and are as follow:
The asset manager is responsible for asynchronously queueing and loading resources such as images and sounds into the engine before proceeding into gameplay. It provides intuitive file labelling, which results in easy access to resources once loaded. Although we shifted between implementing these components as parent classes of the engine, the actual code behind the asset manager prompted us to keep it as a member in order to keep shorter, more meaningful method names and cleaner code separation.
The input manager handles the page and canvas, providing cursor lock, full screen, mouse tracking, and keyboard detection, primarily through the default web browser API. Similarly, we decided to keep this manager as a member in order to prevent clutter in the engine.
The entity manager controls entities, which are our generic class of sprites. Entities can draw themselves on the canvas and execute update functions, but to have access to these engine loops, they must be adopted by the manager first. This both promotes cleanliness in the way game actors are written and accessed during the engine update.
Abstract engine was designed with a storyboard-like approach in mind. In implementation, that ideology translated to our heavy use of the state machine pattern. The engine has several states, both accessible publicly and not. Prior to initialization, the engine is in the null state. While it downloads resources, it’s in the loading state, and after that, the state manager goes to the first user-defined state. States provide their own update and render loop, which are called in place of the engine’s during runtime. To link states, there are transitions, inside which resources can be loaded and entities can be cleaned or reset. Ultimately, this provides a easy way to express multiple views or screens during gameplay; code for the start menu or settings don’t have to be maintained in the same functions or even the same classes.
In addition to this core runtime framework, the engine also provides some useful tools to general game development, such as an efficient vector implementation, particles, custom animations, and physical colliders and collision detectors, making writing a small, 2D game quick and intuitive.
Why This Is Awesome
Abstract Engine is particularly useful for 2D arcade games, as it provides the perfect means for efficient updates, rendering, and entity management. These features, paired with a storyboard approach to game states, made it super easy when we wanted to rewrite Drift, and should provide a great framework for anything we want to do in the future.
Hopefully this summer we’ll be able to spend a little bit more time on the engine; we have plans to potentially make a multiplayer web game with some new networking features and more advanced visual and auditory effects, and by then, we might even have a little bit more documentation and even a tutorial. I suppose we’ll just have to see…