Quickly Solving Jigidi Puzzles

tl;dr? Just want instructions on how to solve Jigidi puzzles really fast with the help of your browser’s dev tools? Skip to that bit.

I don’t enjoy jigsaw puzzles

I enjoy geocaching. I don’t enjoy jigsaw puzzles. So mystery caches that require you to solve an online jigsaw puzzle in order to get the coordinates really don’t do it for me. When I’m geocaching I want to be outdoors exploring, not sitting at my computer gradually dragging pixels around!

A completed 1000-piece "Where's Wally?" jigsaw.
Don’t let anybody use my completion of this 1000-piece jigsaw puzzle over New Year as evidence that I’m lying and actually like jigsaws.

Many of these mystery caches use Jigidi to host these jigsaw puzzles. An earlier version of Jigidi was auto-solvable with a userscript, but the service has continued to be developed and evolve and the current version works quite hard to make it hard for simple scripts to solve. For example, it uses a WebSocket connection to telegraph back to the server how pieces are moved around and connected to one another and the server only releases the secret “you’ve solved it” message after it detects that the pieces have been arranged in the appropriate relative configuration.

A nine-piece jigsaw puzzle with the pieces numbered 1 through 9; only the ninth piece is detached.
I made a simple Jigidi puzzle for demonstration purposes. Do you think you can manage a nine-piece jigsaw?

If there’s one thing I enjoy more than jigsaw puzzles – and as previously established there are about a billion things I enjoy more than jigsaw puzzles – it’s reverse-engineering a computer system to exploit its weaknesses. So I took a dive into Jigidi’s client-side source code. Here’s what it does:

  1. Get from the server the completed image and the dimensions (number of pieces).
  2. Cut the image up into the appropriate number of pieces.
  3. Shuffle the pieces.
  4. Establish a WebSocket connection to keep the server up-to-date with the relative position of the pieces.
  5. Start the game: the player can drag-and-drop pieces and if two adjacent pieces can be connected they lock together. Both pieces have to be mostly-visible (not buried under other pieces), presumably to prevent players from just making a stack and then holding a piece against each edge of it to “fish” for its adjacent partners.
Javascirpt code where the truthiness of this.j affects whether or not the pieces are shuffled.
I spent some time tracing call stacks to find this line… only to discover that it’s one of only four lines to actually contain the word “shuffle” and I could have just searched for it…

Looking at that process, there’s an obvious weak point – the shuffling (point 3) happens client-side, and before the WebSocket sync begins. We could override the shuffling function to lay the pieces out in a grid, but we’d still have to click each of them in turn to trigger the connection. Or we could skip the shuffling entirely and just leave the pieces in their default positions.

An unshuffled stack of pieces from the nine-piece jigsaw. Piece number nine is on top of the stack.
An unshuffled jigsaw appears as a stack, as if each piece from left to right and then top to bottom were placed one at a time into a pile.

And what are the default positions? It’s a stack with the bottom-right jigsaw piece on the top, the piece to the left of it below it, then the piece to the left of that and son on through the first row… then the rightmost piece from the second-to-bottom row, then the piece to the left of that, and so on.

That’s… a pretty convenient order if you want to solve a jigsaw. All you have to do is drag the top piece to the right to join it to the piece below that. Then move those two to the right to join to the piece below them. And so on through the bottom row before moving back – like a typewriter’s carriage return – to collect the second-to-bottom row and so on.

How can I do this?

