Created
June 3, 2025 00:11
-
-
Save JoWovrin/e428958769552dca74a311843579477b to your computer and use it in GitHub Desktop.
Sokoban in Space (Puzzlescript Next Script)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Play this game by pasting the script into https://puzzlescriptnext.polyomino.com/editor.html |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
title Sokoban in Space | |
author JoWovrin | |
homepage www.puzzlescript.net | |
again_interval 0.1 | |
verbose_logging | |
level_select | |
norepeat_action | |
mouse_clicks | |
mouse_left roll_left | |
mouse_right roll_right | |
===== | |
TAGS | |
===== | |
nr = 1 2 3 4 | |
notleft = right down up | |
notup = right left down | |
notdown = right left up | |
notright = left down up | |
========= | |
MAPPINGS | |
========= | |
directions => numbers | |
right left down up -> 1 2 3 4 | |
======== | |
OBJECTS | |
======== | |
Background | |
green | |
roll_left l | |
transparent | |
roll_right r | |
transparent | |
Target | |
transparent | |
(white red | |
00000 | |
01110 | |
01010 | |
01110 | |
00000) | |
Wall # | |
brown | |
Player - | |
darkbrown | |
..... | |
.000. | |
.000. | |
.000. | |
..... | |
( | |
black orange lightgreen blue | |
.000. | |
.111. | |
22222 | |
.333. | |
.3.3.) | |
Box:1 | |
orange | |
00000 | |
0...0 | |
0...0 | |
0...0 | |
00000 | |
Box:2 | |
pink | |
00000 | |
0...0 | |
0...0 | |
0...0 | |
00000 | |
Box:3 | |
blue | |
00000 | |
0...0 | |
0...0 | |
0...0 | |
00000 | |
Box:4 | |
darkgreen | |
00000 | |
0...0 | |
0...0 | |
0...0 | |
00000 | |
Spike s | |
white gray | |
.0.0. | |
00100 | |
.111. | |
00100 | |
.0.0. | |
dead t | |
red | |
0...0 | |
..0.. | |
.0.0. | |
..0.. | |
0...0 | |
falling f | |
transparent | |
(red | |
..... | |
..... | |
..0.. | |
..... | |
.....) | |
lost_travel z | |
transparent | |
levitation x | |
red | |
gravity g | |
gray | |
jumped j | |
transparent | |
..... | |
..0.. | |
..... | |
..0.. | |
.0.0. | |
cur:directions d | |
transparent | |
..0.. | |
.000. | |
00000 | |
..0.. | |
..0.. | |
rot:up:> | |
arm:directions | |
gray darkbrown | |
00000 | |
..1.. | |
..1.. | |
..1.. | |
..... | |
rot:up:> | |
extends ! | |
red | |
======= | |
LEGEND | |
======= | |
. = Background | |
O = Target | |
p = player and arm:up and arm:down and arm:left and arm:right | |
1 = Box:1 | |
2 = Box:2 | |
3 = Box:3 | |
4 = Box:4 | |
pushable = Player or Box:nr or arm:directions | |
pushable2 = Player or Box:nr or arm:directions | |
pushable3 = Player or Box:nr or arm:directions | |
object = Player or Wall or Box:nr or spike or arm:directions | |
obstacle = Wall or spike | |
======= | |
SOUNDS | |
======= | |
================ | |
COLLISIONLAYERS | |
================ | |
Background | |
roll_left | |
roll_right | |
lost_travel | |
levitation | |
gravity | |
jumped | |
extends | |
Target | |
Player, Wall, Box:nr, Spike | |
falling | |
directions -> arm:directions | |
directions -> cur:directions | |
dead | |
====== | |
RULES | |
====== | |
[dead] -> cancel | |
(toggle gravity/levitate mode) | |
[action Player][levitation] -> [Player][gravity] | |
[action Player][gravity] -> [Player][levitation] | |
(extend an arm) | |
[> Player arm:>] -> [Player > arm:>] | |
(if arm hits air, don't use movement system and just move the arm manually) | |
[> arm:> | no object] -> [ | arm:>] | |
(retract an arm) | |
[> Player | arm:>] -> [Player arm:> | ] | |
[gravity] -> gosub gravity-rules | |
[levitation] -> gosub levitation-rules | |
(emergency cancel) | |
[> arm:directions | stationary object] -> cancel | |
late [gravity] -> gosub LATE-gravity-rules | |
late [levitation] -> gosub LATE-levitation-rules | |
late [Player dead][target] -> [Player dead][] | |
late [jumped] -> [] | |
late [lost_travel] -> [] | |
late [extends] -> [] | |
late [falling] -> again | |
late [cur:directions] -> again | |
late [arm:directions obstacle] -> cancel | |
late [arm:directions box:nr] -> cancel | |
======================================================================================================= | |
subroutine gravity-rules | |
======================================================================================================= | |
(gravity from "again" call) | |
[pushable falling] -> [down pushable falling] | |
down [ pushable falling | object no falling] -> [ pushable | object no falling] | |
[roll_left][Player arm:right arm:left arm:down arm:up] -> [roll_left][left Player arm:right arm:left arm:down arm:up] | |
[roll_right][Player arm:right arm:left arm:down arm:up] -> [roll_right][right Player arm:right arm:left arm:down arm:up] | |
[horizontal Player stationary arm:directions] -> [horizontal Player horizontal arm:directions] | |
[> arm:> stationary Player | spike] -> [arm:> Player dead| spike] | |
startloop | |
(pushables can push other pushables along) | |
[> pushable | pushable] -> [> pushable | > pushable] | |
(Propagate movements through connected boxes) | |
[moving Box:1][Box:1] -> [moving Box:1][moving Box:1] | |
[moving Box:2][Box:2] -> [moving Box:2][moving Box:2] | |
[moving Box:3][Box:3] -> [moving Box:3][moving Box:3] | |
[moving Box:4][Box:4] -> [moving Box:4][moving Box:4] | |
(if arm pushes against a wall, all their movement is stopped and all other arms are moved in the opposite direction) | |
[stationary Background > arm:> | wall] -> [> Background > arm:> | wall] | |
[stationary Background > arm:>][> box:nr | obstacle] -> [> Background > arm:>][box:nr | obstacle] | |
[> box:nr | stationary box:nr] -> [box:nr | stationary box:nr] | |
left[> Background > arm:> Player][stationary arm:notleft] -> [> Background > arm:> < Player][< arm:notleft] | |
right[> Background > arm:> Player][stationary arm:notright] -> [> Background > arm:> < Player][< arm:notright] | |
up[> Background > arm:> Player][stationary arm:notup] -> [> Background > arm:> < Player][< arm:notup] | |
down[> Background > arm:> Player][stationary arm:notdown] -> [> Background > arm:> < Player][< arm:notdown] | |
(check if a box is pushed against a wall) | |
[> box:nr | obstacle] -> [box:nr | obstacle] | |
(propagate non-movement through connected boxes) | |
[moving Box:1][stationary Box:1] -> [stationary Box:1][stationary Box:1] | |
[moving Box:2][stationary Box:2] -> [stationary Box:2][stationary Box:2] | |
[moving Box:3][stationary Box:3] -> [stationary Box:3][stationary Box:3] | |
[moving Box:4][stationary Box:4] -> [stationary Box:4][stationary Box:4] | |
[> Background > arm:>] -> [Background arm:>] | |
[stationary arm:>][> arm:directions][Player] -> [arm:>][arm:directions][Player] | |
[stationary arm:>][stationary arm:<][stationary arm:^][stationary arm:v][moving Player] -> [arm:>][arm:<][arm:^][arm:v][Player] | |
endloop | |
(arm pushing into spike -> dead) | |
[> Player][stationary Background > arm:> | spike] -> [dead Player][> Background > arm:> | spike] | |
[> arm:directions | spike][Player] -> [arm:directions | spike][dead Player] | |
[dead Player][> arm:directions] -> [dead stationary Player][arm:directions] | |
(cancel turn if an arm is pushing into a stationary object) | |
[> arm:directions | stationary object] -> cancel | |
======================================================================================================= | |
subroutine LATE-gravity-rules | |
======================================================================================================= | |
(clear falling from just fallen objects) | |
late [falling] -> [] | |
(pushable thing becomes falling if nothing underneath, or if thing underneath is falling) | |
late down [pushable no falling| no object] -> [pushable falling | ] | |
late down [arm:directions | spike] -> [arm:directions falling | spike] | |
late down [pushable no falling | falling] -> [pushable falling | falling] | |
(propagate falling through connected boxes and through arms) | |
late [box:1 no falling][box:1 falling] -> [box:1 falling][box:1 falling] | |
+late [box:2 no falling][box:2 falling] -> [box:2 falling][box:2 falling] | |
+late [box:3 no falling][box:3 falling] -> [box:3 falling][box:3 falling] | |
+late [box:4 no falling][box:4 falling] -> [box:4 falling][box:4 falling] | |
+late [arm:directions no falling][arm:directions falling] -> [arm:directions falling][arm:directions falling] | |
(falling above not falling object -> not falling!) | |
late down [box:nr falling | object no falling] -> [box:nr | object] | |
+late down [arm:directions falling | object no spike no falling] -> [arm:directions | object] | |
(propagate not falling through connected boxes and through the arms) | |
+late [box:1 no falling][box:1 falling] -> [box:1 no falling][box:1 no falling] | |
+late [box:2 no falling][box:2 falling] -> [box:2 no falling][box:2 no falling] | |
+late [box:3 no falling][box:3 falling] -> [box:3 no falling][box:3 no falling] | |
+late [box:4 no falling][box:4 falling] -> [box:4 no falling][box:4 no falling] | |
+late [arm:directions no falling][arm:directions falling] -> [arm:directions no falling][arm:directions no falling] | |
late [arm:directions no falling][Player falling] -> [arm:directions no falling][Player] | |
late [arm:directions falling][Player no falling] -> [arm:directions falling][Player falling] | |
late down[falling Player | spike] -> [dead Player | spike] | |
late [roll_left] -> [] | |
late [roll_right] -> [] | |
======================================================================================================= | |
subroutine levitation-rules | |
======================================================================================================= | |
(give player movement based on cur:directions) | |
[Player cur:>] -> [> Player > cur:>] | |
(propagate player movement through arms) | |
[> Player][stationary arm:directions] -> [> Player][> arm:directions] | |
(give boxes movement based on cur:directions) | |
[stationary Box:nr cur:>] -> [> Box:nr > cur:>] | |
(Propagate movements through connected boxes) | |
+[> Box:1 cur:>][Box:1 no cur:>] -> [> Box:1 > cur:>][> Box:1 > cur:>] | |
+[> Box:2 cur:>][Box:2 no cur:>] -> [> Box:2 > cur:>][> Box:2 > cur:>] | |
+[> Box:3 cur:>][Box:3 no cur:>] -> [> Box:3 > cur:>][> Box:3 > cur:>] | |
+[> Box:4 cur:>][Box:4 no cur:>] -> [> Box:4 > cur:>][> Box:4 > cur:>] | |
(push off of a box) | |
[> arm:> stationary Player | stationary box:nr] -> [ > arm:> < Player < jumped < cur:< extends| > box:nr > cur:>] | |
(push off of a wall) | |
[> arm:> stationary Player | wall] -> [> arm:> < Player < jumped < cur:< | wall] | |
(push off of a spike -> deadly) | |
[> arm:> stationary Player | spike] -> [arm:> Player dead| spike] | |
(non-pushing arms get movement of player) | |
[> Player][stationary arm:directions] -> [> Player][> arm:directions] | |
(arm which you extended gets movement revoked) | |
[> Player][< arm:<] -> [> Player][arm:<] | |
(if arm hits a wall, stop player) | |
[> arm:directions | wall][moving Player cur:directions] -> [arm:directions | wall][Player] | |
(if arm hits a stationary pushable, transfer movement and stop player) | |
+[> arm:directions | stationary box:nr][> Player no jumped cur:>] -> [arm:directions | > box:nr > cur:>][Player stationary cur:>] | |
+[> arm:directions | stationary box:nr][> Player > jumped cur:>] -> [> arm:directions | > box:nr > cur:>][> Player > jumped stationary cur:>] | |
+[> arm:directions][Player no cur:>] -> [stationary arm:directions][Player] | |
(if arm hits spike, kill player) | |
+[> arm:directions | spike][moving Player cur:directions] -> [arm:directions | spike][Player dead] | |
[stationary cur:>] -> [] | |
=================================================== | |
(main loop for collisions with boxes in levitation) | |
=================================================== | |
(box hits other box -> transfer movement/cur:dir) | |
[> box:nr > cur:> | stationary box:nr no lost_travel] -> [box:nr lost_travel | > box:nr > cur:>] | |
(propagate lost_travel through boxes) | |
+[lost_travel box:1][> box:1 cur:>] -> [lost_travel box:1][lost_travel box:1] | |
+[lost_travel box:2][> box:2 cur:>] -> [lost_travel box:2][lost_travel box:2] | |
+[lost_travel box:3][> box:3 cur:>] -> [lost_travel box:3][lost_travel box:3] | |
+[lost_travel box:4][> box:4 cur:>] -> [lost_travel box:4][lost_travel box:4] | |
(propagate movement/cur:dir through connected boxes) | |
+[stationary box:1][> box:1 > cur:>] -> [> box:1 > cur:>][> box:1 > cur:>] | |
+[stationary box:2][> box:2 > cur:>] -> [> box:2 > cur:>][> box:2 > cur:>] | |
+[stationary box:3][> box:3 > cur:>] -> [> box:3 > cur:>][> box:3 > cur:>] | |
+[stationary box:4][> box:4 > cur:>] -> [> box:4 > cur:>][> box:4 > cur:>] | |
(box hits a wall -> remove cur:dir and movement) | |
+[> box:nr cur:> | obstacle] -> [box:nr lost_travel | obstacle] | |
+[> box:nr cur:> | box:nr lost_travel] -> [box:nr lost_travel | box:nr lost_travel] | |
+[> arm:directions | lost_travel] -> [arm:directions lost_travel | lost_travel] | |
(remove cur:directions and movement from connected boxes) | |
+[stationary box:1][> box:1 cur:>] -> [box:1][box:1] | |
+[stationary box:2][> box:2 cur:>] -> [box:2][box:2] | |
+[stationary box:3][> box:3 cur:>] -> [box:3][box:3] | |
+[stationary box:4][> box:4 cur:>] -> [box:4][box:4] | |
==================== | |
(end of loop) | |
==================== | |
[arm:directions lost_travel][> Player cur:>] -> [arm:directions][Player] | |
[stationary Player][> arm:directions] -> [Player][arm:directions] | |
(remove temp objects) | |
[lost_travel] -> [] | |
[roll_left] -> [] | |
[roll_right] -> [] | |
================================================================================ | |
subroutine LATE-levitation-rules | |
================================================================================ | |
late [Player cur:directions | jumped] -> [Player | ] | |
(manually move arm after pushing a box) | |
late [arm:> extends | no object | box:nr cur:>][Player no cur:directions] -> [ | arm:> extends | box:nr cur:>][Player] | |
============== | |
WINCONDITIONS | |
============== | |
all Player on Target | |
======= | |
LEVELS | |
======= | |
section 1 | |
g##### | |
##...# | |
#...## | |
#....o | |
#..#.# | |
##...# | |
#p...# | |
###### | |
section 2 | |
g######## | |
#s......# | |
#.......# | |
#....#..# | |
#..#....o | |
#.......# | |
#.......# | |
#p......# | |
###s#s### | |
(section 3 | |
g########### | |
#..#....#..# | |
#..........# | |
#........#.# | |
#...#s...s.# | |
#.s....#...# | |
#.#....s...# | |
#..........# | |
#.s#s......# | |
#..#.......o | |
#p.........s | |
###s###s####) | |
section 3 | |
g######### | |
#........# | |
#..ss..3.# | |
#..ss..2p# | |
s.4...s### | |
####..##.o | |
#........# | |
#.....#..# | |
##.....#s# | |
########## | |
section 4 | |
g######## | |
#..###..# | |
#.......# | |
#...3...# | |
#...#...# | |
#.......o | |
#.......# | |
#.......# | |
#p....### | |
######### | |
section 5 | |
go######### | |
#......#### | |
#..#......# | |
#s..p.....# | |
#...##....# | |
#....1..#.# | |
#...###...# | |
##......### | |
####....### | |
########### | |
(x##### | |
##...# | |
#...## | |
#....o | |
#..#.# | |
##...# | |
#p...# | |
###### | |
x######### | |
#.######## | |
o.#..1.### | |
#...p2..## | |
#..###...# | |
#........# | |
#.......## | |
########## | |
x########## | |
#..3.....## | |
#.s#....### | |
#..s.42..## | |
#....#s..## | |
#.....#...o | |
#........s# | |
#p.......## | |
######..### | |
########### | |
x######### | |
#........# | |
#..ss..3.# | |
#..ss..2p# | |
s.4...s### | |
####..##.o | |
#........# | |
#.....#..# | |
##.....#s# | |
########## | |
x########o#### | |
##..........## | |
#.......#...## | |
#...4.3.#...## | |
#...####....## | |
#p..........## | |
#####..#.....# | |
s.s.##.##....# | |
....s#.......# | |
.....#..#s.s## | |
....s#########) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment