= Lessons learned from Open Jam 2020

:Author: Klaatu
:Email: <klaatu@member.fsf.org>
:Revision: 1.0

For many people, programming is fun because it's a little like solving a puzzle.
You just know that, in theory, if you can just arrange logic statements and conditions in the right order, using just the right syntax, then you'll end up with an application that does something useful.
The problem, strangely, is that sometimes you don't know why you'd need the application you'd end up with.
It's like stepping outside for a walk with nowhere to go.
Just as marathons provide a framework and goal for erstwhile foot traffic, there are events for coders without a cause.
Called sprints, hackathons, dares, or jams, programming events are great excuses to sit down, possibly with a whole team of your coding comrades, and develop something interesting.

http://openjam.io[Open Jam] is an annual, weekend-long game jam resulting in as many open source games as participants manage to complete.
I first encountered the results of Open Jam at the http://allthingsopen.com[All Things Open] 2018 conference, where the organizers of the jam had an arcade cabinet running the previous year's work.
I'd played small games from other jams before, and always thought it could be fun to joini in on one someday.
However, I had no interest in contributing to projects that were not open source, nor projects developed on non-open stacks.
So the idea of an _open source_ jam was persuasive enough for me to commit.

This year, I completed a game for Open Jam, and the experience was great, and nothing at all as I'd expected.
If you're being tempted by the prospect of fame and forture through a game jam, here are 5 of the lessons learned by taking part in Open Jam.

== 1. Keep it simple

In 2019, I signed up for Open Jam with the intent of programming a simple game in Lua.
I had some good ideas for a game, and I thought it seemed like a simple idea at the time, so I blocked out the weekend for coding.
This game was never completed.

As it turns out, there are simple ideas and then there are _actual_ simple ideas.
For a weekend game jam, you must allow simplicity to pervade through every aspect of your game.

You want a story in your game?
It must be a two beat story.
Skip the second act and move straight from the first act (a problem is presented) to the third (problem solved, game over).

