Game Programming Patterns

I recently read Game Programming Patterns from Robert Nystrom one of the best books about programming I’ve ever read.


I get commissions for purchases made through the following link


I read the entire book from beginning to end in one go, I couldn’t stop. Normally I use programming books to fall asleep, the design pattern book of the gang of four doesn’t make any exception.

The book Game Programming Pattern from Robert Nystrom on the other hand is one of those very rare books which keeps me awake even late in the night. It is crispy, fun and it explains you the design patterns in a fresh and understandable way. It is also helpfull if you are not a game programmer as it explains the design patterns from the gang of four from a different perspective than you know from your daily work.

The author starts always simple without a pattern until he ends up in a dead end and solve the problem by applying graduadly the corresponding pattern which makes it so easy to understand the patterns in all his depts. It’s a very practical approach and even the samples are in C++ they can be easily adapted to any other language.

One of my favorit one is the command pattern with history functionality. Very use full for level construction tools.

If you are interested in design patterns and don’t like the original one, give this one a try.

Test Driven Development Integration Test

Beside unit tests, it is a good idea to have some integration tests. An integration test only makes sure that the new feature is in place. An integration test does not ponder on edge cases. It’s crucial to keep an integration test as simple as possible.

Make the Greeter App Modular

The greeter app from the Test Driven Development is not very modular and hence it is not possible to write integration tests for the new greeter app. In fact, in the first TDD blog post we only could write a system test to check if reading from the keyboard is working.

For the integration test, we need a ReadAndGreet module where we read from a scanner and return the greeting text. Let’s transform the greeter app from the second test driven development post

class Hello {
    void main() {
        Scanner input = new Scanner(System.in);
        String name = input.next();
        System.out.println("Hello " + name);
    }
}

to

public class ReadAndGreet {
    private Scanner scanner;

    public ReadAndGreet(Scanner scanner) {
        this.scanner = scanner;
    }

    public getGreeting() {
        return "Hello " + scanner.next());
    }
}

and

class Hello {
    void main() {
        Scanner input = new Scanner(System.in);
        readAndGreet = new ReadAndGreet(input);
        System.out.println(readAndGreet.getGreeting());
    }
}

Write a Failing Integration Test

And now we can write a simple failing integration test for the not yet integrated Greeter feature, which says "Good morning", "Good afternoon" or "Good evening" depending on the day time.

public class ReadAndGreetIntegrationTest {
    @Mock
    Scanner scanner;

    @Test
    void shouldGreetTomWithGoodMorning() {
        when(scanner.next).thenReturn("Tom");
        ReadAndGreet readAndGreet = new ReadAndGreet(scanner);
        assertEquals("Good morning Tom", readAndGreet.getGreeting())
    }
}

Perfect works… but wait, what if the test runs in the afternoon? It will fail and we don’t want to test the edge cases. So we need to relax the test a bit, we are only interested in "Good" and "Tom" and omit the in-between "morning", "afternoon" and "evening".

public class ReadAndGreetIntegrationTest {
    @Mock
    Scanner scanner;

    @Test
    void shouldGreetTomWithGoodMorning() {
        when(scanner.next).thenReturn("Tom");
        ReadAndGreet readAndGreet = new ReadAndGreet(scanner);
        assertThat(readAndGreet.getGreeting(), MatchesPattern("^Good .* Tom$", ))
    }
}

Now we have a failing and relaxed integration test because we don’t have our Greeter in place yet. That is the next step

public class ReadAndGreet {
    private Scanner scanner;
    private Greeter greeter;

    public ReadAndGreet(Scanner scanner) {
        this.scanner = scanner;
        this.greeter = new Greeter();
    }

    public getGreeting() {
        return greeter.sayHelloTo(scanner.next());
    }
}

And the integration test is happy. You have now a test in place that will act as an alarm if somebody accidentally removes the Greeter from your code. Or if somebody replaces the Greeter with the old "Hello" greeter functionality. Furthermore writing tests forces you to make your code modular which leads to more reusable code, think of a different scanner than the standard input. So again testing helps you in the microarchitecture and favors simple code over complex code.
If you have questions or improvements or any other kind of suggestions let me know in the comments below.

If you are interested in an online or onside workshop for test driven development write me an email artificials_ch@gmx.ch

Test Driven Development Fixtures

We all tend to write helper classes for testing, which clutters the test code and makes it harder to understand. A test should be like a story that you simply can read from top-down. I like test story better than fixture and I will use story and fixture interchangeable.

