Java 8: Awesome Changes for Game Developers

Java8, releasing March 18 2014, has several great changes to it. One in particular has me interested from the aspect of game development and AI, and that is Lambda expressions.

A common structure in games is an event system. Register an entity or agent to listen to certain events and then respond to them. For example:

eventSystem.registerEventListener(“buildingDestroyed”, listeningEntityID, new EventListener() {
    public void onEvent() {
        System.out.println(“Run away!”); // respond to event here
    }
});
eventSystem.broadcastEvent(“buildingDestroyed”, buildingID);

Here we have an Event System that lets listeners register to particular events and a way to broadcast events to those listeners. In this example there is a “buildingDestroyed” event that is registered by an entity with the ID ‘listeningEntityID’. It’s response to the event is an anonymous inner class, with a single method: onEvent. There is handles the event.

This has been the way Java has handled single-method classes for a long time now (what is known as a Functional Interface). It’s a bit clunky, you end up with another interface class floating around, and there is extra code you just don’t use. There’s just nothing elegant about it.

To overcome this limitation I have extracted a lot of code out to Groovy where I can use Closures to clean it up. But I don’t always want to go into Groovy and set up bindings to the scripts and classes. Luckily Java 8 is giving us Lambda Expressions to clean all of this up.

Here’s what the above listener implementation would look like:

EventListener listener = () -> System.out.println(“Run away!”);
eventSystem.registerEventListener(“buildingDestroyed”, listeningEntityID, listener);

If there is only one line in the lambda, then you can use the expression as I have above, but if you want a more complex response you can surround it with braces like so:

EventListener listener = () -> {
    System.out.println(“Run away!”);
    System.out.println(“Find a place to hide”);
}

Lets tighten it up a little more and inline the whole expression:

eventSystem.registerEventListener(“buildingDestroyed”, listeningEntityID, () -> System.out.println(“Run away!”) );

That’s much shorter and cleaner.

Now we still need our EventListener interface. The implementation of EventSystem.registerEventListener needs to know what parameters it is accepting and it shouldn’t care that is might get a lambda expression. It will look like this:

interface EventSystem {
    void registerEventListener(String eventName, int entityId, EventListener listener);
}

 

Scoping in Lambda expressions

So what variables do you have access to in a lambda expression? Well they are kind of like closures in that sense: you get access to variables outside your immediate lexical scope.

Example:

class Bob {

    private String name = “Bob”;

    public void setupEvents(EventSystem eventSystem) {
        eventSystem.registerEventListener(“buildingDestroyed”, listeningEntityID,  () ->
        System.out.println(name+“ is running away from a destroyed building!”) );
    }
}

 

This would output:

Bob is running away from a destroyed building!

 

Other Uses in Games

Finite state machines are very common in game AI. You want an agent to perform tasks, and to control when it performs those tasks you need to have some method of organization, usually via states. Finite state machines allow an agent to switch between one state to another, say from gather logs to chop firewood.

Usually you would have a State class that has a perform() or update() method that is called every frame. Each state class would have its own implementation of what is is supposed to do. So for the GatherLogsState it would send the agent to a tree and then chop it down; when completed, move to the ChopFirewoodState . The ChopFirewoodState would require that there already be some wood in its possession and would then proceed to chop that wood. When done it would switch to the GatherLogsState.

Defining classes for each state can be a pain and pollute your scripts folder, especially if you are using slightly different different actions for a state that are small to begin with. It can be much cleaner and easier to supply the state’s update() action as a lambda expression:

interface State {
    void update();
}

interface Agent {
    void init();
    void update();
}

class FirewoodAgent implements Agent {

    private State currentState;

    private State gatherLogs = () -> {
        findTree();
        chopTree();
        pickUpLogs();
        currentState = chopFirewoodState; // switch states
    }

    private State chopFirewoodState = () -> {
        pickUpAxe();
        chopLogs();
        currentState = gatherLogs; // switch states
    }

    public void init() {
        currentState = gatherLogs;
    }

    public void update()  {
        currentState.update();
    }
}

That is a gross simplification, but you get the idea.

Method References

Another great feature related to lambda expressions in Java 8 is Method References. Here we can reuse existing code in our classes as a lambda expression; no need to write the code again if we don’t have to.

Say we have a Tree class that describes the type of wood it is composed of. That wood has a moisture level that is more desirable depending on what it is used for. We also define an Axe class that converts a Tree into Logs, where Log also has a moisture rating. We use a TreeFinder interface that picks the best log for the Axe to chop. This interface will have several implementations, each one passed to Axe depending on what is wanted. Finally we have an old TreeUtility class for finding the correct tree for the job at hand. It contains some tree finding code.