If you’d like to cheat at Jigidi jigsaws, this approach works as of the time of writing. I used Firefox, but the same basic approach should work with virtually any modern desktop web browser.

  1. Go to a Jigidi jigsaw in your web browser.
  2. Pop up your browser’s developer tools (F12, usually) and switch to the Debugger tab. Open the file game/js/release.js and uncompress it by pressing the {} button, if necessary.
  3. Find the line where the code considers shuffling; right now for me it’s like 3671 and looks like this:
    return this.j ? (V.info('board-data-bytes already exists, no need to send SHUFFLE'), Promise.resolve(this.j)) : new Promise(function (d, e) {

    Javascirpt code where the truthiness of this.j affects whether or not the pieces are shuffled.
    I spent some time tracing call stacks to find this line… only to discover that it’s one of only four lines to actually contain the word “shuffle” and I could have just searched for it…
  4. Set a breakpoint on that line by clicking its line number.
  5. Restart the puzzle by clicking the restart button to the right of the timer. The puzzle will reload but then stop with a “Paused on breakpoint” message. At this point the application is considering whether or not to shuffle the pieces, which normally depends on whether you’ve started the puzzle for the first time or you’re continuing a saved puzzle from where you left off.
    Paused on breakpoint dialog with play button.
  6. In the developer tools, switch to the Console tab.
  7. Type: this.j = true (this ensures that the ternary operation we set the breakpoint on will resolve to the true condition, i.e. not shuffle the pieces).
    this.j = true
  8. Press the play button to continue running the code from the breakpoint. You can now close the developer tools if you like.
  9. Solve the puzzle as described/shown above, by moving the top piece on the stack slightly to the right, repeatedly, and then down and left at the end of each full row.
    Jigsaw being solved by moving down-and-right.

Update 2021-09-22: Abraxas observes that Jigidi have changed their code, possibly in response to this shortcut. Unfortunately for them, while they continue to perform shuffling on the client-side they’ll always be vulnerable to this kind of simple exploit. Their new code seems to be named not release.js but given a version number; right now it’s 14.3.1977. You can still expand it in the same way, and find the shuffling code: right now for me this starts on line 1129:

Put a breakpoint on line 1129. This code gets called twice, so the first time the breakpoint gets hit just hit continue and play on until the second time. The second time it gets hit, move the breakpoint to line 1130 and press continue. Then use the console to enter the code d = a.G and continue. Only one piece of jigsaw will be shuffled; the rest will be arranged in a neat stack like before (I’m sure you can work out where the one piece goes when you get to it).

22 replies to Quickly Solving Jigidi Puzzles

  1. You hate jigsaws in the same way you hate popcorn. If either is present you consume them voraciously whilst complaining about them constantly.

  2. This is working when you are logged in to jigidi. But when you are not logged in there is no such part in code. Thats because jigidi does have different script version in use when you are logged in or not.

    • That’s presumably because it doesn’t need to check if you have saved progress if you’re not logged in. A different but related approach could still be made to work, though, I’m sure.

      • Oh, that’s true. I didn’t realize that there is no need to check that thing when you are not logged in.

  3. I found your explanation pretty pretty useful in order to “solve” some jigsaw puzzle caches. Only a few days ago it was working perfectly for me, but today I cannot find the release.js file in the debugger any more, even after logging out and in again to Jigidi and reloading the puzzle several times. Therefore I also was not able to set a breakpoint correctly and skip shuffling.
    Did Jigidi again change their code? Or am I just to blind to find the right line?

    • You’re right, Abraxas: they’ve changed their code. They’re still doing the shuffling client-side though so it remains trivial to bypass it: I’ve updated my instructions above with a new section at the bottom.

  4. Keep up the good work dude, as a geocacher I love mysteries, Some of my mysteries took weeks of brainstorming and creating them. It’s a bit easy to take an 100 images from the internet put them on jigidi and make a mystery geoart. Solving mysteries is about using tools, just like we use geocachingtoolbox, for me the challenge in those puzzeltrails is to find a solution to be smarter than the geocache creator. I found your website, and I still don’t understand how it works but i’ll try to find it out. Geocachers should create original mysteries from scratch where the clue is only in the head of the creator and not that method that is used over 1000 times before….

  5. Jigidi changed his code again. The tutorial is out of date and I can no longer find the break point. For example, a 400 piece puzzle does not have 1000 lines of code. Can you check it again, please? Thanks!

  6. Works perfectly for me! Thank you so much. I can now spend my time trying to solve the actual cryptic puzzles, not the jigsaws.

    • It would be great if you could explain how this worked for you after the last change. As Frederick wrote, the code was changed again. I tested it extensively two days ago and couldn’t find the line where the break should be set!

  7. How did it work for you? The code is no longer as described. Need more detail to understand its workings.

  8. Is there a way to get access to each piece’s image? I’m trying to do something with AI to solve the puzzle. It would be nice to get the (x,y) location on the screen and the image of the piece. I’m not sure where they are kept.

    • I was thinking about this and you wouldn’t even need AI, just some good image processing code. There’s a preview of the finished image in the corner, and you can determine the number of rows and columns (it’s a simple columnar jigsaw): only the holes and bumps vary. So if you can set the zoom of the main jigsaw space to match the preview size you could just do some kind of image matching to work out with good confidence exactly where each piece lives, for most jigsaws.

      I’ve got no recent experience in image visualisation code and don’t have time to learn, but somebody might be able to do this. No AI required!

      • Yup. I was using AI as a blanket term. I don’t know JS too well. I was thinking of using python/pyautogui/opencv to do it. Opencv has a pattern matching tool that would work well. Pyautogui let’s you take screenshots and simulate the mouse.

        It would be useful to be able to find a pieces position on the screen. Is the array of piece object kept client-side?

Leave a Reply

Your email address will not be published. Required fields are marked *