Note: Development on Deduction is currently paused while I work on my new game Viper Piper.

This is the devlog for Deduction, a fun, challenging logic puzzle. This game will be a version of a puzzle known by various names, including Einstein's Riddle and the Zebra Puzzle. I'm aiming to get it working on Android first, followed by iOS and desktop versions. I'll be using Haxe, OpenFL and HaxeFlixel for development, which makes porting the game to those other platforms pretty straightforward.

Several versions of this already exist on the Google Play Store, but none are terribly pretty or fun to play. There used to be a version on Windows Mobile phones years ago called Einstein which I was addicted to, and spent so long searching for a good modern version that I decided I needed to make my own.

The working title for the game is Deduction, as the puzzle is based on deductive reasoning and involves eliminating candidates until the solution remains.

I already have the puzzle generation code working to the point of producing a randomly-generated text-based version, so most of the work now is to build a UI around the generator and add some extra stuff to make the game a bit more interesting. I already have some ideas for different game modes, power-ups, tile shapes and using an incomplete grid of cells to make puzzles of different shapes and configurations.

Here's the current state of the game:

I'm hoping to have most of the work done on this by the end of the year, but there's already a rough prototype version available for download here. This demo has now expired. I'll upload a new one once development resumes.

For everyday updates, follow me on Twitter as @grayhaze. I'll be posting larger updates here as they happen though. I'd welcome any feedback!

Last night I worked on building the tile grid and getting it to display the current puzzle state. This is the result:

This might be slightly confusing on first glance, as for instance the '6' is in the first column where maybe you'd expect it to be in the last. This is one of the drawbacks of using symbols with an existing sequential order, as the symbols on a row can appear in any column on that row. The order of the smaller 'candidate' tiles simply follows the default ordering of the symbols both to avoid giving the solution away up front and for consistency when selecting those to eliminate.

I intend to build a pool of 30-40 different symbol sets or themes comprising 6 symbols each, and from which the puzzle can be built by choosing a random selection of sets. Most of those sets won't have an implied order to the symbols, which should help to avoid confusion but also potentially increase the difficulty if you get a puzzle with a set you haven't encountered before.

I managed to get a lot done this morning, and now have the clue list displaying! What you see in the screenshot below is basically the hardest difficulty of 6x6 puzzle, using (almost) the full range of clue types:

In the final game these will be introduced to you gradually, on smaller board sizes than this, so don't worry if it looks insanely complicated at this point! The clues in the screenshot are as follows (reading left to right, top to bottom):

I is in an adjacent column to 3

D is NOT in a column to the right of TRIANGLE

V is in the same column as CIRCLE

QUEEN is in an adjacent column to TRIANGLE

ROOK is in an adjacent column to IV

F is in an adjacent column to SQUARE

II is in an column to the left of HEXAGON

BISHOP is in an adjacent column to ROYAL

2 is in an adjacent column to CIRCLE

5 is NOT in a column between and adjacent to both F and V

JOKER is in a column between and adjacent to both HEXAGON and VI

BISHOP is NOT in the same column as ROTATED SQUARE

CLUB is in a cell diagonal to KNIGHT

A is in an adjacent column to V

ROYAL is in a column between and adjacent to both KING and 5

DIAMOND is in the same column as 1

6 is in the same column as F

ROTATED SQUARE is in a column to the right of F

ROOK is in a column between and adjacent to both E and B

BISHOP is in a cell diagonal to A

B is NOT in an adjacent column to QUEEN

QUEEN is in a column between and adjacent to VI and A

VI is in a cell diagonal to HEART

From that list of clues, you can deduce the position of every symbol on the board.

The next task is to implement the interactivity to allow you to click on and eliminate candidates, so that you can actually solve the puzzle. Then I'll almost be at the point where the prototype is ready for some play testing to check that the generator code produces satisfying puzzles.

I did a little more work on the clue types today, adding in a couple that I missed, along with a debug mode which allows me to automatically solve a puzzle by applying a random clue one step at a time. This helps to check that things are working as they should with the clue generation and ensures that the board state updates correctly as the underlying puzzle state changes.

I'm currently having some issues with poor image quality when downscaling the graphics, so I'm working on a way to fix that. I may end up going the route of having various different pre-rendered sizes of each symbol and using the closest one to the display size at runtime, as I suspect that HaxeFlixel can't quite handle the downsizing when it's less than 50%. I wanted to just use a single large graphic for each and scale it down to the size I needed, but when is life ever that simple?

