Make a SOKOBAN puzzle

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
40,062
Reaction score
13,687
First Language
English
Primarily Uses
RMMV
A SOKOBAN puzzle is one where you have to push objects, one step at a time, onto specific locations, and the puzzle is complete when all objects are where they're meant to be. The challenge is to keep yourself free to move, while not moving any objects into a wall or corner where you can't get it out again.


Koi asked for help to create one of these, and as I'm listing the individual steps, figured it might be of interest to others.


This is a sokoban puzzle (image comes from Koi's support thread)

Step 1 - Draw your map


Mark in the walkable areas and borders, and place the destination tiles to indicate the destination for the objects (these must be passable tiles)

Step 2 - Make destination tiles 'special'


You can do this using terrain tags or regions.


To use terrain tags, just go to your Tileset tab, find your 'special' tile, and change its terrain id to something that's not in use elsewhere.


To use region ids, go to the region layer and paint with a single region id over the special tiles.

Terrain Tags:



Region IDs:


Step 3 - Add your movable objects


There are a few ways you can set this up.


For something that rolls, you will want Walking Animation checked, but for something that does not have animations or directions, you'll want Walking Animation UNchecked and Direction Fix checked. Leave all the other options UNchecked.


Decide on your trigger - you can either leave it as Action Button, and make the player press space to move it, or just set it to Player Touch, which means just the player moving into it will force it to move.


The event commands are JUST to move the object away from the player (you may or may not want to add a sound effect) - we're not going to do any position checks or puzzle validation here. Make sure you check the Skip if Cannot Move box. It's up to you whether you want to add a Wait for Completion or not.


Make one, verify that it works, and then copy and paste it so all the objects are on their starting positions.

By now, you should be able to set your player position, and walk around pushing the objects in front of you. They should get caught in the corners or on the walls.


Step 4 - Check for puzzle complete


We'll use one "controller" event to monitor what's happening on the map and poll the object locations to see when the puzzle is complete.


It will run as a parallel process, checking every few frames to see where everything is. By default, a parallel process event will run all the commands listed, then will go back to the top and repeat the process, until we do something to tell it to stop.


When the puzzle is complete, it'll display a message and stop any further checks.


At this point, you will want to reward your player for completing the puzzle, and maybe stop them from pushing the objects around any more.


Step 4a - Get first event's X and Y coordinates, and find the terrain tag or region id at that location on the map

Step 4b - Compare with the 'special' terrain tag or region id


If it's not the 'special' terrain tag or region id, this object is not on its final tile and the puzzle is not solved. We don't need to check any more events, so just skip to the end, ready for the next iteration.

Step 4c - Repeat the test for all other movable object events


Copy and paste those lines so there's one group for each event. Then change the event ID in each group, so at the end you're doing the check for each of your movable object events

Step 4d - Success!!!


All objects are on the correct type of tile. Do whatever needs to be done to let the player know they've succeeded, and end the puzzle.

Step 4e - Failure


Just wait a few frames to avoid lag, then by default the event will start running from the top again.

Add your player's starting location in the correct spot, and play away.
 
Last edited by a moderator:

joeyhugg

Ace Attorney
Member
Joined
Jan 28, 2013
Messages
47
Reaction score
2
First Language
Snarf
Primarily Uses
Thanks! This will prove to be helpful in the future. But, what happens if a bolder is to be pushed into a corner?
 

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
40,062
Reaction score
13,687
First Language
English
Primarily Uses
RMMV
You would need a way to reset the puzzle. A parallel process event monitoring for press of a particular key that would use Set Event Location to move everything back to where it was, or let them leave the room (if their path is not blocked off) and when they come back, everything will be reset.


The whole goal of Sokoban is to be able to PUSH the objects. Giving you the option of PULLING them if you move them the wrong way defeats the purpose of the puzzle.
 

Koi

Veteran
Veteran
Joined
Aug 8, 2013
Messages
358
Reaction score
14
First Language
English
Primarily Uses
RMVXA
Thank you so much! I'm about to test this out.

Oh, and tip for step 3: Select "Skip if cannot move" for the set move route so you don't end up getting stuck in between rocks!

EDIT:


Thanks! This will prove to be helpful in the future. But, what happens if a bolder is to be pushed into a corner?
For the map that I have set for my Sokoban puzzle, it's a map that cannot be reentered. So what I did is I have a character that you can go and talk to that asks, "Did you mess up?", then have a choice command where if "yes," it will transfer you to an identical map to how the first map was set.
 
Last edited by a moderator:

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
40,062
Reaction score
13,687
First Language
English
Primarily Uses
RMMV
As long as you don't somehow block yourself off so you can't access that character. A switch on the floor is also another option.


Thanks for the move route correction - I'll add it to the tute.
 

Koi

Veteran
Veteran
Joined
Aug 8, 2013
Messages
358
Reaction score
14
First Language
English
Primarily Uses
RMVXA
Okay... dammit... I still have no idea how to do this. What exactly is the "controller" event? Would that be the same event where all of the trigger events are looked at? Is that the event that could cause a door to appear?

And most importantly, I have no idea how you put in those commands. When I go to control variables there is no "= [Eventwhatever]'s Map X/Y, thing. I am just as baffled as I was before :c
 

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
40,062
Reaction score
13,687
First Language
English
Primarily Uses
RMMV
Note: Koi and I solved these issues privately. Thanks for the chat - it was an absolute pleasure :)
 
