A downloadable refactor

For the 2025 GMTK Game Jam, some friends and I created Monday 8, a short task-scheduling puzzle game using Unreal Engine. The jam build simply worked, but under the hood it was full of hardcoded values, spaghetti blueprints and duct-tape logic holding it together. It was a fun prototype, but impossible to extend.

In the jam version, the layout of the gameplay UI has all the tasks of the game hardcoded and depending on the value of the current day, more or less tasks are made visible to show the progress.

Also the names of the tasks are hardcoded (TaskName1, TaskName2, and so on) and in order to check the restrictions the controller does checks like:

if "TaskName1" exists before "TaskName2" and "TaskName3" is on the range of "TaskName1" plus 4, etc.

The code above is ran each time a task is moved.


Time to refactor

After the jam, I decided to do what I enjoy most: building clean code and solid software architecture. This dev log is a rebuild of Monday 8 that showcases a data-driven, designer friendly, modular approach, making the systems easier to understand, scale, and expand if we ever want to grow the game beyond the jam prototype.

Restriction System (The Puzzle Layer)

Instead of hardcoded tasks, I created structs for the definition of a task and a for the definition of a restriction. A task has an array of restrictions, meaning that it can have 0, 1, or more restrictions. In order to check a task, all restrictions of the array must be met.

DataTable-Driven Tasks

With my new approach, all the tasks live in a DataTable and there is a DataTable with tasks for each day. This makes it very easy to add or remove tasks to tweak and balance the gameplay. This also allows to have different tasks and restrictions for each day, creating a not so repetitive game loop in which the main character learns from his mistakes.


No hardcoding, pure flexibility.

Soft Reference Loading

In the PlayerController, a variable holds soft references to the DataTables of each day, and only the current one is loaded asynchronously to automatically fill up the task list and the restrictions.

Clean Blueprint Architecture

The PlayerController now has a map (dictionary) of tasks info that is automatically filled when parsing the DataTable information into the gameplay widgets. Every time a task is added, moved or removed from the agenda, it updates the info of that task correspondingly.
When the game checks if the tasks are correct it simply iterates the tasks on the agenda automatically checking the restriction criteria for each one of the constraints of the task.



Gameplay

With the new system implemented, the gameplay could look like this:

Day 1

Day 2

Updated restriction for task "Coffee".

Day 3Changed flowers task: roses instead of daisies.

Day 4

Day 5Added a restriction for the task Park.

Published 16 days ago
StatusPrototype
CategoryTool
AuthorRiggnarock