Just a brief update to say that I now have this working as an actual game with win and lose states. It's obviously still very rough around the edges and needs a lot of work to make it into a game fit for general consumption (such as explanations for all those confusing clues), but this allows me to do some play testing and see how well everything's working up to this point. So far I'm pretty happy with how this is turning out.

What you see below is me randomly clicking on and eliminating symbols until I deliberately lose. Yes, deliberately. That's my story and I'm sticking to it.

When you lose currently it reveals the solution to the puzzle before generating a new puzzle for you to try. Likewise, if you solve the puzzle successfully it generates a new one for you.

You'll also notice that the clues all "press in". This happens clue-by-clue during play as you reveal all symbols referenced in a clue. I've done a bit of work on the graphics for these clues to make the negative (red) clues a little more obvious and attempt to remove some of the colour clash these were causing before.

Now that I've hit my target of having the bare minimum playable a couple of weeks early, I'm going to spend the next week or so adding options to control the size of the board (4x4, 5x5 or 6x6) and the selection of clue types used. I may also start to think about a map editor. The need for this will become obvious eventually.

For the past couple of days I've been working on refactoring the code used to display the tiles and trying to find a nice way to deal with the image quality issues I've been seeing when the tile symbols are displayed at smaller sizes. This is particularly important for this type of game, as the whole focus of play is quickly identifying and eliminating symbols. While looking into the best way to improve this I also started thinking about how best to achieve a high quality when tiles are displayed at any size. At some point I'm going to look into implementing pinch-zoom on mobile to allow those on devices with smaller displays to zoom in for a closer look, so I wanted the graphics to remain as sharp as possible at any zoom level.

What I've come up with is something similar to LODs, or perhaps more aptly texture mipmaps, whereby the graphics are pre-rendered in a small number of increasing sizes, then at runtime the size closest to the display size is used and scaled to the appropriate size. This unfortunately means more work for me, but the results so far have proven to be much better than the antialiasing methods built in to OpenFL and HaxeFlixel.

Below you can see a couple of examples of how this improves readability at small sizes, with the tiles on the left being the default scaling down of a single large image and those on the right using the new method.

One slight issue with this currently is at some in-between sizes it can make things look slightly fuzzy. I'm going to continue fine-tuning the image selection until I find the best compromise between readability and sharpness.

Recently I've been refactoring and redoing a lot of the code to make things more manageable going forward. As a result of this, the puzzle game 'engine' has a few new tricks up its sleeve.

The first of these is that I've now fully implemented mipmaps for all of the current graphics, making the game look good on just about any hardware I've thrown at it, from a five year old Android device up to the lated QHD devices.

The second and third things are probably best left to a GIF:

I originally implemented the zoom to check how the mipmaps were performing, but given the speedy performance of the whole thing I'm now planning to use this to zoom into the six tiles within a cell when clicking on them, making them much easier to eliminate, then zoom back out to show the full puzzle again. I think this will make things a lot more dynamic than a simple pop-up, and will also allow me to add some other effects when I get around to the power-ups. A good example would be a power-up which targets and reveals a complete cell.

The 'responsive' design which expands the game board viewport to the full width of the window as it's resized took a little more work than expected, but with this in place I can potentially handle screen orientation changes and look to releasing a desktop version at the same time as mobile.

There's still lots more refactoring work to be done, but now the individual tiles are self-contained objects it opens up a number of different options to me that were lacking before in terms of UI. The logo is just one example of this.

This looks really cool! I've never played this specific kind of game, but I like these kinds of logic puzzles.

Quick question: How do you construct the rules such that there is only one solution? Do you just have a really complicated algorithm for that?

The algorithm is reasonably complex, but works in much the same way as a human would create one of these puzzles. There's probably a more optimal way of doing this, but so far it seems to be generating quickly and producing puzzles with a nice flow to the solution. As far as I've seen in many hours of playtesting so far, it also only produces puzzles with a single solution. What may surprise people is that it doesn't use any form of solver algorithm, which seems to be the usual approach people go for.

I don't wabt to give away too many specifics at this point, as I'd like to be the first to market and avoid the clones, but I can give you a broad overview of the approach.