Last edited by a moderator:

amerk

Veteran
Veteran
Joined
Mar 13, 2012
Messages
1,433
Reaction score
495
First Language
English
Primarily Uses
Wild Arms had an item you carried that allowed to reset the room, and put your character back to the beginning of that room, if you messed up. Something like that could work here, for those needing a reset option.
 

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
40,062
Reaction score
13,687
First Language
English
Primarily Uses
RMMV
That's a nice idea!
 

Argarion

Warper
Member
Joined
Oct 4, 2013
Messages
1
Reaction score
0
First Language
English
Primarily Uses
I was playing around with scripts and came up with this alternative method for doing steps 4a-e.  For my example I used 4 objects.  The event IDs of the 4 objects are stored in an array (ev_ids) and I used region ID 1 for the special tiles (reg_id).  The values for ev_ids and reg_id are the only thing that need to be changed if you want to reuse this script.  Event scripts are limited to 12 lines so I had to condense multiple lines into 1 to use this script in game (See "Script used in game").  The wait 5 frames to avoid lag is outside the script in my game but can be included by adding "wait(5)" to the script.

Script

ev_ids = [73,74,75,76]reg_id = 1

solved = 0
for i in 0..(ev_ids.length - 1)
  if $game_map.events[ev_ids].region_id != reg_id

    break

  end
  if i == (ev_ids.length - 1)

    solved = 1

  end
end
if solved == 1
  $game_self_switches[[$game_map.map_id, @event_id, "A"]] = true 

end
 

Script used in game

ev_ids = [73,74,75,76]; reg_id = 1; solved = 0
for i in 0..(ev_ids.length - 1)
  if $game_map.events[ev_ids].region_id != reg_id; break; end
  if i == (ev_ids.length - 1); solved = 1; end;
end
  if solved == 1;
  $game_self_switches[[$game_map.map_id, @event_id, "A"]] = true; end
 

 
 

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
40,062
Reaction score
13,687
First Language
English
Primarily Uses
RMMV
It would be so much easier to do in scripts, but this is a basic tutorial and I just wanted to use event commands so people who aren't familiar with scripting can use it too :)
 

Tommy Gun

♩ ♪ ♫ ♬
Veteran
Joined
Jan 20, 2014
Messages
385
Reaction score
123
First Language
English
ev_ids = [73,74,75,76]

reg_id = 1

solved = 0

for i in 0..(ev_ids.length - 1)

  if $game_map.events[ev_ids].region_id != reg_id

    break

  end

  if i == (ev_ids.length - 1)

    solved = 1

  end

end

if solved == 1

  $game_self_switches[[$game_map.map_id, @event_id, "A"]] = true 

end
 

This is great! Is there a reason you need to separate the "solved" part and use extra lines? Can't you just combine them:

Code:
 if i == (ev_ids.length - 1)  $game_self_switches[[$game_map.map_id, @event_id, "A"]] = true end
 

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
40,062
Reaction score
13,687
First Language
English
Primarily Uses
RMMV
I would have to look at it more closely, but you could probably do that. In fact, now that you question it, the whole thing could probably be reduced to 5 or 6 lines.


