What is an Application Class?
The Application Class is a class that defines how the application will interact with the system it’s running on. It is the part of the engine that is responsible for interacting with hardware (input, display, sound, etc.) and other software components that make the system go.
A well-designed Application Class abstracts away the hardware and software interfaces so the game developer (i.e., the person using the engine to write a game) never has to know the particulars of, for example, taking input from a touch screen, or a keyboard, mouse, joystick, gamepad, microphone, VR wand, etc. Ideally, the engine developer (i.e. the person creating the engine) would want the input functions to be as simple as:
myInput = engine.getInput()
and automagically, the value of myInput would be something like KEYBOARD_KEY_SPACEBAR, or TOUCHSCREEN_TAP (maybe with some screen coordinates), or GAMEPAD_BUTTON_1..
Of course, in practice, it’s never quite that simple. But the goal is to get close.
How Does One Make an Application Class?
Fundamentally, the Application Class for a game needs to do 3 things, and 3 things only:
- Collect inputs
- Process inputs/Crunch Data
- Output something
Of course, the details of those 3 steps can be immensely complex. In the list above, “collect inputs” means to any gather input data which the game logic will use to compute stuff. “Inputs” can actually be user/game controller input, AI input, networking input, etc.
Similarly, the term, “process inputs,” is broad. For example, the game can process game controller input and turn it into commands (e.g. walk forward).
The controller input might lead to AI input, as mentioned above. For example, the user might press a gamepad button that causes the player to launch a homing missile at a target. In the same way that the controller generated an input that the game interpreted as a command to launch the missile, the missile itself, and the target, also generate input data that help the game calculate where the missile should go.
Lastly, “output something” entails drawing the scene, playing sound effects, vibrating the controller, etc. The outputs are feedback items that let the game player know what’s happening.
An IRL Example:
- Process user input
- Process game commands
- Update actors
- Do pre-render stuff
- Render the game scene
- Do post-render stuff
In a bit more detail:
- The “process user input” step involves collecting user input and translating it into game command messages.
- The “process game commands” step involves consuming game command messages and executing the actions they instruct. In Falldown, game commands are things like “SetMovingLeftTrue” or “SetMovingLeftFalse”, for the ball.
- The “update actors” step runs the game’s “simulation.” For example, the update step moves objects, performs collision detection, etc.
- The “pre-render” step entails cleaning things up before drawing the scene. In Falldown, it involves constraining the ball to stay within the boundaries of the screen (after the “update actors” step already moved the ball based on gravity and user input).
- The “render” step draws the game scene.
- The “post-render step draws overlays, such as the score, level, etc. In a 2D game like Falldown, the game stats “overlay” doesn’t look like much. It makes more sense in a 3D game, where the overlay might be oriented relative to the “camera” looking into the virtual world.
- Why is the “process input” step separated from the “process game command” step? The separation ensures that all game commands are executed when they’re supposed to be (more on this in the messaging article).
- Why is there a pre-render, render, and post-render step? The short story is: I have read that breaking the scene rendering into those 3 stages is good practice, especially in more complex games.
- Falldown uses Pygame (which is a Python wrapper around SDL) to interact with the computer’s hardware. Even though we are writing our own engine, we <strong>do not</strong> want to write our own low-level code.