www.alxm.org

Ludum Dare 37 Notes

Here is Motel 37, a game I made in 48h for Ludum Dare 37. This was my second Ludum Dare and third 48h game jam. Things went better this time and Motel 37 comes closer to resembling a game than Rushed Dinosaur Dare, thanks to a few lessons learned.

Motel 37 animated screenshot


No More Writer's Block#

The LD37 theme was "One Room". Coming up with game ideas on the fly is hard, and I wanted to avoid spending half a day brainstorming instead of coding like I did in August at LD36. I thought I'd get an edge by coming up with something for each of the 16 finalist themes in the day leading to the jam. However, the idea I had for One Room was one of my weakest, so I referred to my ideas notebook instead.

My notebook is a large .ODT file to which I add things year-round whenever something pops into my head. Ideas are ephemeral and I highly recommend writing them down whenever they come to mind. I'm thinking about setting up a personal wiki to tag and categorize them better.


Better Technology#

I love working on my game framework. I've been adding to it on and off for a while and in addition to desktop Linux and Windows it supports some lesser-known platforms like the GP2X and Open Pandora. However, as I found in LD36, it doesn't do enough to make writing a game easy, as opposed to a generic application.

In an ongoing effort to remedy this, I implemented the entity-component system pattern. This enforces an obvious way to design game code, making it simpler and faster to develop.

For example, here are the functions that create the player and phone objects (see the full source code here). Framework types and functions start with A and a_ respectively, while the game's start with Z and z_:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
AEntity* z_entity_player_new(AColMap* Colmap, int X, int Y)
{
    AEntity* e = a_entity_new();

    ZCompInput* input = a_entity_addComponent(e, "input");
    z_comp_input_init(input, z_entity_player_input);

    ZCompPosition* position = a_entity_addComponent(e, "position");
    z_comp_position_init(position, X, Y);

    ZCompSprite* sprite = a_entity_addComponent(e, "sprite");
    z_comp_sprite_init(sprite, "playerUp playerDown playerLeft playerRight");
    z_comp_sprite_setDir(sprite, Z_COMP_SPRITE_DIRECTION_DOWN);

    ZCompVelocity* velocity = a_entity_addComponent(e, "velocity");
    z_comp_velocity_init(velocity);

    ZCompVolume* volume = a_entity_addComponent(e, "volume");
    z_comp_volume_init(volume, Colmap, X, Y, 8, 8);

    return e;
}

AEntity* z_entity_phone_new(AColMap* Colmap, int X, int Y)
{
    AEntity* e = a_entity_new();

    ZCompMapEvent* event = a_entity_addComponent(e, "mapevent");
    z_comp_mapevent_init(event, z_phone_handler);

    ZCompPhone* phone = a_entity_addComponent(e, "phone");
    z_comp_phone_init(phone);

    ZCompPosition* position  = a_entity_addComponent(e, "position");
    z_comp_position_init(position, X, Y);

    ZCompSprite* sprite = a_entity_addComponent(e, "sprite");
    z_comp_sprite_init(sprite, "nightstand1");

    ZCompVolume* volume = a_entity_addComponent(e, "volume");
    z_comp_volume_init(volume, Colmap, X, Y, 16, 24);

    return e;
}

The two look very similar, which makes them predictable and easy to add features to.


Start with a Skeleton#

Unlike in August, I based my project on a game skeleton I made for a different jam the week before. All the existing code did was draw a tile map and sprite objects, but not starting the code from zero meant I hit the ground running.

Thanks to this head start, I was able to spend more time creating game content as opposed to engine and infrastructure work.


48h Is Still Only 48h#

I started with big dreams of a game with quirky characters, multiple motel rooms to explore, lots of missions, and ominous background music. That will happen one day since I have clear plans for where to take this project, but it sure didn't happen in the two days I worked on it last weekend...

Motel 37 screenshot Motel 37 screenshot

The treasure buried in marked graves was thought up and implemented in the last 50 minutes before 6 PM, when I realized that all I had was a demo without any gameplay. Still, everything went much better than last time - looking forward to LD38 in April!