First I generate a random solution state, where each cell contains a single symbol, then generate a pool of all possible clues which describe that solution. I then start with a full grid, with each cell containing every possible symbol, and select and apply clues one by one from the pool based on the number of candidate symbols each clue eliminates. This is where the "special sauce" of the algorithm comes into play, as trying every clue in the pool would take a really long time on each iteration. I therefore have a way of grabbing a good subset of clues, cutting down the processing required. Clues are also scored based on how many other clues have already been used of that type, and how many times the symbols in the clue have already been referenced. I continue with this process until I eliminate all incorrect candidate symbols from the board, then I do some extra magic to remove any redundant clues which can be removed while still producing a solvable puzzle - this happens more than you'd think.

Hopefully that gives a bit of insight into the process. I had a lot of fun building the algorithm, and it feels good to have that as a foundation for building the rest of the game.

Just a small update tonight, although I've managed to get quite a lot done behind the scenes. I now have the game correctly displaying puzzles of any size from 2x2 up to 6x6, zooming in on the smaller sizes to ensure that they fill the screen. Similarly the clue list now makes better use of the space when there are fewer clues, zooming in to make them easier to read on the smaller puzzle sizes, which will prove useful when I use those smaller sizes to teach the player the different clue types. Hopefully by seeing the symbols at a larger size for much of the game, they will be better equipped to identify them when they get to the hardest difficulty and they're displayed much smaller.

I've also done a little more work on the zoom functionality, paving the way for more dynamic interactions with the board. The next step is to make use of this to zoom in on a cell when the player clicks on it, zooming out again if they click outside the tiles or don't make a selection within a given amount of time. I'm also planning to allow the player to zoom in and pan around the clues at will, therefore making those smaller clues easier to read.

Just spending some time play testing at the moment, making sure I haven't broken anything in the refactor. This week I'm hoping to get the zoom focus working when clicking on a cell so that it'll finally be possible to play on a mobile device without a stylus or really tiny fingers.

After a couple of very frustrating days of struggling to get the mathematics working correctly, I'm now at a point where zooming is working properly! Here's the current state of play, at 2x speed in case you think things are moving a little quickly...

The code for all this is still rather hacky, so it needs a lot of refactoring and optimising. Unfortunately all this animation has taken its toll and the Android build is now running a little too slowly with the 6x6 puzzles. It's likely down to the sheer number of sprites I have on the screen, with each tile being comprised of two sprites - one for the tile and another for the symbol. Add to that the runtime mipmap selection for each sprite texture and the click handler code, and you're looking at a very processor intensive scene for a lowly mobile phone to render.

Hopefully when I get back from my break I'll be able to get things working a lot smoother. I may even post a playable build to get some feedback in a few weeks.

The zooming looks really good, but it seems kind of unnecessary if you're playing with a mouse. The icons aren't THAT small. Maybe make it optional?

I like how double-clicking an icon activates it as part of the solution - very nice!

This is primarily a mobile game at the moment, so the zooming is necessary to be able to play on a small screen with a finger. It's more important for the larger grid sizes, but still really helps on the smaller sizes too. I will however make it possible to turn zooming off in the options, as when playing on a large tablet or a device with a proper stylus it's not really needed.

Despite a busy weekend I managed to squeeze in some work on Deduction, and I now have the very basics of the hint system built. Currently hints are unlimited in the development build, but will limited to between zero and three per puzzle in the final game, with the amount based on the difficulty setting. When you click the hint button (showing off another new type of UI element in the GIF below) the clue 'board' will zoom into the clue which will result in the most eliminations at the current point in the game. Below you can see me cheating my way through a game with this.

In addition to the zooming, I'm also going to look into making some of the tiles that can be eliminated flash to make it a little clearer to see what your next step should be. Perhaps this could be based on the difficulty level too, with hints on the harder difficulties just showing you which clue to use, while on lower difficulties it shows you how to apply it too?

It's likely this will be the last bit of work I'll do on the game for a couple of weeks as I'll be taking a short break. In the meantime I'd love to hear any comments people have about the progress so far. I've had some good suggestions both on here and on Twitter, but I'd like to get a bit more feedback. Perhaps when I return I'll put a playable build up to help get those comments flowing...

I'm now back from my extended break and trying to motivate myself to get going on this again. I'll likely start by working on the hint system a bit more to get it actually suggesting which symbols can be eliminated by the clue it chooses. I also want to implement some text-based descriptions of each clue when you click on them, at which point I can potentially release a rough test build to get some feedback.