Developing Graph Train

A game jam game where you plot graphs to complete train tracks

🧑‍💻

Written by Josh Humphriss

🗓️

Posted: 28 Feb 2023

🗓️

Modified: 05 Oct 2024

⏱️

7 min read

👁️

1095 views

Introduction

I created this game along with 2 other people for the Great Warwick Game Jam 2023. This jam lasted for 2 weeks, where teams had the opportunity to make a game that fits the theme "retro". Our team won the second prize for best designed game out of 18 submissions.

I'm only going to go over a few aspects of the game's creation, focusing particularly on areas that I worked on.

Which bits did I do?

As we were working in a team, I think it's useful to clarify which bits of the project I was responsible for. I was responsible for:

I was not responsible for:

Choosing a Concept

Choosing what type of game to make is always the hardest bit, and this was no exception. Unfortunately, the theme didn't immediately bring many ideas so we spent a while working through different ideas to see what would work. There are so many different ways we could've taken it, but we had to settle on just one. Many of our initial ideas were big (and also included a lot of frogs).

After lots of careful planning, I randomly had a thought of plotting graphs for trains to go over, and it instantly stuck. Despite having spent hours of planning, we had actually just gone with an idea that I randomly thought of when walking back.

This idea was great because it combines two genres we were considering: puzzle and education. The game is both a puzzle game (albeit limited to those with some proficiency in maths) but also a valuable teaching tool to allow students to practice graphs and graph transformations in a fun setting.

Level Design

Beyond the initial concept, we had to actually make some levels. It became evident quite quickly that the initial concept wouldn't be particularly fun if it was just about finding a function that joins two points - after all, you could just always use a straight line! Then, I thought we could have walls to block the path, which dramatically improved it.

However, when I drew this out, it became immediately apparent that we could not only have walls but collectibles! This means that each level would have an 'easy' solution, as well as a more difficult solution where the player has to try and collect a frog (we had spent so much time thinking of frogs that the collectibles very naturally became frogs...). Collectibles made such a drastic impact to the game, as it was suddenly possible to have different difficulty levels built-in (without an option in the options menu), something which is great to have in any game.

Designing the actual levels themselves was more challenging than I thought it would be. Puzzle design is just incredibly hard. Each puzzle needed to be hard enough so it isn't obvious, but also challenging enough such that it isn't trivial. Also, they had to use functions that people generally know about and can easily formulate.

Evaluating Levels

If you find the design of particular levels interesting (I certainly do!), I made a separate blog post that goes over each level with a brief evaluation on how good it is. You can find this blog post here.

Plotting Graphs

One of the biggest challenges was probably plotting the graphs themselves. Obviously, the game will not be very good without the graph plotter.

It was very important for the game that the graph plotting was fast and flexible, so it would update as you type and also allowed basically any function to be input. To ensure it was flexible (and to save us a lot of hassle), we used a library to parse the maths expressions. This gave us a function as an output, which we could then put whatever numbers we want into. Performance also wasn't much of an issue as computers are fast enough to handle graph plotting quite adequately.

As for actually drawing them, I first followed a tutorial which involed creating various different gameobjects and transforming them so they would form a line. Later, I figured out that LineRenderer existed and made this so much easier. We would simply pass in 100 values into the equation, convert them to co-ordinates and pass it into the LineRenderer. Getting everything to display properly took a bit of tweaking but eventually it all worked and we could plot graphs. Then, once input was working, any graph the user input could be plotted! This was a huge milestone for the project and meant it actually felt feasible. This took until about the end of the first week.

There was still plenty of work to be done on graph plotting. Mapping the track asset to the curve was fairly simple with the LineRenderer, although did still take a few hours to fix (as usual). Also, when functions went out of bounds there needed to be a point on the edge so that the graph would draw to the edge and the train could connect to it. This was done with linear interpolation as it made it much easier and was barely noticeable.

Piecing it All Together

Now we had a working graph plotter, we had to make this actually work as part of a level. Easier said than done.

Fortunately, due to how graph plotting was implemented, it was actually quite easy to have a train traverse the tracks. As the co-ordinates were being stored, it simply needed to follow a list of waypoints which is quite easily done.

But the levels consist of not only dynamic sections, but also static sections. While there would've been more efficient ways of doing it, I decided the best way to do the static sections would just be to do it in exactly the same way as the dynamic sections, so they looked consistent. As we were short on time, this was done by simply manually entering every co-ordinate (including manually generating all the curves!).

Finally, we just had to join these all together. Surprisingly, this was made quite easy by two key invariants:

This meant that the algorithm simply needed to:

Note that we needed to handle discontinuous graphs, which were actually quite easy because each segment was plotted separately, so could just be handled as its own separate graph of which the train would follow the closest one. The continuity checker did only check for bounds, but we found it was near impossible to enter any function that broke this (entering piecewise functions is not possible).

Future Development

There are various issues on GitHub that still remain unresolved, however there are a few that are particularly important, which only became more apparent through playtesting.

Input

When picking up the game, most players found it unintuitive to start typing when there wasn't a flashing indicator to let them know that they can type. Also, not being able to use the arrow keys to edit parts of a function was inconvenient.

Camera

The camera currently stays fixed around the train, which is not too bad for functions where you enter from the left, but was very annoying for graphs that are entered from the top or bottom. Ideally, when the train gets close to the graph, the camera should smoothly transition to lock onto the graph instead.

Speed

Using ENTER to toggle fast-forward was just one more thing that players had to learn while under an already strict time limit. It would be far better if the speed adjusted to be faster when going through dialogue and automatically slow down as it approached a graph. This could also make it more generous for the player, as it could slow down extra slow as the train is about to derail. A fast-forward button should've been available to skip through dialogue (but stop for graphs). When the user typed an equation correctly, the game could've automatically skipped forwards (although this may skip before the player collects a frog, which is undesired, hence why enter was used). It was planned to have messages that tell the player in advance whether their graph would work or not, but this didn't make it in time either.

Conclusion

Overall, this was a great project that was a lot of fun and I learnt a lot. As usual, the levels were too hard. As with a lot of game jam games, the implementation could've done with a but more work. But overall, it was very good considering the time we had available. We had a great concept and produced a nice prototype that people enjoyed playing. Also, I learnt a lot about how to use Unity! Winning a prize was also a welcome surprise at the end of it all. This was a really great event and I'm looking forward to getting involved in more game jams in the future.

More About Graph Train

I also made an article that goes in-depth into the level design in particular. You can find that here.