Game Development: Library? Engine? Frame-what?

Posted by admin on January 22nd, 2012 filed in Development, Games, Java, jMonkeyEngine, NetBeans

“The jMonkeyEngine is a game engine that provides a framework for the development of 3D games.” — “… What?”

When I mention the jMonkeyEngine, I often have to explain what these terms mean: What’s a library, a framework, an engine? Who uses that stuff? And what do these abstract things look like?

Let’s compare them to something from Real Life™. Technically you can grab a pair of scissors and cut your own hair. You can cultivate sourdough and bake your own bread. You can grab a chisel and whittle a tree into a chair. You can, but in reality you typically don’t. The task would take quite some time, and the quality of the haircut, the pretzels, or the living room furniture will be dubious.
In reality, you rely on experts to do these jobs for you, hairdressers, bakers, or carpenters. You don’t know what their tools are called or how to use them. And you don’t need to. You only know that if you hire them, they will do the job, and do it faster and better than you.

Now, when developers write a new application, they can technically write everything from scratch. They can draw countless colored rectangles that lay out the user interface. They can write code that calculates which rectangle the user has clicked, and write code to resize and redraw all these rectangles. Or — they can load a “library” that draws functional windows and buttons for them. Creating an application window is such a common task that there is no need to reinvent the wheel. Just like you wouldn’t cut down a tree if you can buy a chair.

A framework is an abstract collection of functionality. — A bakery without a baker and flour, just an empty room with an oven and a few recipes. It makes no sense to “be using a framework” just by its own. You always use frameworks to create something, typically, a larger application.

Some examples of frameworks: The Java Swing framework helps you lay out the visual building blocks of an application: windows, buttons, menus, text fields, dialog boxes, etc. A lone Swing menu or button doesn’t do anything but look pretty. The developer adds functionality to the abstract buildings blocks, and combines them to a working whole.
The NetBeans Platform is another example of an abstract framework. It helps you create complex modular applications such as the jMonkeyEngine SDK. It provides a frame in which you create custom file editors, various file views, an update center, etc. An “abstract editor” or an “abstract plugin” doesn’t do anything. The developer adds the actual functionality to the given frame. The NetBeans Platform itself uses Swing — which shows that frameworks can also build on one another.

An engine is also a collection of functionality — but in contrast to a generic framework, an engine’s methods are highly specific. An engine is similar to an engine in your car. It’s so specific that the driver is not expected to know more than how to switch it on, accelerate, and decelerate. While a framework is just a static frame whose gaps you fill, an engine is something that runs and regulates itself for the duration of the task. After the engine is switched on, there is no need for the driver to worry about internal details, such as torque and air and fuel flow: An engine performs its very specific job with minimal user interaction.

Some examples of engines: Developers use graphic engines (to calculate 3D transformations), rendering engines (to draw colored pixels to the screen fast), and physics engines (to simulate the interaction of physical forces and physical objects). A game engine can join these three engines into one cohesive framework. You switch the engines on and they do their thing on your loaded game data, constantly re-calculating the ever changing positions of game entities and immediately drawing the new image to the screen.

A library is a very generic word for a data container: You can have libraries of common programming methods, of assets, of utilities — what ever it is you need, bundled together. Developers package reusable chunks of code into code libraries; graphic designers package shared media files into media libraries, etc. The components in libraries can be re-combined and re-used for each new job. A library can contain libraries, engines, frameworks, or multimedia assets.

How are libraries used? Back to our real life experts. Hairdressers, bakers, and carpenters usually have a list of services and prices. “You give me a dollar and I give you a loaf of bread, we both are happy, have a nice day.”
If you try to buy the hairdresser’s chairs, or ask the carpenter to work on your hair, your day will be less nice. You didn’t look at the list of services, didn’t pay the agreed-on price, and made a fool of yourself asking the wrong expert.
In programming terms, this corresponds to the libraries’ interfaces. A specific programming library expects to be used in a specific context. It needs specific input to produce specific output. If you don’t read the API (application programming interface) first, your use of the library will either produce spectacularly wrong output, or (more likely) no output at all. For example, you depend on the JUnit library to auto-run your unit tests, and the Log4j library to print custom logs.

Now that you know how and why programmers use libraries, you maybe wonder what these abstract things look like. You already know that applications and documents come as files. You install the application, and open a document to edit it. For example, you install the MS Word application to write a letter in a MS Word document.

Libraries also come as files. In Java, these are JAR files. (*) A library’s installation process can be different from an application — often you merely have to download and save the JAR to a specific directory. When writing your program, you declare dependencies on libraries, that is, you specify the relative paths to the functionality that you intend to load from the libraries.

package com.blah.mygame;                 // I package my program for others to load 

import com.jme3.app.SimpleApplication; // I load a public library provided by somebody else

public class MySuperGame extends SimpleApplication {

    public static void main(String[] args) {
        /** Start the jMonkeyEngine application */
        MySuperGame app = new MySuperGame();
        app.start();       
    }

    @Override
    public void simpleInitApp() { 
        /** custom code to load game assets such as 3D models */ 
    }

    @Override
    public void simpleUpdate(float tpf) { 
        /** custom code to make game assets interact */ 
    }

}

In this exmaple, I am loading one of the libraries provided by the jMonkeyEngine framework. I create the MySuperGame object as an instance of jMonkeyEngine’s SimpleApplication class. I adhere to the jMonkeyEngine API: I call the start() method to start the engine, and I override two methods to fill the empty framework with my actual game content. Just like with the craftspeople, the libraries and you have to meet with the agreed-on payment, at the agreed-on time, at the agreed-on place for the deal to work.

(*) PS: JAR files are not exclusively used for libraries, they can also contain applications, just like .exe files on Windows or .app files on Mac OS. A JAR that contains only a library doesn’t do anything if you try to double click it (although some developers decide to set their library JAR up like an application, so it plays a demo of the library when double-clicked — good idea!).

Comments are closed.