class Tree {
    public String name;
    public int moistureLevel;
}

/**
* Find the best tree.
*/
interface TreeFinder {
    Tree find(Collection<Tree> trees);
}

class Log {
    public int moisture;
}

/**
* Converts trees into wood.
*/
class Axe {

    public static Log chop(TreeFinder treeFinder, Collection<Tree> trees) {
        Tree bestTree = treeFinder.find(trees);
        Log log = new Log();
        log.moisture = tree.moistureLevel;
        return log;
    }
}

/**
* Some static utility methods to find the perfect tree for the job.
*/
static class TreeUtility {

    public static Tree getMoistestTree(Collection<Tree> trees) {

        Tree moistestTree = null;
        int moistest = 0;

        for (Tree t : trees) {
            if (moistestTree == null || t.moistureLevel > moistest) {
                moistestTree = t;
                moistest = t.moistureLevel;
            }
        }
        return moistestTree;
    }

    public static Tree getDriestTree(Collection<Tree> trees) {

        Tree driestTree = null;
        int driest= 0;

        for (Tree t : trees) {
            if (dryestTree == null || t.moistureLevel < driest) {
                driestTree = t;
                driest= t.moistureLevel;
            }
        }
        return driestTree;
    }

}

We want to use the Axe to chop trees and produce Logs. The Axe’s chop() method uses the TreeFinder to pick the best tree. Normally we would create separate subclasses of TreeFinder to pick what tree we want and pass them to the chop() method. But since there is a utility class laying around that does that for us, TreeUtility, we can use its code instead.

To do that we use a Method Reference:

Collection<Tree> allTrees = GameWorld.findAllTrees(); // made up utility method
TreeFinder dryTree = TreeUtility::getDryestTree;
TreeFinder wetTree = TreeUtility::getMoistestTree;
Axe.chop(dryTree, allTrees);

This works because, as we can see, the signature of the getDryestTree() and getMoistestTree() methods match the signature of TreeFinder.find(). The code will be substituted in and the correct tree will be found. In this example we are want to chop dry trees.

Conclusion

The way to think about Lambda expressions is “code as data”. Instead of passing around primitive data types and objects as parameters you are new passing around code chunks.

Some care must be taken when architecting your code in this way. In many applications it would just confuse the whole codebase and fragment the logic leaving you wondering “why is it doing this weird thing here in just the one case, and where in the code is it doing this?” Games by nature allow for this fragmented code. Game objects usually have their own implementation of an action or response to an event, especially for AI. So it will feel natural to use lambda expressions throughout your entities and agents.

Method references are a little tricky and I’m not sure how robust they are to refactoring. It was a bit tricky to think up a use-case example for this blog post, but I’m sure there’s a better one out there that applies well to games.

I hope you will be excited to upgrade to Java8 and give these a try! It should make your game development more enjoyable.

Please note that I have not compiled these code examples! Take them as pseudo code.

Conferences: The Good, the Bad, and the ‘Are they worth it’

Game Conferences

Conference and expos are a great place to showcase your game and get feedback. They can, however, be a bit pricey and for an indie developer you might only be able to afford one a year if you’re lucky. So how do you choose the best one and how do you prepare so you can get the most out of it? I will try and explain all that here.

I’ve been to a few conferences now, both as an attendee and as an exhibitor and I have learned quite a lot from them. I will only talk about exhibiting at a conference, not being an attendee.

Exhibiting Costs

The first thing you need to decide when considering getting a booth at a conference is will it be worth your time and money. Booths range from $200 to $2000+ and depend on size and placement on the expo floor. That’s the first main cost. The second cost is travel and expenses. These almost always add up to more than the booth cost, especially when you have several people traveling. Equipment, signage, and handouts are another cost, but are usually less.

I calculated how much it would cost 2 people to travel from Victoria BC and exhibit at the PAX Prime conference in Seattle. Victoria is very close to Seattle, just a ferry ride away. For two people it is around $200; that’s pretty cheap. For conference materials I wanted a few posters and a bunch of handouts: another $300. Equipment would be a TV and cables, I would bring my computer: another $700. Hotel would be $1000 for 5 nights for 2 people. Food another $40 per person per day. Assuming a booth cost of $1500 that is a total of $4100. It really adds up.

But it is totally worth it! Right? Well in a way it is, but probably not how you think. I decided against showing Attack of the Gelatinous Blob at PAX, partially because I couldn’t get into the Indie Mega Booth (they supply equipment and more exhibitor passes), and partially because of the cost of renting a booth myself. But the main deciding factor was what I wanted to get out of the conference, and that wasn’t necessarily to show off the game.

