Skip to content

Instantly share code, notes, and snippets.

@weeble
Last active November 20, 2023 01:53
Show Gist options
  • Save weeble/cf5fa065aa04b5bc6f8ba1f5082f7102 to your computer and use it in GitHub Desktop.
Save weeble/cf5fa065aa04b5bc6f8ba1f5082f7102 to your computer and use it in GitHub Desktop.
Void Stranger Mini (PuzzleScript Script)
Play this game by pasting the script in http://www.puzzlescript.net/editor.html
title Void Stranger Mini
author Nettie
homepage https://mastodon.scot/@nettles
(
I'm trying to implement as many of the core game mechanics as possible.
I have included a small selection of levels from Void Stranger to test
things out, but it's not really designed to be a good play experience.
My goals are a. prove it can be done, and b. have something good
enough to practice puzzle solutions in. Play about with it and hack at
the code, but don't really expect it to be a game in its own right.
Some areas probably have low accuracy. Things to look out for:
* Tie breaking rules are uncertain, e.g. for diamonds when more than
one path to the player is the same length.
* I'm not dreadfully sure when it's possible for something to enter
a space on the same turn another thing leaves. E.g. shadows,
enemies going in the same or perpendicular directions.
* I've had a number of bugs with glass and trap tiles, I wouldn't be
surprised if there are more hiding in there.
* Shadows are dreadfully complicated and I've only had limited
experience with them in the game, so I may have gotten the corner
cases wrong.
* I think it's probably not faithful to the game around what
happens if you move onto the exit at the same time a monster
will kill you or one of your shadows falls into the void. I'm not
even sure what's the correct behaviour.
* Similarly, there may be timing issues around pressing/unpressing
buttons at the same time you move onto the exit.
Some things are missing:
* Memory fragments aren't implemented. (Though they would be purely
cosmetic if they were - there's no way to carry state between
levels in PuzzleScript.)
* The first and second burdens haven't been implemented. (I still
don't have the second burden so I don't even know how it works.)
* The third burden is implemented, though with no indicator.
* Engraving patterns isn't implemented and likely won't be.
* I don't understand how the very rare spiky statues work so I
haven't implemented them. I suspect they have custom behaviour
each time they appear.
* No NPCs are implemented. (A chase NPC might be doable - I think
the logic is similar to the diamonds.)
* The smiling statues have no special behaviour.
* The black statues show a cosmetic message in the right
circumstances.
* The status bar is never going to show numbers or operate as in
the game.
In case you're wondering, my own progress is that I've rolled the
credits once. I haven't gone VOID yet so I don't really know how
that works. I have the first and third burdens, I understand the
mural cypher but I've still to solve most of the 6x6 rooms. I'm
not looking for spoilers, so if you're going to send bug reports
about game elements I've not encountered, I will probably ignore
them! But do feel free to send bug reports about anything that is
obviously wrong.
You can find me:
* On Mastodon at https://mastodon.scot/@nettles
* On Twitter at https://www.twitter.com/weeble
* On Twitch at https://twitch.tv/clockworknettie
)
norepeat_action
run_rules_on_level_start
again_interval 0.08
(
debug
verbose_logging
)
========
OBJECTS
========
Storage
red
0...0
.....
.....
.....
0...0
( Floors -------------------------------------------- )
Floor
white
Void
black
VoidCliff
black grey darkgrey
11111
21212
02020
00000
00000
Glass
white lightgrey
11100
11000
10001
00011
00111
Circle
grey white lightgrey
10001
01210
02120
02220
10001
CrazedGlass
white grey
10101
01010
10101
01010
10101
DormantTrap
grey lightgrey black
01110
10001
10101
10001
01110
ActiveTrap
grey white
00100
01110
11011
01110
00100
PrimedTrap
grey white
00100
01110
11011
01110
00100
BurnedTrap
orange
Button
grey white
11111
11111
11111
01110
10001
Exit
white grey darkgrey
22222
11222
10112
10101
10101
Lock
grey white
10001
00111
00100
11100
10001
( Walls ----------------------------------------------- )
Wall
lightgrey grey darkgrey black
12222
01222
00122
01112
11111
LockedChest
white lightgray darkgrey
10001
11211
22222
10001
11111
EmptyChest
white lightgray darkgrey
12221
12221
11111
10001
11111
( Player --------------------------------------------- )
LadyGrayE
black white lightgray grey
..000
.0000
.0222
.3330
33303
LadyGrayW
black white lightgray grey
000..
0000.
2220.
0333.
30333
LadyGrayS
black white lightgray grey
.000.
00000
02220
.303.
30333
LadyGrayN
black white lightgray grey
.000.
00000
00000
.333.
33333
( Shadows ------------------------------------------- )
ShadowE
black white lightgray grey
..000
.0000
.0001
.0000
00000
ShadowW
black white lightgray grey
000..
0000.
1000.
0000.
00000
ShadowS
black white lightgray grey
.000.
01010
00000
.000.
00000
ShadowN
black white lightgray grey
.000.
00000
00000
.000.
00000
MoveToken
lightblue
.....
.....
.....
.....
.....
ProtoShadow
purple
.....
.....
.....
.....
.....
( Pushables ----------------------------------------- )
Rock
black grey darkgrey
.111.
11210
12102
11220
.200.
StatueCif
black grey
.010.
01010
00100
00000
00000
StatueSmile
grey black
.010.
01010
01110
10001
00000
StatueSolitary
grey black
00.00
.101.
11011
01110
10101
Gargoyle
grey black
01.10
01010
11011
01110
10101
GargoyleAwake
grey black white
01.10
21012
12021
01110
10101
( Enemies --------------------------------------------- )
Diamond
grey black white
..0..
.000.
00211
.011.
..1..
DiamondDormant
black white
.101.
10101
01110
10101
.101.
Mouthy
grey black white
.000.
00000
02120
01110
.010.
Bull
black white grey
.000.
01010
02220
00200
22022
BullE
black white grey
.000.
00000
00010
00222
2202.
BullW
black white grey
.000.
00000
01000
22200
.2022
BullS
black white grey
.000.
00000
01010
02220
.020.
BullN
black white grey
.000.
00000
00000
00000
22022
SnekE
grey black
..010
..000
1.10.
1..00
.100.
SnekW
grey black
010..
000..
.01.1
00..1
.001.
GrubS
grey black lightgray darkgrey
.212.
02220
00000
32223
.212.
GrubN
grey black lightgrey
.222.
00100
02220
.000.
..1..
Hand
grey white black
..00.
0.000
00000
01210
.000.
HMirrorS
grey white black
.000.
01210
01110
01110
00.00
HMirrorE
grey white black
.000.
01122
01110
01110
00.00
HMirrorW
grey white black
.000.
22110
01110
01110
00.00
HMirrorN
grey white black
.000.
01110
01110
01110
00.00
BMirrorS
grey black white
.000.
01210
01110
01110
00.00
BMirrorE
grey black white
.000.
01122
01110
01110
00.00
BMirrorW
grey black white
.000.
22110
01110
01110
00.00
BMirrorN
grey black white
.000.
01110
01110
01110
00.00
VMirrorS
black grey white
.000.
01210
01110
01110
00.00
VMirrorE
black grey white
.000.
01122
01110
01110
00.00
VMirrorW
black grey white
.000.
22110
01110
01110
00.00
VMirrorN
black grey white
.000.
01110
01110
01110
00.00
( Markers -------------------------------------- )
SearchFront
yellow
.....
.000.
.0.0.
.000.
.....
Searching
green
.....
..0..
.000.
..0..
.....
Searched
blue
.....
.....
..0..
.....
.....
Moved
pink
..0..
..0..
..0..
..0..
..0..
TurnIntent
pink
.....
.000.
..0..
..0..
.....
PlayerFocus
pink
.....
.00..
.0.0.
..00.
.....
Sin
red
Destination
purple
.....
.....
..0..
.....
.....
Annihilated
red
.....
.0.0.
..0..
.0.0.
.....
Suppressor
red
.....
.....
.....
.....
.....
Departed
brown
.....
.....
.....
.....
.....
( Animations -------------------------------------- )
Explosion1
white gray black
..1..
.111.
11011
.111.
..1..
Explosion2
white gray
...1.
1....
..1..
....1
.1...
Sparkle1
white gray darkgrey
101..
0001.
101..
.1...
.....
(
2212.
1002.
20012
2122.
.2.0.
)
Sparkle2
white gray darkgrey
.....
...1.
..101
.1000
..101
(
.212.
22122
11011
22122
.212.
)
Sparkle3
white gray darkgrey
.....
..1..
.101.
..1..
.....
(
.0.1.
..111
...1.
1....
..1..
)
Falling1
gray darkgrey
.....
.111.
10001
10001
.111.
Falling2
#666 #444
.....
.....
.111.
.111.
.....
Lightning1
white gray
.100.
..00.
.010.
.001.
.00..
Lightning2
gray darkgrey
.01..
..0..
.010.
.00..
.10..
=======
LEGEND
=======
` = Storage and Void and Suppressor
. = Floor
+ = Void
# = Wall
Q = LockedChest
X = EmptyChest
/ = Glass
T = DormantTrap
& = Lock
_ = Button
E = Exit
: = Circle
@ = LadyGrayS and Floor
* = DiamondDormant and Floor
1 = DiamondDormant and Exit
S = SnekE and Floor
Z = SnekW and Floor
W = GrubS and Floor
M = GrubN and Floor
G = Mouthy and Floor
B = Bull and Floor
H = Hand and Floor
L = HMirrorS and Floor
9 = BMirrorS and Floor
8 = VMirrorS and Floor
O = Rock and Floor
2 = Rock and Glass
C = StatueCif and Floor
U = StatueSmile and Floor
$ = StatueSolitary and Floor
, = StatueSolitary and Exit
! = Gargoyle and Floor
AnyVoid = Void or VoidCliff
Player = LadyGrayE or LadyGrayW or LadyGrayN or LadyGrayS
Background = AnyVoid or Floor or Glass or CrazedGlass or DormantTrap or ActiveTrap or PrimedTrap or Wall or BurnedTrap or Lock or Exit or Button or EmptyChest or LockedChest or Circle
NonDormantTrap = ActiveTrap or PrimedTrap
Pushable = Rock or StatueCif or StatueSmile or StatueSolitary or Gargoyle or GargoyleAwake
( WallLike - immovable, impermeable. )
WallLike = Wall or EmptyChest or LockedChest
( Solid - blocks pushables. )
Solid = Wall or Pushable or EmptyChest or LockedChest
AnyDiamond = Diamond or DiamondDormant
AnySnek = SnekW or SnekE
AnyGrub = GrubS or GrubN
AnyBull = Bull or BullE or BullW or BullS or BullN
AnyHMirror = HMirrorS or HMirrorE or HMirrorN or HMirrorW
AnyBMirror = BMirrorS or BMirrorE or BMirrorN or BMirrorW
AnyVMirror = VMirrorS or VMirrorE or VMirrorN or VMirrorW
AnyMirror = AnyHMirror or AnyBMirror or AnyVMirror
AnyShadow = ShadowE or ShadowN or ShadowS or ShadowW
Leader = Player or AnyShadow
ShadowPresent = AnyShadow or ProtoShadow
Enemy = AnyDiamond or Mouthy or AnySnek or AnyGrub or AnyBull or Hand or AnyHMirror or AnyBMirror or AnyVMirror
Fatal = Enemy or AnyShadow
Movable = Player or Pushable or Enemy or AnyShadow
BlocksEnemy = Pushable or Enemy or EmptyChest or LockedChest
BlocksPlayer = Wall or Pushable or Enemy or EmptyChest or LockedChest
( Stuff that blocks line of sight for Bull and Mouthy. )
BlocksSight = Wall or Movable or EmptyChest or LockedChest
( Stuff you can pick up with the rod. )
Rodable = Floor or Glass or PrimedTrap or DormantTrap or Exit or Lock or Button or Circle
AnyExit = Exit or Lock
AnyTrap = DormantTrap or ActiveTrap or PrimedTrap
( Places you can step (and not fall). )
Walkable = Floor or Glass or AnyTrap or Exit or Button or Lock or Circle
( Places the player or reckless enemies, such as Mouthy )
( or mirror dudes, can step. And maybe fall. )
RecklessWalkable = AnyVoid or Walkable
( Any of the markers used during searches. )
AnySearch = SearchFront or Searching or Searched
( Stuff that should create a cliff decoration in the )
( void. )
HasCliff = Floor or Glass or CrazedGlass or Wall or AnyTrap or EmptyChest or LockedChest or Exit or Lock or Circle or Button
( Animation stuff. )
Falling = Falling1 or Falling2
Exploding = Explosion1 or Explosion2
Lightning = Lightning1 or Lightning2
Sparkling = Sparkle1 or Sparkle2 or Sparkle3
Animating = Falling or Exploding or Lightning or Sparkling
=======
SOUNDS
=======
sfx0 43273904 ( thud )
sfx1 13171901 ( fall )
sfx2 37104707 ( push )
sfx3 12936301 ( annihilate )
sfx4 15258102 ( lightning )
sfx5 93276504 ( shatter )
sfx6 4057307 ( click )
sfx7 44029307 ( rod )
sfx8 66786102 ( squish )
EndLevel 3252509 ( win - shuffling steps )
(
ShowMessage 96348902 ( Frilly laser explosion )
ShowMessage 3252609 ( Crystal fall )
ShowMessage 31802102 ( Big zappy explosion )
ShowMessage 92760102 ( Laser shrivel )
ShowMessage 65699902 ( Another fall )
)
================
COLLISIONLAYERS
================
Background
Movable, AnyShadow
Animating
Storage
AnySearch
Annihilated
Destination
Moved
TurnIntent
PlayerFocus
Sin
Suppressor
MoveToken
ProtoShadow
Departed
======
RULES
======
( Animation ------------------------------------------ )
( Suppressor on the Storage cell is a marker that this )
( is an animation frame and no movement should occur. )
[Animating] [Storage] -> [Animating] [Storage Suppressor]
[Explosion2] -> []
[Explosion1] -> [Explosion2] again
[Falling2] -> []
[Falling1] -> [Falling2] again
[Lightning2] -> []
[Lightning1] -> [Lightning2] again
[Sparkle3] -> []
[Sparkle2] -> [Sparkle3] again
[Sparkle1] -> [Sparkle2] again
( Player -------------------------------------------- )
[UP Player] -> [UP LadyGrayN]
[RIGHT Player] -> [RIGHT LadyGrayE]
[DOWN Player] -> [DOWN LadyGrayS]
[LEFT Player] -> [LEFT LadyGrayW]
( PlayerFocus is a marker to denote the cell the player )
( is facing. This greatly simplifies actions later. )
[PlayerFocus] -> []
RIGHT [LadyGrayE|] -> [LadyGrayE|PlayerFocus]
LEFT [LadyGrayW|] -> [LadyGrayW|PlayerFocus]
UP [LadyGrayN|] -> [LadyGrayN|PlayerFocus]
DOWN [LadyGrayS|] -> [LadyGrayS|PlayerFocus]
( First copy player movement to mirror dudes. )
( Needs to come before anything that cancels player movement. )
( Horizontal dudes... )
VERTICAL [> Player] [AnyHMirror] -> [> Player] [> AnyHMirror]
HORIZONTAL [> Player] [AnyHMirror] -> [> Player] [< AnyHMirror]
( 180 degree dudes... )
[> Player] [AnyBMirror] -> [> Player] [< AnyBMirror]
( Vertical dudes... )
VERTICAL [> Player] [AnyVMirror] -> [> Player] [< AnyVMirror]
HORIZONTAL [> Player] [AnyVMirror] -> [> Player] [> AnyVMirror]
( Pushing )
[> Player | Pushable | Solid ] -> [Player | Pushable | Solid] sfx0
[> Player | Pushable | NO Solid] -> [Player | > Pushable |]
[> Player | Pushable ] -> [Player | Pushable] sfx0
( Rod action )
( Note that these rules can be unidirectional because )
( we previously placed the PlayerFocus on the tile we )
( are facing. Sin is a marker used to update Gargoyles )
( later. )
[action Player] [PlayerFocus Rodable NO Movable] [Storage NO Rodable] -> [Player Sin] [PlayerFocus Void NO Rodable] [Storage Rodable] sfx7
[action Player] [PlayerFocus AnyVoid] [Storage Rodable] -> [Player Sin] [PlayerFocus Rodable] [Storage NO Rodable] sfx7
( Sword action )
( We should probably have an inventory item to enable )
( this. )
[action Player] [PlayerFocus Enemy] -> [Player] [PlayerFocus NO Enemy] sfx3
( Chest unlock action )
DOWN [LockedChest PlayerFocus|action Player] -> [EmptyChest PlayerFocus|LadyGrayS] sfx6
( Tried to do an invalid action. Cancel the whole turn )
( because otherwise you can force enemy movement that )
( shouldn't be allowed. )
[action Player ] -> [Player] cancel
( We're finished with actions, we can clean this up. )
[PlayerFocus] -> []
( Player movement )
( Note that enemies move in reaction to the player. It's )
( important that the player moves first before enemies )
( make decisions about how to move. )
( Just kill the player now if they try to move into )
( an enemy. Otherwise later rules will cancel the )
( movement and they might get away with it. )
[> Player | Fatal] -> [Sparkle1 | Fatal] sfx3 again
( This first movement rule makes sure that a player
moving off a trap leaves it ready to fire even if a
monster steps on it in this turn. It's a more
specific version of the following rule. )
[> Player ActiveTrap | recklesswalkable NO BlocksPlayer] -> [PrimedTrap > MoveToken| Player RecklessWalkable ]
( This is the main player movement rule. )
[> Player | RecklessWalkable NO BlocksPlayer] -> [ > MoveToken | Player RecklessWalkable]
( If we have any shadows going on, fill the player's vacated space. )
[ ShadowPresent ] [ RIGHT MoveToken ] -> [ ShadowPresent ] [ ShadowE MoveToken ]
[ ShadowPresent ] [ LEFT MoveToken ] -> [ ShadowPresent ] [ ShadowW MoveToken ]
[ ShadowPresent ] [ DOWN MoveToken ] -> [ ShadowPresent ] [ ShadowS MoveToken ]
[ ShadowPresent ] [ UP MoveToken ] -> [ ShadowPresent ] [ ShadowN MoveToken ]
( Find the end of the conga line... )
[ AnyShadow ] -> [ AnyShadow Destination ]
RIGHT [ ShadowE | Leader Destination ] -> [ ShadowE | Leader ]
DOWN [ ShadowS | Leader Destination ] -> [ ShadowS | Leader ]
UP [ ShadowN | Leader Destination ] -> [ ShadowN | Leader ]
LEFT [ ShadowW | Leader Destination ] -> [ ShadowW | Leader ]
( When a ProtoShadow reaches the end of the conga line, )
( prevent it from shrinking this turn. )
[ AnyShadow Destination ProtoShadow ] [ MoveToken ] -> [ AnyShadow ] [ MoveToken ]
( Otherwise, the conga line recedes one shadow from the )
( back. )
[ AnyShadow Destination NO ProtoShadow ] [ MoveToken ] -> [ ] [ MoveToken ]
( DON'T clean up the MoveToken. But stop it moving. )
[ MOVING MoveToken ] -> [ MoveToken ]
[ Destination ] -> [ ]
( If we failed to move the player then we must have hit )
( a wall or an object or the edge of the play area. Play )
( a thud and revoke the movement. )
[> Player] -> [Player] sfx0
( ---------------------------------------------------- )
( Pushable movement )
[> Pushable | Enemy] -> [MoveToken|Pushable Sparkle1] sfx8 sfx2 again
[> Pushable | NO Solid] -> [MoveToken|Pushable] sfx2
( Enemy Intent --------------------------------------- )
( No enemy movement will occur here. We want to keep )
( the places we need to suppress movement during )
( animation to a minimum. )
( Diamonds )
( We do a flood fill from the player. "Searching" is )
( our current wavefront. "SearchFront" is the next )
( wavefront. "Searched" are the cells we have already )
( visited. )
[Diamond] -> [DiamondDormant]
[DiamondDormant] [Player] -> [DiamondDormant] [Player Searching]
[DiamondDormant | Searching] -> [> Diamond | Searching]
+ [Searching | Walkable NO Movable NO AnySearch] -> [Searching | Walkable SearchFront]
+ [Searching] -> [Searched]
+ [SearchFront] -> [Searching]
[AnySearch] -> [ ]
( Mouthy and Bully )
( Preserve movement )
RIGHT [BullE] -> [> BullE]
LEFT [BullW] -> [> BullW]
UP [BullN] -> [> BullN]
DOWN [BullS] -> [> BullS]
( Start moving if stationary and can see player )
( Note that we re-use the Searching state again, but )
( nothing carries over. )
[Player | NO Searching NO BlocksSight] -> [Player | > Searching]
[> Searching | NO Searching NO BlocksSight] -> [> Searching | > Searching]
[Player | Mouthy] -> [Player | < Mouthy]
[> Searching | Mouthy] -> [> Searching | < Mouthy]
[Player | Bull] -> [Player | < Bull]
[> Searching | Bull] -> [> Searching | < Bull]
[AnySearch] -> [ ]
( Select correct appearance for movement )
RIGHT [> Bull] -> [> BullE]
LEFT [> Bull] -> [> BullW]
UP [> Bull] -> [> BullN]
DOWN [> Bull] -> [> BullS]
( Bulls stop at platform edge )
[> AnyBull | NO Walkable] -> [Bull|]
( Blocked by walls and other enemies )
[> AnyBull | BlocksEnemy] -> [Bull|BlocksEnemy]
[> Mouthy | BlocksEnemy] -> [Mouthy|BlocksEnemy] (Can't happen?)
[> AnyBull | ] -> [AnyBull > Destination | ]
[> AnyBull ] -> [Bull]
[AnyBull > Destination] -> [> AnyBull]
( Mirror dudes )
( An earlier rule copied their movement intent from )
( the player, but now we fix them up to look in the )
( correct direction. )
[RIGHT AnyHMirror] -> [RIGHT HMirrorE]
[LEFT AnyHMirror] -> [LEFT HMirrorW]
[UP AnyHMirror] -> [UP HMirrorN]
[DOWN AnyHMirror] -> [DOWN HMirrorS]
[RIGHT AnyBMirror] -> [RIGHT BMirrorE]
[LEFT AnyBMirror] -> [LEFT BMirrorW]
[UP AnyBMirror] -> [UP BMirrorN]
[DOWN AnyBMirror] -> [DOWN BMirrorS]
[RIGHT AnyVMirror] -> [RIGHT VMirrorE]
[LEFT AnyVMirror] -> [LEFT VMirrorW]
[UP AnyVMirror] -> [UP VMirrorN]
[DOWN AnyVMirror] -> [DOWN VMirrorS]
[> AnyMirror | WallLike ] -> [AnyMirror | WallLike]
[> AnyMirror | < Enemy ] -> [AnyMirror | < Enemy]
[> AnyMirror | STATIONARY Enemy] -> [AnyMirror | Enemy]
( Sneks )
RIGHT [SnekE | Walkable NO BlocksEnemy] -> [> SnekE | Walkable]
LEFT [SnekW | Walkable NO BlocksEnemy] -> [> SnekW | Walkable]
[STATIONARY AnySnek] -> [AnySnek TurnIntent]
[SnekE TurnIntent] -> [SnekW]
[SnekW TurnIntent] -> [SnekE]
( Grubs )
DOWN [GrubS | Walkable NO BlocksEnemy] -> [> GrubS | Walkable]
UP [GrubN | Walkable NO BlocksEnemy] -> [> GrubN | Walkable]
[STATIONARY AnyGrub] -> [AnyGrub TurnIntent]
[GrubS TurnIntent] -> [GrubN]
[GrubN TurnIntent] -> [GrubS]
[Suppressor] [> Enemy] -> [Suppressor] [Enemy]
( Enemy movement and annihilation --------------------- )
[> Enemy | NO Movable] -> [> Enemy | Destination ]
[> Enemy | Destination NO Movable] -> [ MoveToken | Enemy Destination ]
[> Enemy | Destination Enemy ] -> [ MoveToken | Enemy Destination Annihilated ]
[> Enemy | Player] -> [Enemy | Sparkle1] sfx3 again
[> Enemy | AnyShadow] [Player] -> [ Enemy | Sparkle1 ] [ Sparkle1 ] sfx3 again
[Enemy Annihilated] -> [Sparkle1] sfx3 again
[Destination] -> [ ]
( Floors ---------------------------------------------- )
( Buttons )
late [AnyExit] -> [AnyExit Destination]
late [Button NO Movable] [AnyExit Destination] -> [Button] [AnyExit]
late [Lock Destination] -> [Exit Destination] sfx6
late [Exit NO Destination] -> [Lock] sfx6
late [Destination] -> []
( Glass )
late [MoveToken CrazedGlass] -> [Void] sfx5
late [No Movable CrazedGlass] -> [Void] sfx5
late [Movable Glass] -> [Movable CrazedGlass]
( Traps )
late [MoveToken ActiveTrap] -> [PrimedTrap]
late [No Movable ActiveTrap] -> [PrimedTrap]
late [Movable DormantTrap] -> [Movable ActiveTrap]
late [Movable PrimedTrap] -> [Movable BurnedTrap]
late [BurnedTrap | NonDormantTrap] -> [BurnedTrap | BurnedTrap]
late [BurnedTrap] -> [Void]
( DormantTrap - untouched )
( ActiveTrap - something is on it )
( PrimedTrap - it moved off and we are ready to fire )
( BurnedTrap - currently firing )
( Problem: A player can move off a trap and an enemy
move on at the same time, leaving it Active. We
special-case this for players, but we probably need
even more special-casing for shadows. )
( Circle )
( Is this wrong? It might trigger in an animation turn )
( or after activating an ability, but such activations )
( should be harmless. )
late [Player Circle] -> [Player Circle ProtoShadow]
( Stuff falls into the void --------------------------- )
( Special rule for Gargoyles because their wakefulness )
( is transferred when they fall. Unless they all fall )
( at the same time. )
late [Storage NO Suppressor] [GargoyleAwake AnyVoid] [Gargoyle] -> [Storage] [Falling1 AnyVoid] [GargoyleAwake] sfx1 again
( Special rule for shadows, because you die when they )
( die. )
late [Storage NO Suppressor] [AnyShadow AnyVoid] [Player] -> [Storage] [Falling1 AnyVoid] [Sparkle1] sfx1 again
( Normal falling rule. )
late [Storage NO Suppressor] [Movable AnyVoid] -> [Storage] [Falling1 AnyVoid] sfx1 again
( Statue effects -------------------------------------- )
( Destroy statues if all enemies are gone. )
( We re-use the Destination marker here. We could use a )
( fresh one if we preferred. )
late [StatueSolitary] -> [StatueSolitary Destination]
late [Enemy] [StatueSolitary Destination] -> [Enemy] [StatueSolitary]
late [StatueSolitary Destination] -> [Sparkle1] sfx3 again
( Sin )
( Player incurs sin when using the rod. Sin wakens
gargoyles. If there is at least one gargoyle and they
are all awake, the player is struck down. )
late [Sin] [Gargoyle] -> [NO Sin] [GargoyleAwake]
late [Sin] -> []
late [Gargoyle] [GargoyleAwake NO Sin] -> [Gargoyle] [GargoyleAwake Sin]
late [GargoyleAwake NO Sin] [Player] -> [GargoyleAwake] [Explosion1] sfx4 again
late [Sin] -> []
( Gargoyle death animation with lightning )
late [Explosion1] [Background] -> [Explosion1] [Void]
late [Explosion1] [Enemy] -> [Explosion1] []
late [Explosion1] [Movable NO GargoyleAwake] -> [Explosion1] []
late DOWN [|Explosion1] -> [Lightning1|Explosion1]
late DOWN [|Lightning1] -> [Lightning1|Lightning1]
( Cliff decorations ---------------------------------- )
( Make sure the front edge of floor and wall tiles is )
( visible when exposed by a void. )
( We would love to apply this _before_ the first turn, )
( but that requires run_rules_on_level_start and then )
( we would need to put a condition on _all_ monster )
( movement to prevent them moving in this phase. )
late DOWN [NO HasCliff | VoidCliff] -> [ | Void]
late DOWN [HasCliff | Void NO Storage] -> [HasCliff | VoidCliff]
late DOWN [StatueCif | Player Exit] -> [StatueCif | Player Exit] message Only a simple memory will remain
( Clean up ------------------------------------------- )
late [Suppressor] [Player] -> [] [Player]
late [MoveToken] -> [ ]
==============
WINCONDITIONS
==============
Some Player on Exit
=======
LEVELS
=======
MESSAGE This is a work in progress.
MESSAGE I made this mostly to practice levels I found hard.
(
##############
#............#
#............#
#............#
#............#
#............#
#............#
##############
............`.
)
( B121 - Glass, statues )
MESSAGE B121
##############
#.........++##
#@2.+.+.+.++##
#++h+h+h+.+o##
#$+.+.+.2.++##
#$+.......++##
#e$###########
##############
............`.
( B129 )
MESSAGE B129
##############
#+_+##...s...#
#+w+##......@#
#+.+##.u.....#
#...++.h...z$#
#+.+##......$#
#+.+#######$&#
##############
............`.
MESSAGE B131
##############
####//g/######
####///////###
##$$//@///g###
##e$.//////###
##$$/////./###
#####g//######
##############
............`.
( B164 - Mirror dudes )
MESSAGE B164
##############
##############
#,+###..###./#
#/.###9.###..#
#//###/.###..#
#@.###..###.l#
##############
##############
............`.
( B191 - Diamond, trap, gargoyles )
MESSAGE B191
##############
####1#####q..#
###t!....+..+#
##tt+tttt+t###
##tttt.!t++###
#+ttt.....@..#
##############
++++++++++++`+
( B192 - Diamond, trap )
MESSAGE B192
#######
##ttt##
##t@t##
##t.t##
#.t*t.#
###E###
#######
+++++`+
( B208 - Button, trap, circle )
MESSAGE B208
++++++++++++++
++++++++++++++
++++++++++++++
++:..t.&.t_+++
++.+++++++.+++
++@t...t..:+++
++++++++++++c+
++++++++++++++
............`.
( B223 - We want to see the conga line! )
MESSAGE B213
++++++++++++++
+c++++_..._+++
+++_....::..&+
+++.::..::..@+
+++.::..::.+++
+++.::...._+++
+++_..._++++c+
++++++++++++++
............`.
( B002 - Diamond, chest )
MESSAGE B002
##############
#.......###o##
#....##.##/./#
#*e..##....q.#
#######.##...#
#######.##...#
##@.....######
##############
............`.
MESSAGE "We have no hope and yet we live in longing."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment