Last active
November 20, 2023 01:53
-
-
Save weeble/cf5fa065aa04b5bc6f8ba1f5082f7102 to your computer and use it in GitHub Desktop.
Void Stranger Mini (PuzzleScript Script)
This file contains 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 in http://www.puzzlescript.net/editor.html |
This file contains 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 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