HomeGamesUpdatesPricingMethodology
Steam News14 May 20261mo ago

v2.0.3 Occlude Hotfix

We're back from that space of unbeing. Not quite here and not quite there... with an update! Update 2.0.3 It's a small but fun one this time.

Full notes

Full Occlude update

Read the full published notes in a cleaner layout. The original post stays linked below.

What changed

2 fixes2 additions2 changes1 removal
  • Fixes
  • Gameplay
fixedUpdate 2.0.3Fixes to the tutorial for all players. Some players were experiencing an issue where the instructions on the tutorial didn't match the position of the cards on the tableau. This is now fixed for all players!
changedA Far Too Detailed History of Occlude's RNGTreat runs of cards as one block. Once a run of cards is made they can always be moved as a block. This effectively reduces the number of cards on the tableau and reduces the search space.
addedA Far Too Detailed History of Occlude's RNGWith my new algorithm in hand was ready to prove myself right. Occlude wasn't that hard, it was the players who were wrong! I ran the code and it checked the first seed... unsolvable . Unlucky I thought but one is not a sample size. Unsolvable... unsolvable... unsolvable... It wasn't until the seventh seed checked that it found one that it could solve. In the end around 30% of shuffles were actually solvable with perfect play. Oh no.
changedA Far Too Detailed History of Occlude's RNGThankfully, I came up with a solution. This solution was based on two heuristics. First, as we said above 2s and Queens are the hardest target cards to solve for. They give you the fewest opportunities to clear cards from the tableau. Second, if you can solve the deal with 2 as the target card then you can probably solve it with 3 as the target card. So the solution was to upgrade my previous algorithm so that it paid attention to target cards and make it play twice, once where the target cards were all 2s and once where the target cards were all Queens. That way it is almost certain that you can place the cards on the foundation in whichever order you like. And the algorithm only has to do twice as much work.
addedA Far Too Detailed History of Occlude's RNGSo after another few hundred hours of my CPU screaming and finding out that now only about 15% of games were solvable we were done! And this is pretty much how this problem was left solved until launch (apart from the hidden mechanic where the game takes pity on you but that's a story for another day). This work was also useful for adding the tutorial where a particular tested seed is always chosen for the tutorial which then steps you through the moves.
fixedA Far Too Detailed History of Occlude's RNGFinally, we come to the bug that has just been fixed. A while ago, we were alerted to an issue where for some players the instructions in the tutorial didn't match the order of the cards on the tableau. This was worrying because it maybe meant that all this work I'd done to make sure the cards got dealt in a solvable way wasn't working at all for some players. After much digging around we found our answer in the C# documentation for System.Random:

We're back from that space of unbeing. Not quite here and not quite there...

with an update!

Update 2.0.3

It's a small but fun one this time. For those who just want the headlines, here are the fixes included:

  • Fixes to the tutorial for all players. Some players were experiencing an issue where the instructions on the tutorial didn't match the position of the cards on the tableau. This is now fixed for all players!

  • Consistent card deals across all machines. A lot of work went on behind the scenes to make sure every time you play Occlude it is solvable, even if it doesn't feel like it. However, a tricky bug meant that, for some players, that effort was all for naught. There is a full explanation below for those interested in the nitty-gritty of how Occlude shuffles a pack of cards

If you were one of the players who didn't quite believe our promise that every deal is solvable, maybe give the game another play and see if you fare better. Maybe you were one of the unlucky few that were affected by this issue.

A Far Too Detailed History of Occlude's RNG

In the early versions of Occlude the deck was shuffled completely randomly every time. There was no clever game development magic going on in the background. Sometimes you got a good deal, and sometimes you got a bad one. I like to keep things simple (sometimes too simple) and kept saying to Sam "It doesn't matter if a deal is unsolvable, players will just click redeal". Sam was quietly sceptical.

Without doing a lot of work it was difficult to know how often the game was solvable. A quick google shows that Klondike (the kind of solitaire you are most familiar with from Windows in the 90s) is solvable around 82% of the time if you play perfectly. That didn't seem bad to me. Occlude was harder but surely couldn't be that much harder, right? Then we came to our first public playtest...

The feedback was damning. Not only did players find the game hard but they were often convinced it was unwinnable. We were told we were mad for putting out a game so obtuse. Maybe we were but we had 2 months left until launch and no time to start over. The only thing to do was improve the experience we had made and I bit the bullet and decided to finally answer the question "How often is a deal of Occlude unsolvable?"

