Realm Racer Devlog #2: Aesthetics and Design Patterns

     We haven't done this in a while, but this post is going to present to you all the wonderful updates we have for our game!

     I'm quite happy with the progress we've made. It's been considerately motivating, applying different software engineering principles and seeing what a difference they make in game. I'll discuss what those changes are and reflect on why they've made me a better coder.


Aesthetics

     The gif below sums up most of what the game looks like now:

gif of game

     The game has gone from just a bunch of debugging objects to actual art. We tweeted some concept art we had in mind for one possible slice of the game and have, to some degree, implemented that art. The tubes and the car currently reflect that. However,you'll note that the lines on the tube are very large. I had to perform some scaling due to nonstandard sizing of the models. Don't worry, I complained to our artist, and he says he has now standardized the sizes of all the models.

car model concept art      The gif doesn't demonstrate the sound of the crash. It's just a royalty free sound, but we will change it later to align with the games feel.

     Obstacle collision technically records damage to health as well, but there is no GUI for that yet. In fact, there is no GUI at all. Suchaaver is hashing it out, and we'll hopefully have some sense of a GUI in the coming months. If he knows what he's doing, it'll follow his post late last year regarding GUI design. We may even do an analysis of different GUI schemes we drew up and how they rank. I think that would be pretty cool.

     Finally, the gif doesn't reveal that it currently works on Android. Have to make sure the target platform supports it, right?


Code

     What really excites me are the programming patterns I've implemented. Part of why I make games is to learn how to build them; making changes so that the code is cleaner, faster, and more scalable is an essential part of that process.

Messaging Queue

     It was becoming harder and harder to manage the interaction between my objects; simple things such as telling my TrackCreationControl to generate a new track piece were no longer easy. However, two pieces of reading kicked in, saving me from horrible code. The first is Game Programming Pattern's page on Event Queues. The article articulates very well when messaging protocols are needed, and my situation definitely called for it*. GameDev Tuts “How to Implement and use a Message Queue in Your Game" gave me a practical and minimal way to implement the queue.

     I introduced a CommunicatingObject interface which any object that needed to throw messages around implemented. Then, in the style of the tutorial, I created a MessageBroker and a Message class. Now, say, the player finishes a turn on the track. The following actions take place:

  1. The TrackPieceDeletionControl fires off a message to the TrackCreationControl telling it to generate a new piece.

  2. The TrackPieceDeletionControl deletes the turn piece. 1 & 2 are performed in the code below:

    private void delayedDeletion(){
        Message m = new Message(
            "track creation",
            this,
            "deleted",
            -1);
        MessageBroker.getInstance().sendMessage(m);
        obs_destroy = null;
        bas.getPhysicsSpace().remove(track_piece.piece);
        track_piece.piece.removeFromParent();
        bas.getPhysicsSpace().remove(this);
    }
    
  3. TrackCreationControl receives the message and generates a new piece:

    public void onMessage(Message m) {
        if(m.getFrom() instanceof TrackPieceDeletionControl){
            removeDeletionControl((TrackPieceDeletionControl)m.getFrom());
            createPiece();      
        }      
    }
    

     I may think about adding a relay message back to the TrackPieceDeletionControl to let it know when TrackCreationControl has created the new piece, but that's a redundancy I'll implement if sufficient testing deems it necessary.

Singleton

     This is a simpler idea, explained once again by the fabulous Game Programming Patterns Singleton article. Right now, the singleton design pattern is being used for my MessageBroker class. It dictates that there only be one MessageBroker, and prevents me from accidentally instantiating another MessageBroker to put a message on a queue. It has a fairly simple use, but it does the job of making me have to think less. That's a plus.

Flyweight

     I didn't have to implement this design pattern because but it is already provided by the jMonkeyEngine API. I just wanted to take a step back and appreciate it. As described by, wait for it, Game Programming Patterns Flyweight article, the flyweight design involves making objects more lightweight by moving extrinsic data in a single place for more efficient access and usage. In our game's case, each of the barrels is cloned. With no animation, this means they all share the same mesh, optimizing the use of the barrels. Huzzah! These little things under the hood make a difference, especially when developing for mobile.

* I'm not foreign to messaging systems. I have worked with RabbitMQ in a larger software setting. But being told to work with something versus deciding for yourself when to implement something are very distinct roles. It can be rewarding to see your decision play out in your favor.


     The updates are done. For now.

     The roadmap in the near future involves getting this to a prototype that people can download and test. To get that going, we want to have

  • A GUI of some sort in place
  • A scoring system
  • An end to the level

     When the last bullet point comes to life, then the game becomes a much more modular system, and scaling it will be fun. But we'll cross that bridge when we get to it.

     Watch our twitter, and stay tuned!

Joraaver Chahal

I'm currently an undergraduate at UCLA studying Computer Science and Engineering, but I take part in a myriad of other activities, like game development, soccer, and robotics, that keep me busy.

comments powered by Disqus