Why a Story Is More Powerful Than a Helper

If you have helpers you have code somewhere else, most often at the end of the test or even in another class where you hold all these helper utilities. If I read a test and I see method calls I tend to think that this is the code I test, but it is not. Helper utilities are also a sign that you probably need these utils also in your code and you should have tests for these utilities. As well helpers break the flow of your test story, it is like a reference to another story which you also should read before you can go on with this story. How awkward would that be in a book? Well, it is awkward as well in tests.
Unfortunately, this is hard to teach and to make visible why helper utilities are not a good thing.
When I write a test, I start with one single test and pack everything in that test I need, like calling methods, filling in entities, whatever is needed. Then I write a second test and do the same and after the third test, I put all the similarities into the setup method which is called before every test. And this holds the story. In Java JUnit5 it is the @BeforeEach annotation.

Let’s Jump Into The First Story

We base this blog article on the Test Driven Development Mantra. If not done yet read that first as it will give you a better understanding of the test refactoring we are going to make now.

We have two tests from that article (and maybe you did the exercise and wrote the next test with for "good afternoon")

  @Mock
    private DateTime dateTime

@Test
    void shouldSayGoodMorningToTom() {
        when(dateTime.getHourOfDay()).thenReturn(6);
        assertEquals("Good morning Tom", sayHelloTo("Tom", new DateTime()));
    }

   @Test
    void shouldSayGoodMorningToJerry() {
        when(dateTime.getHourOfDay().thenReturn(6);
        assertEquals("Good morning Jerry", sayHelloTo("Jerry", new DateTime()));
    }

The similarities are very obvious here and you can make a good morning fixture out of it like this

public class GoodMorningTest {
    @Mock
    DateTime dateTime;

    @BeforeEach
    void setUp() {
        when(dateTime.getHourOfDay().thenReturn(6);
    }

@Test
    void shouldSayGoodMorningToTom() {
        assertEquals("Good morning Tom", sayHelloTo("Tom", new DateTime()));
    }

   @Test
    void shouldSayGoodMorningToJerry() {
        assertEquals("Good morning Jerry", sayHelloTo("Jerry", new DateTime()));
    }
}

That’s it. You can read it top-down without any distractions. You have all together which makes tests very easy to read. Avoid helpers at all cost, it asks for troubles and confused programmers. And I’m well aware that this here is a very simple example, but honestly, most often it is not much more complicated than this here, test driven development favors simplicity.

Let me know if you have suggestions or questions in the comments below.

If you are interested in an online or onside workshop for test driven development write me an email artificials_ch@gmx.ch

Laughing While Shooting

The little hero starts to laugh when shooting a lot. It is bound to the number of rounds per second to make him start laughing, every weapon has his threshold. Or when he shoots two or more targets in a row.

It makes the game more fun.

I’m thinking of more little animations like the love it animation for picking up ammo. Currently, I’m thinking of a cursing animation, unfortunately, I can not use the hits I get because we die too easy and I don’t want to change that. He curses when he stucks somewhere maybe. Or when he struggles with something.


New Design Of Our Hero on Our Shop

We are exciting to promote our cute angry little hero on our shop. You can buy it as hoodie, t-shirt, bag, or cap and support on this journey to develop this cute looking game.


We are working on the cursing and love it animation which takes place in the game on certain activities, like the crazy laughter after shooting down two or more enemies in a row.

Twitch Channel ia97lies

I have a twitch channel and I plan to develop my game from time to time life on this channel. I will not comment on what I’m doing but rather would like to interact with you, just write on the chat all the questions you have and I try to explain in the lifestream. As well as suggestions or improvements are welcome. Just to talk my self or to hidden people isn’t a too nice experience and feels a bit unnatural.

https://www.twitch.tv/ia97lies

I’m looking forward to this out-of-my-comfort-zone experience.

One more thing, I do this game in Java, jMonkeyEngine, Zay-es, Lemur,libgdx-ai, dyn4j and feather. Of course for the models I use blender.

I offer as well test driven development sessions, just let me know down in the comments if you would be interested. Or directly on my twitch channel. I don’t do test driven development for my personal stuff as I’m a one-man-show-game-developer, and I have a different focus than at work. But it would be a completely different story if I work with someone together. If there is interest I prepare something or do it while developing my game All Fucked Up.

I do it in Swiss-German, German and English, depends on the people joining. I’ll see it in the chat 🙂

I’ll be streaming between 8-9 PM CEST on Sunday eve.

Test Driven Development Mantra

This is the mantra

  • Think of a piece of code you want to add
  • Write a test which fails because that piece of code is not in place
  • Write that piece of code to make the failing test succeed
  • Refactor the code
  • Refactor the test

and you do that over and over again. Why did I not start with writing a test which fails? Because if you think for the next test without having code in your mind it’s incredible hard to figure out especially in the begining. This first step is a help and that works surprisingly well for me and for the people I taught test driven development with my workshops. It also keeps the steps as small as possible and in my opinion, that’s key if you want to test all the aspects of your new class.
And I do refactor the test as well and organize that around stories mostly referred to as fixtures. I will write about fixtures in one of the next blog posts about test driven development.

Simple App

Let’s carry on with the greeter app from the last blog post

Gretter.java

public class Greeter {
    public String sayHelloTo(String name) {
        return "Hello " + name;
    }
}

Hello.java

class Hello {
    void main() {
        Scanner input = new Scanner(System.in);
        String name = input.next();
        System.out.println(new Greeter().sayHelloTo(name));
    }
}

On the last meeting with the customer, we agreed that our greeting app must greet different depending on the daytime. Or more precisely our greeting app must say "Good morning" after 12 am, "Good afternoon" after 12 am and "Good evening" after 6 pm.

Practice

I will guide you to know how to write the needed code test driven step by step.

First Failing Test

What could be the next line of code we want to write? The easiest way ist to have an additional method in the Greeter class like this

public String sayHelloTo(String name, DateTime time) {
    return null;
}

We don’t write this, it’s just that we think of it. That is the first step. But wait… how does the failing test look like if that code is not even in place? Well it doesn’t compile and that is the failing test and it looks like

public class GreeterTest {

    @Test
    void shouldSayGoodMorningToTom() {
        sayHelloTo("Tom", new DateTime());
    }
}

Make the Test Happy

To make it compile we simply add the piece of code we thought about above and it compiles and even works.

Skip Refactor The Code and The Test

In this case, we don’t need to refactor the code or the test as there is nothing to improve so far. We skip these two steps in the mantra consciously.

Next Piece Of Code

The next piece of code is probably something like this

    public String sayHelloTo(String name, DateTime time) {
        return "Good morning " + name;
    }

but… resist writing the code!

Let’s Think of The Next Test

What could be the next test which fails? Exactly we add now an assertion for this. And here it goes

    @Mock
    private DateTime dateTime
    @Test
    void shouldSayGoodMorningToTom() {
        when(dateTime.getHourOfDay()).thenReturn(6);
        assertEquals("Good morning Tom", sayHelloTo("Tom", new DateTime()));
    }

I made already all the proper assumptions to say good morning and mocked the DateTime to return 6 in the morning if getHourOfDay is called.

And it will fail because our code just returns null.

Make The Second Test Happy Too

This is now really important and it is the only way to test all edge and aspects of your application in a test driven way. What do you think is the minimal code you need to make the app say "Good morning Tom"? What if I say just return exactly that? I mean literally this static string?

    public String sayHelloTo(String name, DateTime time) {
        return "Good morning Tom";
    }

I give you some time to digest… and while digesting run the test to see it is green. I mean it! Hit the damn button and run it.

And yes I know it is not our initial piece of code we thought of, but that is ok because that only helps us to find the next failing test. It’s a help and actually optional if you can do that without, I can not.

What Next?

The first thing we want to go rid of is this super static string. I guess that is your inner urge. Well then let’s think of a less static string, like this

    public String sayHelloTo(String name, DateTime time) {
        return "Good morning " + name;
    }

But… don’t write this code, just think of this code, because we need first a failing test!

Let it Fail Again

But how can we make the test fail? We simply write a new test with a different name, boom!

    @Test
    void shouldSayGoodMorningToJerry() {
        when(dateTime.getHourOfDay().thenReturn(6);
        assertEquals("Good morning Jerry", sayHelloTo("Jerry", new DateTime()));
    }

Isn’t that amazing? So simple to think of the next failing test if you keep thinking of a small portion of code.

That’s It For Now

What are the next steps for daytime addition to making the app say "Good afternoon Tom" if the getHourDay() method returns 14?

Write in the comment about how you would do that. What is the code you think of and what is the test which fails because that piece of code is not yet there? And finally what is the code to make the test happy.

If you are interested in an online or onside workshop for test driven development write me an email artificials_ch@gmx.ch