The process of answering this was actually quite fun. I built a simple algorithm to start a game and play until it either solved the game or got stuck. For the coders among you this was just a simple depth-first search navigating a graph of game states connected by valid moves.

A few fun optimisations in this algorithm

  • Always prioritise moving cards onto the foundation. This first version didn't worry about target cards so moving to the foundation is always a good move.

  • Assume the game is winnable once you have cleared 4 columns. Anyone who plays for a length of time knows how valuable empty columns are. In my experience, it is always possible to solve if a few columns are clear. There's no logic to why I picked 4 but I have never come across a game that is unsolvable with 4 empty columns. If you can find one, send it to me!

  • Treat runs of cards as one block. Once a run of cards is made they can always be moved as a block. This effectively reduces the number of cards on the tableau and reduces the search space.

With my new algorithm in hand was ready to prove myself right. Occlude wasn't that hard, it was the players who were wrong! I ran the code and it checked the first seed... unsolvable. Unlucky I thought but one is not a sample size. Unsolvable... unsolvable... unsolvable... It wasn't until the seventh seed checked that it found one that it could solve. In the end around 30% of shuffles were actually solvable with perfect play. Oh no.

Fortunately, all this work also provided the solution for solving the problem. I could run the algorithm, check if a deal was solvable, and if it was record the seed that generated it in a list that the game can curate from. Now, when you hit reshuffle it takes a seed from the pre-approved list and shuffles the deck based on that. And all it took was 200 hours of burning my CPU overnight making it play solitaire.

Then I had another conversation with Sam very reminiscent of the one referenced earlier.

"So this will make sure the shuffle is always solvable for any set of target cards, right?"

"...no, only solvable in general"

"..."

"..."

"Aren't players just going to have the same frustration when they can't reach the target cards?"

So it was back to the drawing board. The reason I didn't take target cards into account originally wasn't purely laziness. It isn't possible to check all sets of target cards for each deal. There are 14,641 different combinations of them and checking each deal was already slow enough. The simple solution would be to generate a set of target cards with each deal. The problem there is that a 7 is a much easier target card than a 2 or Queen so the algorithm would start validating more deals with 7s than 2s or Queens. I strongly believe that the core part of the game of Occlude is puzzling out the target cards and was worried that if 7s became much more likely target cards then the game could be cheesed.

Thankfully, I came up with a solution. This solution was based on two heuristics. First, as we said above 2s and Queens are the hardest target cards to solve for. They give you the fewest opportunities to clear cards from the tableau. Second, if you can solve the deal with 2 as the target card then you can probably solve it with 3 as the target card. So the solution was to upgrade my previous algorithm so that it paid attention to target cards and make it play twice, once where the target cards were all 2s and once where the target cards were all Queens. That way it is almost certain that you can place the cards on the foundation in whichever order you like. And the algorithm only has to do twice as much work.

So after another few hundred hours of my CPU screaming and finding out that now only about 15% of games were solvable we were done! And this is pretty much how this problem was left solved until launch (apart from the hidden mechanic where the game takes pity on you but that's a story for another day). This work was also useful for adding the tutorial where a particular tested seed is always chosen for the tutorial which then steps you through the moves.

Finally, we come to the bug that has just been fixed. A while ago, we were alerted to an issue where for some players the instructions in the tutorial didn't match the order of the cards on the tableau. This was worrying because it maybe meant that all this work I'd done to make sure the cards got dealt in a solvable way wasn't working at all for some players. After much digging around we found our answer in the C# documentation for System.Random:

[c]The implementation of the random number generator in the Random class isn't guaranteed to remain the same across major versions of .NET. As a result, you shouldn't assume that the same seed will result in the same pseudo-random sequence in different versions of .NET.[/c]

Which means it's possible that a seed that I have spent so much time testing might do something completely different on another machine. To be honest, I'm still not 100% sure if this is the actual problem, as it's difficult to work out from Unity's documentation exactly how it links to .NET libraries. But to make sure, we no longer do any RNG at runtime and all of the orders of the decks are stored in-game having been shuffled on my computer.

Anyway, if you got this far, thank you for reading my little ramble about one of my favourite parts of Occlude's development. If you enjoyed it, I can probably dredge up some other tales that could be turned into blog posts.

Owen

Source

Steam News / 14 May 2026

Open original post

Changelog.gg summarizes and formats this update. How we read updates.