Dynamic Difficulty Tuning in Knit Worth
When it comes to prioritizing aspects of a game during a time crunch like a game jam, playtesting and tuning is usually on the lower end of the list, right behind "make it work" and "oh god, why isn't it working?"
It's difficult to predict how well your players will be able to understand your game, and how challenging it might be to a person who didn't spend 72 straight hours staring at it with out some form of playtesting. Unfortunately, such opportunities are a luxury in such a short amount of time, so we decided to work with our constraints, and came up with a solution that we like to think works pretty well.
"Screw it, if we can't predict a player's skill level, we'll just let the player show us how skilled they are, and tune to that."
Now on the surface, that sounds like a LOT of work, but actually it took a lot less time to implement when compared to gathering data from strangers, tuning the difficulty, and iterating over and over. So here's how we did it!
Sequences
In Knit Worth, players are presented with 8 synapse nodes inside Granny's head that they can poke at with their crochet needles. These synapses can be in 4 different states: Light Blue (Hit me!), Red (Don't hit me!), Flashing Blue (Hit me a bunch!), and Neutral (Don't hit me, but it's not the worst thing in the world if you do, I guess...).
It would have been super easy to just randomly set a state for each synapse and call it a day, but that runs the risk of immediately confusing new players, and robs experienced players from a natural sense of progression and difficulty. So instead, we came up with the concept of Synapse Sequences.
Essentially, a Sequence is a ScriptableObject we made in Unity that contains the designated state for each synapse in a list, as well as a duration in seconds for how long that sequence should last.

We made a BUNCH of these, and organized them into Easy/Medium/Hard folders in our Resources directory.

With this sort of structure, we were able to cover the entire spectrum of player skill levels. To give you an idea of what each Sequence difficulty level looked like, here are a few examples:
Easy Sequence
This is a nice, easy sequence for the player to process. The synapses you want to hit and the synapses you want to avoid are clearly separated. Also, there are a lot of "neutral" synapses. Hitting these will break your combo, but they won't deduct your score and time like the red synapses, which makes them much less punishing to hit.
There's no trickery here. The only barrier to clear this sequence should be the player's understanding of the controls.
Medium Sequence
A little trickier here. There quite a bit more going on, and the presence of more red synapses means there is a harsher punishment for messing up. However, it's not that insurmountable. Much like the easy sequences, the "good" and "bad" synapses are grouped up and clearly separated.
There are a few tricky patterns in the medium, but this difficulty level is mostly meant to test the player's ability to multitask and hit multiple synapses at once.
Hard Sequence
This is where we get a little mean, for the sake of pushing the player to their limits. Flashing blue synapses demand a player's prolonged attention while light blue synapses draw their eyes for one-time extra points. "Safe" and "dangerous" synapses are intentionally mixed together to make things harder to process for the player. At this point, "neutral" synapses are almost exclusively used to add information noise to make the game state harder to parse.
The reward for making it to the hard difficulty is the potential for higher combos and points (given the abundance of flashing blue synapses), but the price is a much more challenging set of sequences that were designed to try and trip your brain up.
Adapting to Player Skill
Initially, when we implemented the Sequence loading system, we had the difficulty "level up" based on how much time was remaining in the round. 50% time remaining would bump you to medium, and 30% time remaining would bump you to hard. After some consideration, we decided that this was probably the wrong way to implement a difficulty curve for our game.
For one, if players struggled to learn the controls or mechanics, they would very quickly get overwhelmed as the game ramped up in difficulty before they were ready to tackle it. On the flip side, if players picked up on our mechanics quickly, they would be bored for 50% of our game before things maybe got challenging for them. We wanted to aim to have players having fun for 100% of the 90-second duration of our game.
In an attempt to achieve this, we implemented a behind-the-scenes "streak" system that counted how many consecutive sequences a player cleared (hit all the light blue ones) without making a mistake. If the player clears 10 in a row without messing up, they will automatically be bumped to the next difficulty level. This way, players who are still learning the mechanics can do so in a safe, non-punishing environment, and players who have maybe played before and thoroughly understand the mechanics can fly right to hard mode without wasting too much time being bored.
Obviously this wasn't an exact science, and it's still super tricky to predict what players will find easy, medium, or hard. But we believe we came up with a solution that at least feels semi-organic and friendly to both new players and veterans alike.
For those who have played Knit Worth already, did you notice the dynamic difficulty? ;)
For those who haven't played yet, check it out for yourself, and let us know how we did! https://ldjam.com/events/ludum-dare/44/knit-worth