You need graphics for your game.
Keep them simple.
Even if you find a wandering artist (they do exist, and they converge on Open Jam's chat server in search of projects to join), their time is as limited as yours.
Graphics in games multiply quickly, and exponentially in the event of animation.

If you want sound effects and music, keep it simple.
You might find composers, but a weekend doesn't allow much time for composition, performance, and delivery.
It's likely you'll have to choose from music that already exists but may not fit your game perfectly, or simple tunes that are quick to deliver.
Loops are probably ideal, and letting your composer handle sound effects ensures that the music and effects are well integrated.

For my game this year, I did away with even simplicity and adopted extreme minimalism.
I was a one-person team, so I opted for no graphics beyond coloured blocks, and used mostly single-note musical pieces (composed on https://opensource.com/life/16/2/linux-multimedia-studio[LMMS]), much of which is composed by the user as a side effect of what they do during the game. 


== 2. Start from the beginning

When I started writing my game, I started with my game board and worked out the mechanics largely in attempt to discover whether I actually had a game.
For several hours, I wasn't entirely convinced I wasn't just writing a digital Etch-a-sketch without a game elemnt in sight.
I eventually found a game in the code I was writing, but when I finished my first draft I discovered that I had a game that needed to be relaunched each time you wanted to play again.
I had no start screen, no end screen, no leader board, and no way to choose to play again.

Fixing these issues required some refactoring, and even its present state the code isn't as optimized as it could be.
In much of my utilitarian code, I don't mind code that's more verbose than necessary as a way of documenting the logic for myself and for others who may seek to understand it.
However, this is just a relaxing game, so I think it would be nice to have optimized code that's well organized rather than after thought functions mixed in with important classes and hastily added global variables.

Some of this can be excused by it having been written during a frantic game jam, but in the future I'd like to start from the beginning instead, even if it's just boiler plate templates.
I'd start with a start screen where the player can set difficulty levels, I'd ensure an end screen existed with the option to quit or play again, and so on.


== 3. One game mechanic

I'm not a game designer but that doesn't stop me from trying it.
In the best of big video games with lots of levels, part of the experience is often the discovery of new game mechanics.
Imagine a game in which you start out by discovering, through subtle prompts, that you can stop time.
Next, you gain the power to not just stop time, but to rewind it by some number of seconds.
Later, you gain the ability to fast-forward time.
And so on.

Sounds fun, and like something you should never try to make in a game jam.

In the original version of my game, I started writing automated actions for the computer to take against the player in an attempt to disrupt the game board state.
This led me down a path of complex calculations, state detection, turn anticipation, and probability.
I spent several hours trying to find a good balance between good aggravation and just plain annoying, and also struggling to emulate intelligent decisions.

Ultimately, I learned a lesson or two from my experience as a Dungeon Master™: the player's most menacing opponent is the player.
I discarded the idea of disrupting the game state and allowed the player room to overthink things.

This was the correct choice both from a design perspective and from a code perspective.
After all, the more mechanics you have in your game, the more code you have to write.
The more code you have to write, the more code you eventually have to debug.


== 4. Choose your language carefully

I didn't so much choose Python and Pygame for my project this year as Python and Pygame chose me.
I'd just been demonstrating to someone how to create a grid (a simple two-dimensional array) using nested loops, and it happens that the language they were using was Python.
I used Pygame instead of something more modern like https://opensource.com/article/18/4/easy-2d-game-creation-python-and-arcade[Arcade] because I was familiar with Pygame.
After I'd demonstrated the task, I realised it was the Open Jam weekend and that with "just a few" extra lines of code, I could create a game out of the array I'd created.
Unsurprisingly, those few extra lines turned out to be a 200 or so. 

Python is great because it's cross-platform, but delivering a Python app to all of its possible platforms can be another jam in itself if you haven't planned ahead (and I hadn't planned ahead).
You absolutely _can_ deliver Python to desktop operating systems, Android, iOS, and more, but for best results you must develop with that in mind, using https://kivy.org[Kivy] or http://beeware.org[BeeWare] or similar.
These aren't processors that you run your existing code through to magically and instantly end up with packages for all platforms, these are frameworks you must work with from start to finish.
Because I hadn't planned with my targets in mind, I finished the game jam with a game that runs well on Linux, Windows, and Mac, but that still requires packaging, and not at all on mobile platforms.

Were I to repeat the game jam with improved foresight, I'd have used Kivy, BeeWare, Java, or http://processing.org[Processing] (and a personal rewrite still isn't entirely out of the question).

Ultimately, you should keep your target in mind, and work toward your desired result.
Don't program all weekend only to find that final delivery requires another weekend.


== 5. Use what you know

As an intentional counterpoint to my previous lesson learnt, I have to admit that ultimately removing barriers to completion is one of the best ways to ensure you finish your game.
While Pygame may not have been the best choice by some measures, it was the best choice given the results.
As I demonstrated to myself last year, it's easy _not_ to finish a game jam, so ensuring I had every opportunity to finish by using a framework I've taught to kids and adults for the past several years was a good strategy.

This extends to other aspects, too.
A game jam probably isn't the best occasion to experiment with anything unfamiliar.
Don't try to compose music on an application you've barely ever touched.
Don't design your graphics with a cool new application you read about on the Internet but have only opened once.
It's hard enough to finish a game in two days, so you want everything you use during development to facilitate the end goal. 


== Open Jam Next

I was a one-person team, which didn't exactly take advantage of (or contribute to) the social aspect of Open Jam, and yet it was still a satisfying and fun experience.
There's a lot of momentum when lots of people gather together for a unified goal, and Open Jam's promotion of open source gaming is something that's easy to get excited about from both the open source and gamer angle.
If you've ever thought of joining in on a game jam, I highly recommend Open Jam next year!