The tutorial is geared at a beginner-level RMer, though, who isn't familiar with scripting, so more lines is better if it gives more clarity to what's happening - given that there aren't going to be that many events so extra lines won't cause lagging issues.
 

Cadh20000

Veteran
Veteran
Joined
Sep 15, 2013
Messages
1,828
Reaction score
445
First Language
English
Primarily Uses
Wild Arms had an item you carried that allowed to reset the room, and put your character back to the beginning of that room, if you messed up. Something like that could work here, for those needing a reset option.
That is what I did in an old project.

It would be so much easier to do in scripts, but this is a basic tutorial and I just wanted to use event commands so people who aren't familiar with scripting can use it too :)
Or those who are using Lite, like I did for so long.
 

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
40,062
Reaction score
13,687
First Language
English
Primarily Uses
RMMV
But Lite doesn't give you the script box either, does it? So you couldn't do this in Lite, unless you found another way around that method.
 

GrandmaDeb

Modern Exteriors Posted!
Veteran
Joined
Apr 25, 2012
Messages
4,467
Reaction score
2,941
Primarily Uses
Is your first image down?

Code:
[URL="http://upload.wikimedia.org/wikipedia/en/1/18/Sokoban_animation.gif"]http://upload.wikimedia.org/wikipedia/en/1/18/Sokoban_animation.gif[/URL]
seems like such a lovely tut. =]
 
Last edited by a moderator:

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
40,062
Reaction score
13,687
First Language
English
Primarily Uses
RMMV
Looks like it. That one isn't my image. It's Koi's, from her original request for help in making a puzzle like this.


If I have time, I'll create a new one. But Koi's was animated (showed the puzzle being completed) and I don't know how to make gifs.
 

MistressDarna

Veteran
Veteran
Joined
Jun 1, 2014
Messages
52
Reaction score
0
First Language
Dutch
Primarily Uses
Hey, Shaz,

I followed your instructions and although I'm not sure if I not add in/change certain things when using this (or what I would need to change/add).

But after I get my chickens (my puzzle is with chickens) where they are supposed to be the controller event does nothing.. (there's supposed to be a text thing saying that the chickens can now go to sleep or something and that they get 50 exp). So if I followed your instructions to the letter as shown above, would I have had to add things somewhere else?
 

Sharm

Pixel Tile Artist
Veteran
Joined
Nov 15, 2012
Messages
12,760
Reaction score
10,884
First Language
English
Primarily Uses
N/A
You can change the message but there shouldn't be anything you need to change or add to make it work. I had a similar problem and it turned out that because I'd created my events in a different order from the tutorial it no longer matched the code. The game was expecting me to move the controlling event over the special tiles and was thinking it was incomplete because that event wasn't.
 

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
40,062
Reaction score
13,687
First Language
English
Primarily Uses
RMMV
I've already responded via PM, but I'll post the issues here as well, in case anyone else has troubles and might have done the same thing ...


Two small mistakes.


You'd already used region 1 for something else, so you used region 40 instead to paint your "safe" spots. However, in the event that checks for puzzle completion, you grabbed the region, but still checked to see if it was 1. You need to change all those conditional branches to check for the value 40, not 1.


The second issue was that you correctly got the X and Y coordinates of each event, but then you didn't use them. In the Get Location Info command, you used Direct Designation and selected the destination tiles, instead of using the X and Y variables. THIS resulted, once I'd fixed the incorrect region id comparison, in the puzzle ALWAYS being solved, because it was looking at the region id of the destination tiles, not of the events. So change all the Get Location Info commands to use Designate with Variables, with your X and Y variables, instead of Direct Designation.


After that, the only things that remain are adding a second page to the checker event and all the chicken events, with ALL of them conditioned by the switch you're turning on when the puzzle is complete. This means you can no longer move the chickens around, and the checker will stop checking and repeating the message :)
 

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Posts

Latest Profile Posts

Why is there so much month left at the end of money? D=
Hello humans! How goes your day in this journey of living? I hope it is good, for I am human like you, and I am feeling great! Worship the altar.
Sand is basically small rocks

Forum statistics

Threads
105,609
Messages
1,014,971
Members
137,273
Latest member
Parzival
Top