I ended up helping out Dejobaan and Radial Games at their booth. It was a good chance to view the conference from the other side: the exhibitor. But the biggest benefit was meeting the other developers, media, and networking. When it came down to it, networking was what I needed to do more than to show off the game.

During a conference every exhibitor is busy beyond belief. They don’t have time to wander around and try out your game. So your best chance to really talk to them and show them your project is to go to the nighttime events and parties.

If you do decide to get a booth, I highly recommend having 3 people per day to take shifts watching the booth. A multi-day event will exhaust you and you must have relief. Just taking you and one other person will ruin your experience and possibly make you too tired to go to any of the networking events.

But what about showing off a game? While I was volunteering at the booth I kept a count in my head of how many people tried the game we were showing (Monster Loves You). There were 2 tablets with the game on them available at all times, and sometimes 3. From 9am to 5pm I counted 60 to 80 people tried the game each day. Over the 4 days that’s about 300 people. That seems like a lot until you factor in the cost of the conference. I was only going to bring one computer to demo the game, so I would at most have only been able to show it to 150 people the entire weekend. Dividing the cost of the trip by that number of people, it would have cost me $27 per person to show it to them. Since I plan to sell the game for around $15, I better hope that each person would buy 2 copies of the game right there on the spot! But no one sells their games there. They might try to recoup costs by selling merchandise or swag, but it won’t cover the trip costs. More people walk by and look at the game and don’t try it. For those you must have cards or flyers to give them so they can remember your game. The amount of walk-bys amounts to many, many more than those who tried the game and unfortunately I did not keep count of that.

The Benefit of a Conference

So there has to be a benefit to exhibiting or else no one would do it. And that benefit is networking and the media.

When you go to a conference, especially a major one, you must arrange ahead of time scheduled meetings with as many media as possible that will be attending the conference. They will write a story and then thousands to tens of thousands will see your game. Not just the few attendees that walk by and try it out. When you break the conference costs down by including media exposure, a booth makes much more sense.

As I’ve said, networking is huge. The indie game community is incredibly friendly and helpful: they want to see everyone succeed. Talking to them could give you good advice and create friendships that will benefit you and your company. Developers and media will now know you by your name and face. You are a person then and they will respond to your emails and write an article about you.

 

What Conference is Right For You?

Hopefully by now you get what I am saying: “conference are for networking and media exposure”. Yea there is a bit of brand awareness, but that can disappear quickly in the noise of the hundreds of booths at a conference. So what conference should you attend? Travel distance is a huge factor in cost. But if travel cost doesn’t affect your budget much you still need to look at if the money is being well spent.

I recently attended a much smaller conference than PAX. While PAX Prime had over 80,000 attendees, this one only had 3000. It was local however, so travel was nearly free. The booth was free as well as it was hosted by the local IGDA chapter, LevelUp Victoria. My costs were nothing so I cannot complain. But other people’s costs were not free: they paid for booths and set up all weekend. A small booth was about $300.

The conference wasn’t entirely focused on video games and the expo hall was the smallest part of what was being exhibited. There was Warhammer, board games, RPGs, and a LAN party as well there. Throughout the day we had very few people visit the booth. Over the 2.5 days I would say less than 100 people walked by and looked at the games. And I only counted 4 people play Attack of the Gelatinous Blob for the half a day it was shown. With that few of people the only thing to get from them was live play-testing (which is awesome and rare to get).

Not many attendees, players, or walkbys. But that is okay, that’s not what conferences are for! Media and networking is what you want so how did that stack up? Well, there was a media event, but only 10-15 media outlets. And the media event was focused on the conference itself not the individual booths or games being demonstrated. It was also mostly local new outlets reporting so their target audience is probably not the gaming community.

Throughout the event only one media person came by. More might have, it was hard to tell because their passes weren’t noticeably different from a general admission pass. At PAX the media have a bright yellow badge so you can pick them out and start talking to them. The whole time we were waiting for media to show up, do some interviews, and see some stories posted. But that just didn’t happen.

At least during the huge downtime between the occasional person walking by we could network a bit.

So what did I take from this experience? Small conferences not solely focused on videogames are probably not a good venue nor worth the money of setting up a booth. Without individual media exposure there is no point in my opinion. You get some play-testers and can network a bit. From talking to the other developers they said it was a bit of a letdown or “not the right venue.” To be fair the conference is growing, it doubled in size this year, but I think it needs to get much larger to make it worthwhile renting a booth there.

This applies to other conferences as well. Are people there to see new games? Are the media excited about it and will you get a chance to do an interview and get a story posted? Are there after-parties where you can network? Take all of that into consideration when planning your next conference.

What are your thoughts or experiences?