Skip to content

Instantly share code, notes, and snippets.

@Draknek
Last active December 14, 2025 18:18
Show Gist options
  • Select an option

  • Save Draknek/2eb3eea974f4d8bf6afcb8da4a5b5547 to your computer and use it in GitHub Desktop.

Select an option

Save Draknek/2eb3eea974f4d8bf6afcb8da4a5b5547 to your computer and use it in GitHub Desktop.
Treasure Dive
https://puzzlescriptnext.polyomino.com/editor.html
title Treasure Dive
author Alan Hazelden & Andrew Shouldice
homepage alan.draknek.org
tween_length 0.1
//again_interval 0.075
realtime_interval 0.16
smoothscreen 15x9 5x3
//verbose_logging
// enable one-line comments
========
OBJECTS
========
Background
blue
NormalWall
darkred
Current:right
lightblue #1d3ff6
10111
11011
11101
11011
10111
Current:directions
lightblue #1d3ff6
copy: Current:right rot:right:directions
ToDissipate
lightblue
.....
..0..
.0.0.
..0..
.....
CurrentEmitter:right
darkred red
00000
00001
00001
00001
00000
CurrentEmitter:directions
darkred red
copy: CurrentEmitter:right rot:right:directions
Player
yellow
.000.
00000
00000
00000
.000.
WoodCrate
brown orange
00000
01110
01110
01110
00000
MetalCrate
darkgrey grey
00000
01110
01110
01110
00000
Mine
grey red
.0.0.
00000
.010.
00000
.0.0.
ActiveCurrentBlocker
transparent
====
TAGS
====
=======
LEGEND
=======
. = Background
# = NormalWall
P = Player
* = WoodCrate
@ = MetalCrate
! = Mine
Wall = NormalWall or CurrentEmitter:directions
PushedByCurrent = Player or WoodCrate or Mine
PushedByPlayer = PushedByCurrent or MetalCrate
Solid = Wall or Player or PushedByPlayer
PushableCurrentBlocker = WoodCrate or MetalCrate
BlocksCurrent = Wall or ActiveCurrentBlocker
HasGravity = WoodCrate or MetalCrate
a = CurrentEmitter:left
b = CurrentEmitter:right
c = CurrentEmitter:up
d = CurrentEmitter:down
(e = Current:left
f = Current:right
g = Current:up
h = Current:down)
=======
SOUNDS
=======
================
COLLISIONLAYERS
================
Background
Current:directions, ActiveCurrentBlocker
ToDissipate
Player, Wall, WoodCrate, MetalCrate, Mine
======
RULES
======
// spawn new currents
[ CurrentEmitter:> no Current:directions ] -> [ CurrentEmitter:> Current:> ]
// If player is caught in current, don't let them move
[ moving Player Current:> | no Solid ] -> [ stationary Player Current:> | ]
// Push objects
[ > Player | PushedByPlayer ] -> [ > Player | > PushedByPlayer ]
[ > PushedByPlayer | PushedByPlayer ] -> [ > PushedByPlayer | > PushedByPlayer ]
// pushing/carrying things on current, and gravity
once [] -> gosub current_push
// redirect currents
[ stationary MetalCrate ] -> [ MetalCrate ActiveCurrentBlocker ] // non-falling metal crates block and redirect current
[ PushableCurrentBlocker Current:directions ] -> [ PushableCurrentBlocker ] // crates remove current on their tile
once [] -> gosub current_redirect
once [] -> gosub current_push
[ stationary WoodCrate ] -> [ WoodCrate ActiveCurrentBlocker ] // non-falling wood crates block and redirect current - then recalculate
once [] -> gosub current_redirect
[ > Current:> | BlocksCurrent ] -> [ | BlocksCurrent ] // this handles if we're blocked but don't have anything to the side to redirect
[ action Current:> PushedByCurrent ] -> [ Current:> > PushedByCurrent ]
[ action Current:> Wall ] -> [ Wall ]
// dissipate conflicting current
[ ToDissipate ] -> []
[ Current:> | no ToDissipate ] -> [ Current:> | < ToDissipate ]
[ Current:> | > ToDissipate ] -> [ Current:> | action ToDissipate ]
[ Current:> | perpendicular ToDissipate ] -> [ Current:> | action ToDissipate ]
[ Current:> | action ToDissipate ] -> [ | action ToDissipate no Current:directions ]
[ > ToDissipate ] -> []
// mark currents for movement
[ Current:> ] -> [ > Current:> ]
// cleanup
[ > PushableCurrentBlocker | Current:directions ] -> [ > PushableCurrentBlocker | ]
late [ ActiveCurrentBlocker ] -> []
subroutine current_push
[ stationary PushedByCurrent Current:> ] -> [ > PushedByCurrent Current:> ]
[ Current:> | stationary WoodCrate ] -> [ Current:> | > WoodCrate ]
[ > PushedByCurrent | stationary PushedByCurrent ] -> [ > PushedByCurrent | > PushedByCurrent ]
[ stationary HasGravity ] -> [ down HasGravity ]
startloop
[ > PushedByCurrent | stationary Solid ] -> [ action PushedByCurrent | Solid ]
down [ action WoodCrate | Current:< ] -> [ WoodCrate | Current:< ]
down [ action HasGravity | no Solid ] -> [ down HasGravity | ]
[ action PushedByCurrent ] -> [ PushedByCurrent ]
down [ > HasGravity | stationary Solid ] -> [ HasGravity | Solid ]
endloop
subroutine current_redirect
[ Current:> | BlocksCurrent ] -> [ > Current:> | BlocksCurrent ] // detect blocked current
[ perpendicular Current:perpendicular | BlocksCurrent ] -> [ < Current:perpendicular | BlocksCurrent ] // if current is blocked, try changing direction
[ > Current:perpendicular | BlocksCurrent ] -> [ | BlocksCurrent ] // if new direction is still blocked, current is blocked on 3 sides
[ > Current:perpendicular ] -> [ action Current:> ] // otherwise we can change direction
==============
WINCONDITIONS
==============
=======
LEVELS
=======
###############
#####...#######
####..p.##...##
###.....#..@.##
##b.......##..#
####...##.....#
#####........a#
#..#........###
#...@.....#####
##..###..######
##..#.#..##..##
##.....@......#
#......##.....#
#..##c###.....#
#....###.....##
#............a#
#..##...###..##
#####...#######
#####....#d####
#####..*...#..#
####...@......#
####...#.....##
#####.......###
######..#######
###############
// test levels
###############
#...*.@...*.###
#...@.##c.@.###
#...a.....#...#
#.....#.......#
#####.*.......#
#...a.#c......#
#...@.p.......#
############c##
###############
####......*.###
####......#.###
#.............#
#..*..........#
#..*.......!!!#
#..*..........#
#..*..p..@....a
##c############
###############
#..#..###..#..#
#..#..###..#..#
#..#..###..#..#
#.............#
#......p......#
#...*...*.*...#
#.*.*.*.*.*.*.#
##c#c#c#c#c#c##
// undefined or unexpected behaviour
// When current is blocked by 2x wood crates, it doesn't push either
// - even if one could be pushed and one couldn't be
// Do we want this behaviour?
// If not, what is the intended behaviour?
// My instinct: in this specific scenario, both should be pushed
// (so bottom-left would push both, and then current would be unchanged, and bottom-right would push the one that can be pushed, and then current would redirect)
####d#####d####
##...........##
##...........##
##.*.@...@.@.##
####d##p##d####
##...........##
##...........##
##.*.*.##*.*.##
###############
// When wood crate hits two competing currents, the one that the crate was not in wins.
// Do we want this behaviour?
// If not, what is the intended behaviour?
###############
#b.*..###..*.a#
##.#.......#.##
#b...........a#
##..p........##
##...a#.#b...##
##...........##
##...*...*...##
###c#######c###
// When wood crate hits two competing currents, and one is upwards, it can bounce up and down
// Do we want this behaviour?
// If not, what is the intended behaviour?
######d#d######
##...........##
#b.*.......*.a#
##.#.......#.##
##..p#####...##
##...........##
#b.*.......*.a#
##.#.......#.##
######c#c######
// mini-puzzles
// goal: get into the cave on the left
###############
#######....####
###..!......###
###.###.......#
#.....##..*.p.#
#.....##..*..##
#.....###c#####
###############
// goal: get the grey thing out of the cave on the left
###############
#####.***....##
#####.#d#.....#
#####.#.#.....#
###........####
###...##....###
###.!.#..p..###
#######.....###
#######....####
###############
//goal: get the grey thing out of the cave at the top
############
###...######
##.....#####
##.!...#####
#####.######
##.@*.....##
#..#d##....#
#..#.##....#
#.......####
##c##..p..##
#####.....##
#####....###
#####c######
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment