├── .build └── buildnumber.txt ├── .github └── FUNDING.yml ├── .gitignore ├── .idea ├── .name ├── PuzzleEngine.iml ├── encodings.xml ├── misc.xml ├── modules.xml ├── scopes │ └── scope_settings.xml ├── vcs.xml └── workspace.xml ├── README.md ├── compile.js ├── installing_on_windows_diary.txt ├── runserver.bat └── src ├── .htaccess ├── Documentation ├── about.html ├── actionbutton.html ├── collisionlayers.html ├── credits.html ├── css │ ├── bootstrap-theme.css │ └── bootstrap.css ├── directions.html ├── documentation.html ├── executionorder.html ├── faq.html ├── fonts │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.svg │ ├── glyphicons-halflings-regular.ttf │ └── glyphicons-halflings-regular.woff ├── gifs.html ├── ico │ ├── favicon.ico │ └── favicon.png ├── images │ ├── 1380414_1376117409297752_1657046753_n.jpg │ ├── actiontest.gif │ ├── constellationz.gif │ ├── editoroutput.png │ ├── editorplus.png │ ├── editorsave.png │ ├── eyefollow.gif │ ├── horizontal_follow.gif │ ├── horizontalblock.gif │ ├── kettle.gif │ ├── leveleditor.png │ ├── limerick.gif │ ├── limerick_cropped.gif │ ├── nekopuzzle.gif │ ├── octat.gif │ ├── player.png │ ├── puzz_whale.gif │ ├── puzz_whale_cropped.gif │ ├── randomrobots.gif │ ├── rigid_scott1.gif │ ├── rigid_twolittlecrates1.gif │ ├── rigid_twolittlecrates2.gif │ ├── rigid_twolittlecrates3.gif │ ├── rigidbodies.gif │ ├── rigidfail1.gif │ ├── rigidfail2.gif │ ├── rigidsuccess_singleblock.gif │ ├── robotspawner.gif │ ├── sokoban.gif │ ├── sokoban_fairy.gif │ ├── sokoban_match3.gif │ ├── sokoban_new.gif │ ├── sokoban_new_cropped.gif │ ├── sokoban_reversed.gif │ ├── soundbuttons.png │ ├── sumo.gif │ ├── tumblr_2level.gif │ ├── tumblr_atlas.gif │ ├── tumblr_bigban.gif │ ├── tumblr_bomb.gif │ ├── tumblr_boom.gif │ ├── tumblr_bounce.gif │ ├── tumblr_castlemouse.gif │ ├── tumblr_closure.gif │ ├── tumblr_collapse.gif │ ├── tumblr_colors.gif │ ├── tumblr_columns.gif │ ├── tumblr_crategame.gif │ ├── tumblr_drop6.gif │ ├── tumblr_ebony_ivory.gif │ ├── tumblr_flower.gif │ ├── tumblr_flyingkick.gif │ ├── tumblr_heroesofsokoban3.gif │ ├── tumblr_hope.gif │ ├── tumblr_ice.gif │ ├── tumblr_itdies.gif │ ├── tumblr_janitor.gif │ ├── tumblr_kettle.gif │ ├── tumblr_legend.gif │ ├── tumblr_lex.gif │ ├── tumblr_limerick.gif │ ├── tumblr_microban.gif │ ├── tumblr_midas.gif │ ├── tumblr_pony.gif │ ├── tumblr_quest.gif │ ├── tumblr_rat.gif │ ├── tumblr_sok2.gif │ ├── tumblr_sokobond.gif │ ├── tumblr_train.gif │ ├── tumblr_whalegame.gif │ ├── tumblr_wordgame.gif │ ├── twitter_escher.gif │ ├── verbose_logging.png │ └── wordgame.gif ├── index.html ├── input.html ├── js │ ├── bootstrap.min.js │ └── jquery.js ├── keyboard_shortcuts.html ├── legend.html ├── leveleditor.html ├── levels.html ├── objects.html ├── permanent_urls.html ├── prelude.html ├── privacypolicy.html ├── randomness.html ├── realtime.html ├── rigidbodies.html ├── rules.html ├── rules101.html ├── sounds.html └── winconditions.html ├── access_token.py ├── auth.html ├── auth_pat.html ├── commit ├── css ├── codemirror.css ├── concat ├── console.css ├── dialog.css ├── docs.css ├── frontpage.css ├── gamecanvas.css ├── layout.css ├── midday.css ├── midnight.css ├── show-hint.css ├── soundbar.css └── toolbar.css ├── demo ├── I'm too far gone.txt ├── Loop Deleter.txt ├── README ├── actiontest.txt ├── againexample.txt ├── atlas shrank.txt ├── blank.txt ├── blockfaker.txt ├── bouncers.txt ├── byyourside.txt ├── cakemonsters.txt ├── castlecloset.txt ├── castlemouse.txt ├── chaos wizard.txt ├── coincounter.txt ├── collapse.txt ├── color chained.txt ├── constellationz.txt ├── cratopia.txt ├── cute train.txt ├── dropswap.txt ├── dungeon janitor.txt ├── easyenigma.txt ├── ebony and ivory.txt ├── gobble_rush.txt ├── heroes_of_sokoban.txt ├── heroes_of_sokoban_2.txt ├── heroes_of_sokoban_3.txt ├── icecrates.txt ├── it dies in the light.txt ├── kettle.txt ├── kishoutenketsu.html ├── ledchallenge.txt ├── leftrightnpcs.txt ├── legend of zokoban.txt ├── limerick.txt ├── lovendpieces.txt ├── lunar_lockout.txt ├── m c eschers armageddon.txt ├── manic_ammo.txt ├── mazetest.txt ├── mazezam.txt ├── microban.txt ├── midas.txt ├── modality.txt ├── naughtysprite.txt ├── nekopuzzle.txt ├── notsnake.txt ├── octat.txt ├── ponies jumping synchronously.txt ├── push.txt ├── puzzles.txt ├── randomrobots.txt ├── randomspawner.txt ├── rigid_and_little.txt ├── rigid_one_object.txt ├── rigid_scott1.txt ├── rigidfail1.txt ├── riverpuzzle.txt ├── robotarm.txt ├── scriptcross.txt ├── several_rigid_bodies.txt ├── slidings.txt ├── smother.txt ├── sok7.txt ├── sokoban_basic.txt ├── sokoban_eyeball.txt ├── sokoban_horizontal.txt ├── sokoban_match3.txt ├── sokoban_sticky.txt ├── sokobond demake.txt ├── stick_candy_puzzle_saga.txt ├── sumo.txt ├── take heart lass.txt ├── the_saga_of_the_candy_scroll.txt ├── threes.txt ├── tiny treasure hunt.txt ├── tunnel rat.txt ├── twolittlecrates1.txt ├── twolittlecrates2.txt ├── twolittlecrates3.txt ├── twolittlecrates4.txt ├── whaleworld.txt ├── wordgame.txt ├── wrappingrecipe.txt └── zenpuzzlegarden.txt ├── editor.html ├── fonts ├── PuzzleScripTt.woff ├── SourceSansPro-Regular.ttf ├── SourceSansPro-Regular.woff └── font-5x12.png ├── images ├── audio1.gif ├── audio10.gif ├── audio2.gif ├── audio3.gif ├── audio4.gif ├── audio5.gif ├── audio6.gif ├── audio7.gif ├── audio8.gif ├── audio9.gif ├── birdy.gif ├── clearConsole.gif ├── debugRules.png ├── mascot_128.png ├── mascot_256.png ├── mascot_32.png ├── mascot_512.png ├── mascot_512_colorful.png ├── mascot_64.png └── mascot_colorful.png ├── index.html ├── js ├── addlisteners.js ├── addlisteners_editor.js ├── buildStandalone.js ├── codemirror │ ├── active-line.js │ ├── anyword-hint.js │ ├── codemirror.js │ ├── comment.js │ ├── dialog.js │ ├── match-highlighter.js │ ├── search.js │ ├── searchcursor.js │ ├── show-hint.js │ └── stringstream.js ├── colors.js ├── compiler.js ├── compiler │ ├── identifiers.js │ ├── rule.js │ ├── rule_expansion.js │ ├── rule_groups.js │ ├── rule_parser.js │ └── sprites.js ├── console.js ├── debug.js ├── debug_off.js ├── editor.js ├── editor │ ├── error_messages.js │ ├── level_editor.js │ └── random_sound_generators.js ├── engine │ ├── bitvec.js │ ├── cell_pattern.js │ ├── commands_set.js │ ├── engine_base.js │ ├── generate_matches.js │ ├── level.js │ ├── log.js │ ├── message_screen.js │ ├── rule.js │ └── screen_layout.js ├── font.js ├── gamedat.js ├── globalVariables.js ├── graphics.js ├── inputoutput.js ├── jsgif │ ├── GIFEncoder.js │ ├── LZWEncoder.js │ └── NeuQuant.js ├── layout.js ├── makegif.js ├── mobile.js ├── parser.js ├── riffwave.js ├── rng.js ├── sfxr2.js ├── soundbar.js └── toolbar.js ├── new_demos ├── bouncers.txt ├── cakemonsters.txt └── castlemouse.txt ├── play.html ├── runserver ├── standalone.html └── tests ├── demo_list.txt ├── resources ├── errormessage_testdata.js ├── increpare_testdata.js ├── qunit-1.12.0.css ├── qunit-1.12.0.js ├── testdata.js ├── testingFrameWork.js ├── tests.js └── wrapper.js └── tests.html /.build/buildnumber.txt: -------------------------------------------------------------------------------- 1 | 1662 -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [increpare] 4 | patreon: increpare 5 | open_collective: puzzlescript 6 | custom: ['paypal.me/increparegames'] 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | .DS_Store 3 | */.DS_Store 4 | */*/.DS_Store 5 | */*/*/.DS_Store 6 | */*/*/*.DS_Store 7 | */*/*/*/*.DS_Store 8 | 9 | *.swp -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | PuzzleEngine -------------------------------------------------------------------------------- /.idea/PuzzleEngine.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/scopes/scope_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Pattern:Script 2 | ============== 3 | 4 | About 5 | ----- 6 | 7 | *Pattern:Script* is an open-source HTML5 game engine based on [PuzzleScript](https://www.puzzlescript.net). Try it out [here](https://clementsparrow.github.io/Pattern-Script/src/editor.html)! 8 | 9 | The manual has only been partially updated from PuzzleScript, as the project targets game devs with prior knowledge of PuzzleScript. A list of the new features (and planned features) is available [on the project's wiki](https://github.com/ClementSparrow/Pattern-Script/wiki) – you should start there to learn what Pattern:Script can do for you! 10 | 11 | If you want to contribute to the project, I suggest starting with reading these pages: 12 | - [What to contribute?](https://github.com/ClementSparrow/Pattern-Script/wiki/What-To-Contribute%3F) – most needed features and easiest features to implement 13 | - [How to contribute?]() – what do I need to contribute, how do I setup an environment to contribute, what code standard should I follow, how do I send my contributions, etc? 14 | 15 | Licence 16 | ------- 17 | 18 | The MIT License (MIT) 19 | 20 | Copyright (c) 2013 increpare for the original PuzzleScript software, 21 | (c) 2021-2022 ClementSparrow for the modifications of PuzzleScript and new Pattern:Script features 22 | 23 | Permission is hereby granted, free of charge, to any person obtaining a copy 24 | of this software and associated documentation files (the "Software"), to deal 25 | in the Software without restriction, including without limitation the rights 26 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 27 | copies of the Software, and to permit persons to whom the Software is 28 | furnished to do so, subject to the following conditions: 29 | 30 | The above copyright notice and this permission notice shall be included in 31 | all copies or substantial portions of the Software. 32 | 33 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 34 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 35 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 36 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 37 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 38 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 39 | THE SOFTWARE. 40 | -------------------------------------------------------------------------------- /installing_on_windows_diary.txt: -------------------------------------------------------------------------------- 1 | Ok keeping track of what I do to get puzzlescript building on windows. 2 | 3 | 1 - sync to github repo 4 | 2 - try opening the folder in vs code 5 | 3 - realize that the build scripts rely on the folder being called src and there being a parallel bin directory 6 | *4 - move everything to a src directory in the github structure (probably breaking things on mac) 7 | *5 - edited the ..gitignore file to take this into account 8 | 6 - try to run the non-compiled version (src/editor.html). Oh I can just run it in edge. Also chrome. Also firefox. (Much easier than on mac, where you need a http server). 9 | 10 | 11 | what external tools does my bash script need? 12 | 13 | images/minimize needs pngcrush 14 | https://www.npmjs.com/package/pngcrush 15 | 16 | css/concat uses concat 17 | https://www.npmjs.com/package/concat 18 | 19 | closure.jar 20 | https://www.npmjs.com/package/google-closure-compiler 21 | 22 | yuicompressor-2.4.8.jar 23 | https://www.npmjs.com/package/ycssmin 24 | 25 | htmlcompressor-1.5.3.jar 26 | https://www.npmjs.com/package/html-minifier-terser 27 | 28 | gzipper needs perl, lol 29 | gzipper 30 | https://www.npmjs.com/package/tar 31 | 32 | inliner 33 | https://www.npmjs.com/package/inliner 34 | 35 | directory cp = ncp 36 | 37 | 7 - install npm packages I'll probably need: 38 | npm i tar html-minifier-terser ycssmin google-closure-compiler concat imagemin imagemin-pngcrush inliner ncp 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /runserver.bat: -------------------------------------------------------------------------------- 1 | ipconfig 2 | python3 -m http.server -------------------------------------------------------------------------------- /src/.htaccess: -------------------------------------------------------------------------------- 1 | RewriteEngine on 2 | RewriteCond %{HTTP:Accept-Encoding} gzip 3 | RewriteCond %{REQUEST_FILENAME}.gz -f 4 | RewriteRule ^(.*)$ $1.gz [L] 5 | -------------------------------------------------------------------------------- /src/Documentation/actionbutton.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | The Action Button - PuzzleScript Documentation 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 23 | 24 | 25 | 26 | 27 | 50 | 51 |
52 | 53 | 54 |

55 |

59 |

60 | 61 | 62 |

The Action Button

63 |

64 | You want the player to respond to pressing action (X or SPACEBAR)? It's super easy. 65 |

66 |

 Edit[ Action Player | Sheep ] -> [  Action  Player | > Sheep  ]
67 | [ > Sheep |  Sheep ] -> [ blood | > Sheep ]
68 |

69 | You must feel so powerful now that you know how to ACTION. 70 |

71 | 72 |

73 | It's treated like a directional input, merely one that has no effect during the movement phase and is removed (so if you search for a moving player, it will detect someone doing an action. If you want to detect someone moving who is not doing an action, you can use the word ORTHOGONAL (which just means up/down/left/right). 74 |

75 | Action markers are discarded during the movement phase. 76 |

77 | So, what are you going to use the action button for? It seems to want to be a button for violence, and puzzle games mostly get by just fine without it, but maybe you have some awesome ideas :D

78 | 79 | 80 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /src/Documentation/css/bootstrap-theme.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 50px; 3 | padding-bottom:50px; 4 | } 5 | .starter-template { 6 | padding: 40px 15px; 7 | text-align: center; 8 | } 9 | 10 | 11 | dt { 12 | margin-top:20px; 13 | margin-left:-10px; 14 | padding-left:0px; 15 | margin-bottom:10px; 16 | /* background-color:lightgray;*/ 17 | } 18 | -------------------------------------------------------------------------------- /src/Documentation/documentation.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | PuzzleScript Documentation 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 23 | 24 | 25 | 26 | 27 | 50 | 51 |
52 |

53 |

56 |

57 | 58 |

Documentation

59 |

60 |

81 | 82 | 83 | 84 | 85 |
86 | 87 | 88 | 90 | 91 | 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /src/Documentation/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /src/Documentation/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /src/Documentation/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /src/Documentation/gifs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Making GIFs - PuzzleScript Documentation 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 23 | 24 | 25 | 26 | 27 | 50 | 51 |
52 | 53 |

54 |

58 |

59 |

Making GIFs

60 |

61 | Making gifs is crazy fun. 62 |

63 | From the editor, load a level, bop around in it a bit, and then press CTRL+K (or CMD+K if you're on osx), then BE PATIENT, then BAM a shiny GIF along with a download link should appear in the console in a short few moments. 64 |

65 | 66 |

67 | It's not the fastest generator in the world, and its speed depends on the length of the animation and the resolution of the game-screen in the editor. 68 |

69 | 70 | 71 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /src/Documentation/ico/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/ico/favicon.ico -------------------------------------------------------------------------------- /src/Documentation/ico/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/ico/favicon.png -------------------------------------------------------------------------------- /src/Documentation/images/1380414_1376117409297752_1657046753_n.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/1380414_1376117409297752_1657046753_n.jpg -------------------------------------------------------------------------------- /src/Documentation/images/actiontest.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/actiontest.gif -------------------------------------------------------------------------------- /src/Documentation/images/constellationz.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/constellationz.gif -------------------------------------------------------------------------------- /src/Documentation/images/editoroutput.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/editoroutput.png -------------------------------------------------------------------------------- /src/Documentation/images/editorplus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/editorplus.png -------------------------------------------------------------------------------- /src/Documentation/images/editorsave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/editorsave.png -------------------------------------------------------------------------------- /src/Documentation/images/eyefollow.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/eyefollow.gif -------------------------------------------------------------------------------- /src/Documentation/images/horizontal_follow.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/horizontal_follow.gif -------------------------------------------------------------------------------- /src/Documentation/images/horizontalblock.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/horizontalblock.gif -------------------------------------------------------------------------------- /src/Documentation/images/kettle.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/kettle.gif -------------------------------------------------------------------------------- /src/Documentation/images/leveleditor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/leveleditor.png -------------------------------------------------------------------------------- /src/Documentation/images/limerick.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/limerick.gif -------------------------------------------------------------------------------- /src/Documentation/images/limerick_cropped.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/limerick_cropped.gif -------------------------------------------------------------------------------- /src/Documentation/images/nekopuzzle.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/nekopuzzle.gif -------------------------------------------------------------------------------- /src/Documentation/images/octat.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/octat.gif -------------------------------------------------------------------------------- /src/Documentation/images/player.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/player.png -------------------------------------------------------------------------------- /src/Documentation/images/puzz_whale.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/puzz_whale.gif -------------------------------------------------------------------------------- /src/Documentation/images/puzz_whale_cropped.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/puzz_whale_cropped.gif -------------------------------------------------------------------------------- /src/Documentation/images/randomrobots.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/randomrobots.gif -------------------------------------------------------------------------------- /src/Documentation/images/rigid_scott1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/rigid_scott1.gif -------------------------------------------------------------------------------- /src/Documentation/images/rigid_twolittlecrates1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/rigid_twolittlecrates1.gif -------------------------------------------------------------------------------- /src/Documentation/images/rigid_twolittlecrates2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/rigid_twolittlecrates2.gif -------------------------------------------------------------------------------- /src/Documentation/images/rigid_twolittlecrates3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/rigid_twolittlecrates3.gif -------------------------------------------------------------------------------- /src/Documentation/images/rigidbodies.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/rigidbodies.gif -------------------------------------------------------------------------------- /src/Documentation/images/rigidfail1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/rigidfail1.gif -------------------------------------------------------------------------------- /src/Documentation/images/rigidfail2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/rigidfail2.gif -------------------------------------------------------------------------------- /src/Documentation/images/rigidsuccess_singleblock.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/rigidsuccess_singleblock.gif -------------------------------------------------------------------------------- /src/Documentation/images/robotspawner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/robotspawner.gif -------------------------------------------------------------------------------- /src/Documentation/images/sokoban.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/sokoban.gif -------------------------------------------------------------------------------- /src/Documentation/images/sokoban_fairy.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/sokoban_fairy.gif -------------------------------------------------------------------------------- /src/Documentation/images/sokoban_match3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/sokoban_match3.gif -------------------------------------------------------------------------------- /src/Documentation/images/sokoban_new.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/sokoban_new.gif -------------------------------------------------------------------------------- /src/Documentation/images/sokoban_new_cropped.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/sokoban_new_cropped.gif -------------------------------------------------------------------------------- /src/Documentation/images/sokoban_reversed.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/sokoban_reversed.gif -------------------------------------------------------------------------------- /src/Documentation/images/soundbuttons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/soundbuttons.png -------------------------------------------------------------------------------- /src/Documentation/images/sumo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/sumo.gif -------------------------------------------------------------------------------- /src/Documentation/images/tumblr_2level.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/tumblr_2level.gif -------------------------------------------------------------------------------- /src/Documentation/images/tumblr_atlas.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/tumblr_atlas.gif -------------------------------------------------------------------------------- /src/Documentation/images/tumblr_bigban.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/tumblr_bigban.gif -------------------------------------------------------------------------------- /src/Documentation/images/tumblr_bomb.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/tumblr_bomb.gif -------------------------------------------------------------------------------- /src/Documentation/images/tumblr_boom.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/tumblr_boom.gif -------------------------------------------------------------------------------- /src/Documentation/images/tumblr_bounce.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/tumblr_bounce.gif -------------------------------------------------------------------------------- /src/Documentation/images/tumblr_castlemouse.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/tumblr_castlemouse.gif -------------------------------------------------------------------------------- /src/Documentation/images/tumblr_closure.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/tumblr_closure.gif -------------------------------------------------------------------------------- /src/Documentation/images/tumblr_collapse.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/tumblr_collapse.gif -------------------------------------------------------------------------------- /src/Documentation/images/tumblr_colors.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/tumblr_colors.gif -------------------------------------------------------------------------------- /src/Documentation/images/tumblr_columns.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/tumblr_columns.gif -------------------------------------------------------------------------------- /src/Documentation/images/tumblr_crategame.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/tumblr_crategame.gif -------------------------------------------------------------------------------- /src/Documentation/images/tumblr_drop6.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/tumblr_drop6.gif -------------------------------------------------------------------------------- /src/Documentation/images/tumblr_ebony_ivory.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/tumblr_ebony_ivory.gif -------------------------------------------------------------------------------- /src/Documentation/images/tumblr_flower.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/tumblr_flower.gif -------------------------------------------------------------------------------- /src/Documentation/images/tumblr_flyingkick.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/tumblr_flyingkick.gif -------------------------------------------------------------------------------- /src/Documentation/images/tumblr_heroesofsokoban3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/tumblr_heroesofsokoban3.gif -------------------------------------------------------------------------------- /src/Documentation/images/tumblr_hope.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/tumblr_hope.gif -------------------------------------------------------------------------------- /src/Documentation/images/tumblr_ice.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/tumblr_ice.gif -------------------------------------------------------------------------------- /src/Documentation/images/tumblr_itdies.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/tumblr_itdies.gif -------------------------------------------------------------------------------- /src/Documentation/images/tumblr_janitor.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/tumblr_janitor.gif -------------------------------------------------------------------------------- /src/Documentation/images/tumblr_kettle.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/tumblr_kettle.gif -------------------------------------------------------------------------------- /src/Documentation/images/tumblr_legend.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/tumblr_legend.gif -------------------------------------------------------------------------------- /src/Documentation/images/tumblr_lex.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/tumblr_lex.gif -------------------------------------------------------------------------------- /src/Documentation/images/tumblr_limerick.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/tumblr_limerick.gif -------------------------------------------------------------------------------- /src/Documentation/images/tumblr_microban.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/tumblr_microban.gif -------------------------------------------------------------------------------- /src/Documentation/images/tumblr_midas.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/tumblr_midas.gif -------------------------------------------------------------------------------- /src/Documentation/images/tumblr_pony.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/tumblr_pony.gif -------------------------------------------------------------------------------- /src/Documentation/images/tumblr_quest.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/tumblr_quest.gif -------------------------------------------------------------------------------- /src/Documentation/images/tumblr_rat.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/tumblr_rat.gif -------------------------------------------------------------------------------- /src/Documentation/images/tumblr_sok2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/tumblr_sok2.gif -------------------------------------------------------------------------------- /src/Documentation/images/tumblr_sokobond.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/tumblr_sokobond.gif -------------------------------------------------------------------------------- /src/Documentation/images/tumblr_train.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/tumblr_train.gif -------------------------------------------------------------------------------- /src/Documentation/images/tumblr_whalegame.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/tumblr_whalegame.gif -------------------------------------------------------------------------------- /src/Documentation/images/tumblr_wordgame.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/tumblr_wordgame.gif -------------------------------------------------------------------------------- /src/Documentation/images/twitter_escher.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/twitter_escher.gif -------------------------------------------------------------------------------- /src/Documentation/images/verbose_logging.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/verbose_logging.png -------------------------------------------------------------------------------- /src/Documentation/images/wordgame.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/Documentation/images/wordgame.gif -------------------------------------------------------------------------------- /src/Documentation/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | Page Redirection 10 | 11 | 12 | 13 | If you are not redirected automatically, follow the link to the documentation. 14 | 15 | -------------------------------------------------------------------------------- /src/Documentation/input.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Input - PuzzleScript Documentation 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 23 | 24 | 25 | 26 | 27 | 50 | 51 |
52 | 53 |

54 |

58 |

59 | 60 |

Input

61 |

62 | When you press the arrow keys or action, this input is sent to the main player. 63 |

64 | Sometimes you will want to have several player entities on screen at once. Don't worry, input gets sent to all of them :) 65 |

66 | Sometimes you will want several different types of objects to be able to receive input. Let's call them Player1,Player2, Player3. You can define player as follows in the legend section 67 |

68 |

Player = Player1 or Player2 or Player3
69 |

70 | and then three of those entity types will receive input from the player. 71 |

72 | See kettle for an example of sending many inputs to many entities simultaneously. 73 |

74 |

75 | 76 | 77 | 79 | 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /src/Documentation/keyboard_shortcuts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Keyboard Shortcuts - PuzzleScript Documentation 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 23 | 24 | 25 | 26 | 27 | 50 | 51 |
52 | 53 |

54 |

58 |

59 |

Keyboard Shortcuts

60 |

61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 |
Script Editor
CTRL/ + /Comment/Uncomment selection.
CTRL + SHIFT + UP/DOWNMove up/down the lines containing the cursor/selection.
CTRL/ + ReturnRebuild game without restarting it.
CTRL/ + SHIFT + ReturnRebuild and restart game.
CTRL/ + FSearch.
CTRL/ + GFind next.
CTRL/ + SHIFT + GFind previous.
CTRL+SHIFT + F (Win)
71 | +ALT + F (Mac)
Replace.
Game Window
EToggle map editor.
CTRL/ + KGenerate an animated GIF.
Map Editor
1,2,3,4,5,6,7,8,9,0To select brush tiles.
- / =Move selected brush tile left/right respectively.
PPrint ascii-representation of level to console.
80 | 81 | 82 |

83 | 84 | 85 | 87 | 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /src/Documentation/legend.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Legend - PuzzleScript Documentation 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 23 | 24 | 25 | 26 | 27 | 50 | 51 |
52 | 53 | 54 | 55 |

56 |

61 |

62 | 63 |

Bird's-eye view of a PuzzleScript file

64 |

65 | A puzzlescript file is divided into 8 sections: 66 |

67 | 68 |

78 | 79 | 80 |

Legend

81 | This section has two purposes. Firstly, it's a place where you can set up single-character names for things so that you can type them in levels: 82 |

83 |

P = Player
 84 | . = Background
 85 | # = Wall
 86 | * = Crate
 87 | O = Target
 88 | @ = Crate and Target
89 |

90 | There is another purpose, and this is to define properties of objects that you can refer to in rules and elsewhere: 91 |

92 |

Flying = Bat or Bird
 93 | Obstacle = Wall or Lava or Water
94 |

95 | 96 | 97 |

98 | 99 | 100 | 102 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /src/Documentation/leveleditor.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Level Editor - PuzzleScript Documentation 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 23 | 24 | 25 | 26 | 27 | 50 | 51 |
52 | 53 | 54 |

55 |

59 |

60 |

The Level Editor

61 |

62 | In addition to editing the levels as text files, which is good for small modifications, there's a level editor. Just click the level editor button in the toolbar and you'll switch to editor mode in-game - 63 |

64 | 65 |

66 | You can left click to select tiles in the toolbar (the tiles are generated from the 1-letter object types defined in the legend and elsewhere - basically anything you can put on a map is displayed on top in the level editor), and also to paint them in the main window. (Right click, or CTRL/CMD+click to delete). 67 |

68 | You can also use the number keys 1 to 0 on your keyboard to select tiles. 69 |

70 | If you hover to the borders, a + symbol appears 71 |

72 | 73 |

74 | If you left click it'll add an extra row/column to that side. If you right-click, it'll remove one. 75 |

76 | 77 |

78 | Click the S button to save the output to your console, where you can paste it back in the level section if you want. 79 |

80 | 81 |

82 | If you've messed with the map so that it's not in a state that can be converted faithfully into single-character glyphs, the editor will output the closest approximation it can find. 83 |

84 | Tip: you can press the E key while playing the game in the editor to toggle the level editor. If you press R, it resets to the last time the editor was toggled. 85 |

86 | Also, if you hold CTRL (or, on a Mac, CMD) and left click on the text of a level in the script editor or the console, it will load it in game. 87 |

88 |

89 | 90 | 91 | 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /src/Documentation/permanent_urls.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Updateable PuzzleScript.net URLs - PuzzleScript Documentation 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 23 | 24 | 25 | 26 | 27 | 50 | 51 |
52 | 53 |

54 |

58 |

59 |

Updateable PuzzleScript.net URLs

60 |

61 | If you want to share a link to a puzzle you've made, but still be able to update it (in case there are bugs you want to fix, or new levels you want to add), here's how you do that: 62 |

68 |
69 | 70 | 71 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /src/Documentation/realtime.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Real-time Games - PuzzleScript Documentation 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 23 | 24 | 25 | 26 | 27 | 50 | 51 |
52 | 53 | 54 |

55 |

59 |

60 |

Real-time Games

61 |

62 | 63 | If you want your game to work in real-time, set the realtime_interval tag in the prelude. 64 |

65 |

realtime_interval 0.5
66 |

67 | The number indicates how long each realtime frame should be. In the above case, twice a second the game engine will tick, but with no input. Player input is processed as regular. 68 |

69 | So, there are two sorts of ticks - one where the player has input, and then realtime ones - to tell them apart, you can search for this pattern. 70 |

71 |

(only triggers on real-time ticks)
72 | [ stationary Player ] [ a ] -> [ Player ] [ b ] 
73 | 
74 | (only triggers in response to player input)
75 | [ moving Player ] [ c ] -> [ moving Player ] [ d ] 
76 | 
77 |

78 | Because you're working on a realtime game, you might want to limit the speed at which a player can move - you can do this with the throttle_input prelude switch. 79 |

80 |

throttle_movement
81 |

82 | With this switch, if you press the same direction multiple times in rapid succession, you'll still move no more quickly than key_repeat_interval. You can still alternate directions quickly, and press action as quickly as you like. 83 |

84 |

A small note on the interaction of realtime and again:

85 |

86 | If again is triggered, no realtime ticks will happen until the again stuff has finished. 87 |

88 |

89 | 90 | 91 | 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /src/Documentation/winconditions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Win Conditions - PuzzleScript Documentation 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 23 | 24 | 25 | 26 | 27 | 50 | 51 |
52 | 53 | 54 |

55 |

60 |

61 | 62 | 63 |

Bird's-eye view of a PuzzleScript file

64 |

65 | A puzzlescript file is divided into 8 sections: 66 |

67 | 68 |

78 | 79 | 80 | 81 | 82 |

83 |

WinConditions

84 |

85 | Here are the possible formats of win conditions: 86 |

87 |

 (neko puzzle - you win if there's no fruit left)
 88 | No Fruit
 89 | 
 90 | (sokoban - you win if every target point has a crate on it)
 91 | All Target On Crate 
 92 | 
 93 | (you win if Love exists somewhere)
 94 | Some Love 
 95 | 
 96 | (you win if there's some gold in the chest)
 97 | Some gold on chest 
 98 | 
 99 | (you win if all gold has been taken from the chest)
100 | No gold on chest
101 |

102 | If you have multiple win conditions, they all have to be satisfied. 103 |

104 | These should do for most games, but if you want more advanced control over winning and losing, then you can specify your own win rules using commands. 105 | 106 | 107 | 108 | 109 | 110 |

111 | 112 | 113 | 115 | 116 | 117 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /src/access_token.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """Proxies a request for a GitHub access_token. 4 | 5 | This script handles the server-side part of Github authentication. 6 | PuzzleScript uses it to get an access token after a user gives 7 | PuzzleScript permission to write gists on their behalf. 8 | 9 | To use this script, register a Github OAuth application at 10 | https://github.com/settings/developers and update the OAUTH_CLIENT and 11 | OAUTH_SECRET values below to match. Add any allowed domains to 12 | ORIGIN_LIST (they need to use HTTPS). 13 | 14 | Install python-requests: 15 | $ sudo apt-get install python3-pip 16 | $ sudo pip install requests 17 | 18 | Set it up as a cgi script on your web server. The server needs to 19 | provide the HTTP_ORIGIN header. 20 | """ 21 | 22 | import cgi 23 | import json 24 | import os 25 | import requests 26 | import sys 27 | 28 | OAUTH_CLIENT = "211570277eb588cddf44" 29 | OAUTH_SECRET = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 30 | ORIGIN_LIST = [ 31 | "www.puzzlescript.net", 32 | "www.increpare.com", 33 | "ded.increpare.com", 34 | "increpare.github.io", 35 | "sfiera.github.io", 36 | "www.flickgame.org", 37 | "www.tinychoice.net", 38 | "tinychoice.net", 39 | "www.plingpling.org", 40 | "plingpling.org", 41 | "www.flickgame.org", 42 | "flickgame.org", 43 | ] 44 | 45 | LOGIN_URL = "https://github.com/login/oauth/access_token" 46 | LOGIN_HEADERS = { 47 | "user-agent": "puzzlescript", 48 | "accept": "application/json", 49 | } 50 | 51 | origin = os.environ.get("HTTP_ORIGIN", "") 52 | if not origin.startswith("https://") or (origin[8:] not in ORIGIN_LIST): 53 | print("Content-type: text/plain") 54 | print() 55 | json.dump({"error": "invalid origin"}, sys.stdout) 56 | sys.exit(0) 57 | 58 | form = cgi.FieldStorage() 59 | code = form.getfirst("code", "") 60 | state = form.getfirst("state", "") 61 | 62 | try: 63 | data = requests.get( 64 | LOGIN_URL, 65 | headers=LOGIN_HEADERS, 66 | data={ 67 | "client_id": OAUTH_CLIENT, 68 | "client_secret": OAUTH_SECRET, 69 | "code": code, 70 | "state": state, 71 | }).json() 72 | except Exception as e: 73 | data = {"error": type(e).__name__} 74 | 75 | print("Content-type: application/json") 76 | print("Access-Control-Allow-Origin: " + origin) 77 | print() 78 | json.dump(data, sys.stdout) 79 | -------------------------------------------------------------------------------- /src/auth.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Pattern:Script Login 6 | 7 | 8 | 9 |

10 | 
75 | 
76 | 
77 | 


--------------------------------------------------------------------------------
/src/auth_pat.html:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 | 
 4 | 	
 5 | 	Pattern:Script Login
 6 | 
 7 | 
 8 | 
 9 | 	
10 |

Pattern:Script needs a credential from GitHub to save your game as a Gist on your behalf.

11 |

To create such a credential, please go to your GitHub settings and follow the steps in the GitHub documentation on how to create a personal access token, but make sure to only check gists during the "scope" selection (step 8 as I write this). It may look impressive but it actually takes only a few seconds. If you are already familiar with the process, here is a direct link to the credential creation page on GitHub.

12 |

Now, copy the "personal access token" that you created in the field below and click the button. Then forget the token, you should not keep it anywhere. I will store it in your browser safe storage so that Pattern:Script only can use it. If you use multiple browsers/devices, you will need to redo this step on each. 13 |

14 | 15 | 16 | 17 |
18 |
19 | 23 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /src/commit: -------------------------------------------------------------------------------- 1 | git checkout dev 2 | git add -u 3 | git add . 4 | git commit -a 5 | git push -u origin dev 6 | -------------------------------------------------------------------------------- /src/css/concat: -------------------------------------------------------------------------------- 1 | cat docs.css codemirror.css midnight.css console.css gamecanvas.css soundbar.css layout.css toolbar.css dialog.css show-hint.css >> combined.css 2 | -------------------------------------------------------------------------------- /src/css/console.css: -------------------------------------------------------------------------------- 1 | 2 | #consoletextarea { 3 | font-family: monospace; 4 | color: #428BDD; 5 | background-color:#0F192A; 6 | margin-left:10px; 7 | margin-bottom: 20px; 8 | line-height:1.0; 9 | } 10 | 11 | .errorTextLineNumber { 12 | color: yellow; 13 | text-decoration: underline; 14 | } 15 | .warningText { 16 | color: orange; 17 | } 18 | .errorText { 19 | color: red; 20 | } 21 | .betaText { 22 | color: orange; 23 | } 24 | -------------------------------------------------------------------------------- /src/css/dialog.css: -------------------------------------------------------------------------------- 1 | .CodeMirror-dialog { 2 | position: absolute; 3 | left: 0; right: 0; 4 | background: #203040; 5 | z-index: 15; 6 | padding: .1em .8em; 7 | overflow: hidden; 8 | color: yellow; 9 | } 10 | 11 | .CodeMirror-dialog-top { 12 | border-bottom: 1px solid #eee; 13 | top: 0; 14 | } 15 | 16 | .CodeMirror-dialog-bottom { 17 | border-top: 1px solid #eee; 18 | bottom: 0; 19 | } 20 | 21 | .CodeMirror-dialog input { 22 | border: none; 23 | outline: none; 24 | background: transparent; 25 | width: 20em; 26 | color: inherit; 27 | font-family: monospace; 28 | } 29 | 30 | .CodeMirror-dialog button { 31 | font-size: 70%; 32 | } 33 | -------------------------------------------------------------------------------- /src/css/docs.css: -------------------------------------------------------------------------------- 1 | @font-face 2 | { 3 | font-family: "Source Sans Pro"; 4 | font-style: normal; 5 | font-weight: 400; 6 | src: 7 | local('Source Sans Pro'), 8 | local('SourceSansPro-Regular'), 9 | url("../fonts/SourceSansPro-Regular.woff") format('woff'), 10 | url("../fonts/SourceSansPro-Regular.ttf") format('truetype'); 11 | } 12 | 13 | 14 | @font-face { 15 | font-family: 'Glyphicons Halflings'; 16 | src: url('../fonts/glyphicons-halflings-regular.eot'); 17 | src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons-halflingsregular') format('svg'); 18 | } 19 | 20 | BODY, HTML 21 | { 22 | margin: 0; 23 | padding: 0; 24 | height: 100%; 25 | } 26 | SECTION, ARTICLE 27 | { 28 | display: block; 29 | padding: 0; 30 | } 31 | BODY 32 | { 33 | background: black; 34 | font-family: "Source Sans Pro", Helvetica, Arial, sans-serif; 35 | line-height: 1.5; 36 | } 37 | P 38 | { 39 | margin-top: 0; 40 | } 41 | H2, H3 42 | { 43 | color: #ffffff; 44 | font-weight: normal; 45 | text-decoration: underline; 46 | margin-bottom: 0.7em; 47 | display: inline; 48 | } 49 | FORM 50 | { 51 | display: inline; 52 | } 53 | H2 54 | { 55 | font-size: 120%; 56 | } 57 | H3 58 | { 59 | font-size: 110%; 60 | } 61 | ARTICLE > H2:first-child, SECTION:first-child > H2 62 | { 63 | margin-top: 0; 64 | } 65 | A, A:visited, A:link, .quasilink 66 | { 67 | color: #e06f8b; 68 | } 69 | .quasilink 70 | { 71 | cursor: pointer; 72 | } 73 | ARTICLE 74 | { 75 | margin: 0 auto; 76 | padding: 0px; 77 | border: 0px; 78 | background: #2A363B; 79 | z-index: 2; 80 | position: relative; 81 | min-height: 100%; 82 | box-sizing: border-box; 83 | -moz-box-sizing: border-box; 84 | } 85 | SECTION 86 | { 87 | border-top: 1px solid #E84A5F; 88 | margin: 1.5em 0; 89 | } 90 | SECTION.first 91 | { 92 | border: none; 93 | margin-top: 0; 94 | } 95 | #demo 96 | { 97 | position: relative; 98 | } 99 | #demolist 100 | { 101 | position: absolute; 102 | right: 5px; 103 | top: 5px; 104 | z-index: 25; 105 | } 106 | TH 107 | { 108 | text-decoration: underline; 109 | font-weight: normal; 110 | text-align: left; 111 | } 112 | .rel 113 | { 114 | margin-bottom: 0; 115 | } 116 | .rel-note 117 | { 118 | margin-top: 0; 119 | color: #2A363B; 120 | } 121 | PRE 122 | { 123 | padding-left: 15px; 124 | } 125 | CODE 126 | { 127 | padding: 0 2px; 128 | } 129 | STRONG 130 | { 131 | text-decoration: underline; 132 | font-weight: normal; 133 | } 134 | .field 135 | { 136 | border: 1px solid #E84A5F; 137 | } -------------------------------------------------------------------------------- /src/css/frontpage.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-image: url("../images/background.gif"); 3 | background-size: 1440px 800px; 4 | background-repeat:no-repeat; 5 | } -------------------------------------------------------------------------------- /src/css/gamecanvas.css: -------------------------------------------------------------------------------- 1 | 2 | #gameCanvas { 3 | position:absolute; 4 | top: 0px; 5 | left: 0px; 6 | width: 100%; 7 | height: 100%; 8 | bottom: 0px; 9 | right:0px; 10 | border: 0px; 11 | background-color: black; 12 | -webkit-tap-highlight-color: rgba(0,0,0,0); 13 | image-rendering: -moz-crisp-edges; 14 | image-rendering: -webkit-crisp-edges; 15 | image-rendering: pixelated; 16 | image-rendering: crisp-edges; 17 | touch-action: none; 18 | } 19 | 20 | .tapFocusIndicator { 21 | color: white; 22 | position: absolute; 23 | border: 3px solid gray; 24 | left: 0px; 25 | right: 0px; 26 | top: 0px; 27 | bottom: 0px; 28 | pointer-events: none; 29 | } -------------------------------------------------------------------------------- /src/css/layout.css: -------------------------------------------------------------------------------- 1 | HTML, BODY 2 | { 3 | height: 100%; 4 | width: 100%; 5 | margin: 0; 6 | top: 0px; 7 | left: 0px; 8 | } 9 | #leftpanel 10 | { 11 | position:absolute; 12 | left: 0; 13 | top: 30px; 14 | bottom: 0; 15 | width: 50%; 16 | height: 100%; 17 | float: left; 18 | } 19 | #righttophalf 20 | { 21 | position: absolute; 22 | top: 30px; 23 | right: 0; 24 | bottom: 50%; 25 | left: 50%; 26 | float: right; 27 | } 28 | #rightbottomhalf 29 | { 30 | position: absolute; 31 | top: 50% + 3px; 32 | right: 0; 33 | bottom: 0; 34 | left: 50%; 35 | float: right; 36 | 37 | } 38 | #uppertoolbar 39 | { 40 | position: absolute; 41 | display: block; 42 | left: 2px; 43 | right: 0px; 44 | height: 30px; 45 | top: 0px; 46 | background-color: #444444; 47 | overflow: hidden; 48 | } 49 | .upperarea 50 | { 51 | height: 100%; 52 | width: 100%; 53 | } 54 | .lowertoolbar 55 | { 56 | display: block; 57 | left: 2px; 58 | right: 0px; 59 | height: 20px; 60 | 61 | padding-top:1px; 62 | background-color:#444444; 63 | } 64 | .lowerarea 65 | { 66 | color: #808080; 67 | background-color: #0F192A; 68 | position: absolute; 69 | top: 21px; 70 | bottom: 0px; 71 | left: 0px; 72 | right: 0px; 73 | overflow: auto; 74 | word-wrap: normal; 75 | } 76 | #verticaldragbar { 77 | position: absolute; 78 | top: 30px; 79 | left: 50%; 80 | background-color:#555555; 81 | height: 100%; 82 | float: left; 83 | width: 3px; 84 | cursor: col-resize; 85 | } 86 | #horizontaldragbar { 87 | position: absolute; 88 | background-color:#555555; 89 | top: 50%; 90 | left: 50%; 91 | right: 0; 92 | float: right; 93 | height: 3px; 94 | cursor: row-resize; 95 | } 96 | 97 | .generatedgif { 98 | max-width: 200px; 99 | max-height: 200px; 100 | } 101 | -------------------------------------------------------------------------------- /src/css/show-hint.css: -------------------------------------------------------------------------------- 1 | .CodeMirror-hints { 2 | position: absolute; 3 | z-index: 10; 4 | overflow: hidden; 5 | list-style: none; 6 | 7 | margin: 0; 8 | padding: 2px; 9 | 10 | -webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2); 11 | -moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2); 12 | box-shadow: 2px 3px 5px rgba(0,0,0,.2); 13 | border-radius: 3px; 14 | border: 1px solid silver; 15 | 16 | background: #0F192A; 17 | font-size: 90%; 18 | font-family: monospace; 19 | 20 | max-height: 20em; 21 | overflow-y: auto; 22 | } 23 | 24 | .CodeMirror-hint { 25 | margin: 0; 26 | padding: 0 4px; 27 | border-radius: 2px; 28 | white-space: pre; 29 | color: #FFc540; 30 | cursor: pointer; 31 | } 32 | 33 | li.CodeMirror-hint-active { 34 | background: #3f5883; 35 | color: orange; 36 | } 37 | 38 | 39 | .CodeMirror-hint-active .cm-s-midnight span.cm-COLOR-BLACK { 40 | color: black; 41 | } -------------------------------------------------------------------------------- /src/css/soundbar.css: -------------------------------------------------------------------------------- 1 | .lowertoolbar { 2 | padding:0; 3 | margin:0; 4 | margin-top:0px; 5 | border:0; 6 | white-space: nowrap; 7 | overflow: hidden; 8 | line-height:0; 9 | height: 100%; 10 | width:100%; 11 | line-height:0; 12 | -webkit-touch-callout: none; 13 | -webkit-user-select: none; 14 | -khtml-user-select: none; 15 | -moz-user-select: none; 16 | -ms-user-select: none; 17 | user-select: none; 18 | } 19 | 20 | .lowertoolbar img { 21 | padding:0px; 22 | margin:0px; 23 | } 24 | 25 | 26 | .lowertoolbar #clickMe{ 27 | padding:0px; 28 | margin:0px; 29 | height:16px; 30 | padding-left:2px; 31 | padding-right:3px; 32 | } 33 | 34 | .lowertoolbar a { 35 | margin:0; 36 | padding:0; 37 | } 38 | .lowertoolbar form { 39 | padding:0; 40 | margin:0; 41 | display:inline; 42 | 43 | position:absolute; 44 | top:3px; 45 | right:10px; 46 | } 47 | .lowertoolbar input { 48 | padding:0; 49 | border:0; 50 | height:16px; 51 | } 52 | 53 | #soundbar { 54 | margin-top: 1px; 55 | } 56 | #sounddat{ 57 | padding-top:0px; 58 | margin-top:0px; 59 | width:100px; 60 | } 61 | #soundbutton { 62 | padding-left:10px; 63 | } 64 | 65 | #soundButtonPress { 66 | /* background-color: #808080; 67 | color:white;*/ 68 | padding-left:3px; 69 | padding-right:3px; 70 | } 71 | #soundbutton {vertical-align:top;} 72 | /* */ 73 | -------------------------------------------------------------------------------- /src/css/toolbar.css: -------------------------------------------------------------------------------- 1 | img { 2 | image-rendering: -moz-crisp-edges; 3 | image-rendering: -webkit-crisp-edges; 4 | image-rendering: pixelated; 5 | image-rendering: crisp-edges; 6 | } 7 | /* 8 | .uppertoolbar { 9 | -webkit-touch-callout: none; 10 | -webkit-user-select: none; 11 | -khtml-user-select: none; 12 | -moz-user-select: none; 13 | -ms-user-select: none; 14 | user-select: none; 15 | cursor:default; 16 | }*/ -------------------------------------------------------------------------------- /src/demo/README: -------------------------------------------------------------------------------- 1 | These demos aren't necessarily under MIT license. Ones that are linked to from the dropdown in the editor as examples can be assumed to be so, but other ones are just private records of games that I liked a lot and want to make sure aren’t lost in the sands of time. 2 | 3 | If you don’t want your game here, and it’s here, just let me know and I’ll remove it. 4 | -------------------------------------------------------------------------------- /src/demo/actiontest.txt: -------------------------------------------------------------------------------- 1 | title Simple Action Example 2 | author increpare 3 | homepage www.puzzlescript.net 4 | 5 | ======== 6 | OBJECTS 7 | ======== 8 | 9 | Background 10 | LIGHTGREEN GREEN 11 | 11111 12 | 01111 13 | 11101 14 | 11111 15 | 10111 16 | 17 | Wall 18 | BROWN DARKBROWN 19 | 00010 20 | 11111 21 | 01000 22 | 11111 23 | 00010 24 | 25 | Player 26 | Black Orange White Blue 27 | .000. 28 | .111. 29 | 22222 30 | .333. 31 | .3.3. 32 | 33 | 34 | Blood 35 | DarkRed red white 36 | .01.0 37 | .1202 38 | 2.0.1 39 | 02.1. 40 | .1.0. 41 | 42 | Sheep O 43 | black white gray 44 | ..11. 45 | 01111 46 | 01112 47 | .212. 48 | .0.0. 49 | 50 | 51 | ======= 52 | LEGEND 53 | ======= 54 | 55 | . = Background 56 | # = Wall 57 | P = Player 58 | 59 | 60 | ======= 61 | SOUNDS 62 | ======= 63 | 64 | Sheep MOVE 76935307 65 | SFx0 52519108 66 | 67 | ================ 68 | COLLISIONLAYERS 69 | ================ 70 | 71 | Background 72 | Blood 73 | Player, Wall, Sheep 74 | 75 | ====== 76 | RULES 77 | ====== 78 | 79 | [ Action Player | Sheep ] -> [ Action Player | > Sheep ] 80 | 81 | [ > Sheep | Sheep ] -> [ blood | > Sheep ] Sfx0 82 | 83 | ============== 84 | WINCONDITIONS 85 | ============== 86 | 87 | ======= 88 | LEVELS 89 | ======= 90 | 91 | ################# 92 | #...............# 93 | #...............# 94 | #......ooo......# 95 | #########ooo....# 96 | #P.o...o..ooo...# 97 | #########oooo...# 98 | #...oooooooo....# 99 | #......oo.......# 100 | #...............# 101 | ################# 102 | 103 | -------------------------------------------------------------------------------- /src/demo/againexample.txt: -------------------------------------------------------------------------------- 1 | title Simple Action Example 2 | author increpare 3 | homepage www.puzzlescript.net 4 | 5 | ======== 6 | OBJECTS 7 | ======== 8 | 9 | Background 10 | LIGHTGREEN GREEN 11 | 11111 12 | 01111 13 | 11101 14 | 11111 15 | 10111 16 | 17 | Wall 18 | BROWN DARKBROWN 19 | 00010 20 | 11111 21 | 01000 22 | 11111 23 | 00010 24 | 25 | Player 26 | Black Orange White Blue 27 | .000. 28 | .111. 29 | 22222 30 | .333. 31 | .3.3. 32 | 33 | 34 | Blood 35 | DarkRed red white 36 | .01.0 37 | .1202 38 | 2.0.1 39 | 02.1. 40 | .1.0. 41 | 42 | Sheep O 43 | black white gray 44 | ..11. 45 | 01111 46 | 01112 47 | .212. 48 | .0.0. 49 | 50 | 51 | ======= 52 | LEGEND 53 | ======= 54 | 55 | . = Background 56 | # = Wall 57 | P = Player 58 | 59 | 60 | ======= 61 | SOUNDS 62 | ======= 63 | 64 | 65 | Sheep Create 76935307 66 | SFx0 52519108 67 | 68 | ================ 69 | COLLISIONLAYERS 70 | ================ 71 | 72 | Background 73 | Blood 74 | Player, Wall, Sheep 75 | 76 | ====== 77 | RULES 78 | ====== 79 | 80 | random [ no Sheep ] -> [ Sheep ] again 81 | 82 | ============== 83 | WINCONDITIONS 84 | ============== 85 | 86 | ======= 87 | LEVELS 88 | ======= 89 | 90 | ################# 91 | #...............# 92 | #...............# 93 | #...............# 94 | #...............# 95 | #.......P.......# 96 | #...............# 97 | #...............# 98 | #...............# 99 | ################# 100 | 101 | -------------------------------------------------------------------------------- /src/demo/blank.txt: -------------------------------------------------------------------------------- 1 | ======== 2 | OBJECTS 3 | ======== 4 | 5 | ======= 6 | LEGEND 7 | ======= 8 | 9 | ======= 10 | SOUNDS 11 | ======= 12 | 13 | ================ 14 | COLLISIONLAYERS 15 | ================ 16 | 17 | ====== 18 | RULES 19 | ====== 20 | 21 | ============== 22 | WINCONDITIONS 23 | ============== 24 | 25 | ======= 26 | LEVELS 27 | ======= 28 | -------------------------------------------------------------------------------- /src/demo/blockfaker.txt: -------------------------------------------------------------------------------- 1 | title Block Faker 2 | author Droqen 3 | homepage www.droqen.com 4 | 5 | require_player_movement 6 | key_repeat_interval 0.12 7 | 8 | background_color white 9 | text_color black 10 | 11 | color_palette c64 12 | ( 13 | A port of first several levels of Droqen's beautiful game: 14 | 15 | https://droqen.itch.io/block-faker 16 | 17 | (his game has secrets that this one does not) 18 | 19 | ) 20 | 21 | ======== 22 | OBJECTS 23 | ======== 24 | 25 | Background 26 | White 27 | 28 | Grille 29 | gray 30 | 0...0 31 | .0.0. 32 | ..0.. 33 | .0.0. 34 | 0...0 35 | 36 | EndPoint 37 | Green 38 | 39 | Player 40 | Black 41 | 00000 42 | 00000 43 | 0.0.0 44 | 00000 45 | 00000 46 | 47 | Wall 48 | Gray 49 | 50 | WallBlock 51 | Black Grey 52 | 01111 53 | 01111 54 | 01111 55 | 01111 56 | 00001 57 | 58 | BlueBlock 59 | Blue 60 | 00000 61 | 00.00 62 | 0.0.0 63 | 00.00 64 | 00000 65 | 66 | GreenBlock 67 | LightGreen 68 | 00000 69 | 00000 70 | 00.00 71 | 00000 72 | 00000 73 | 74 | PinkBlock 75 | Red 76 | 00000 77 | 00.00 78 | 0...0 79 | 00.00 80 | 00000 81 | 82 | PurpleBlock 83 | Purple 84 | 00000 85 | 0...0 86 | 0.0.0 87 | 0...0 88 | 00000 89 | 90 | OrangeBlock 91 | Orange 92 | 00000 93 | 0.0.0 94 | 00000 95 | 0.0.0 96 | 00000 97 | 98 | 99 | ======= 100 | LEGEND 101 | ======= 102 | 103 | Block = PinkBlock or BlueBlock or PurpleBlock or OrangeBlock or GreenBlock 104 | Moveable = Player or Block 105 | PlayerObstacle = Block or Wall or WallBlock 106 | BlockObstacle = Player or Wall or WallBlock or Grille or Block or EndPoint 107 | . = Background 108 | # = Wall 109 | @ = WallBlock 110 | P = Player 111 | B = BlueBlock 112 | G = GreenBLock 113 | K = PinkBlock 114 | R = PurpleBlock 115 | O = OrangeBlock 116 | E = EndPoint 117 | x = Grille 118 | H = Grille and Player 119 | 120 | 121 | ========= 122 | SOUNDS 123 | ========= 124 | 125 | ================ 126 | COLLISIONLAYERS 127 | ================ 128 | 129 | Background 130 | EndPoint 131 | Grille 132 | Player, Wall, WallBlock, PinkBlock, BlueBlock, PurpleBlock, OrangeBlock, GreenBlock 133 | 134 | ====== 135 | RULES 136 | ====== 137 | 138 | [ > Moveable | Moveable ] -> [ > Moveable | > Moveable ] 139 | 140 | [ > Block | Grille ] -> [ Block | Grille ] 141 | 142 | late [ PinkBlock | PinkBlock | PinkBlock ] -> [ | | ] 143 | late [ BlueBlock | BlueBlock | BlueBlock ] -> [ | | ] 144 | late [ PurpleBlock | PurpleBlock | PurpleBlock ] -> [ | | ] 145 | late [ OrangeBlock | OrangeBlock | OrangeBlock ] -> [ | | ] 146 | late [ GreenBlock | GreenBlock | GreenBlock ] -> [ | | ] 147 | 148 | ============== 149 | WINCONDITIONS 150 | ============== 151 | some player on endpoint 152 | ======= 153 | LEVELS 154 | ======= 155 | 156 | ........######## 157 | ################ 158 | ########@@@@@### 159 | ####@@@@@...@### 160 | ###@..OO....@@## 161 | ##@..@@@@@....@# 162 | ##@.@..@@@..E@@# 163 | #@..@.O...@@@@## 164 | ##@...@.P.###### 165 | ####@.@@@@###### 166 | ####@@########## 167 | ########........ 168 | 169 | message congrats: level 2! 170 | 171 | ########## 172 | ####R.R### 173 | #x....#x## 174 | #xO#O.OxE# 175 | #xx##.#xx# 176 | #####R#### 177 | #####P#### 178 | O######### 179 | 180 | message congrats: level 3! 181 | 182 | ......#######... 183 | .....##P.#####.. 184 | ....###....####. 185 | ..#####O...#B..# 186 | ..#####.#.##BB.# 187 | ##EBB..O.O.....# 188 | ..#####.#.#....# 189 | ..######..#G.### 190 | ....####..#.OOx. 191 | .....###.GG.#x.. 192 | ......#######... 193 | 194 | message congrats: level 4! 195 | 196 | ######xx###### 197 | ######GG###### 198 | ##xx#...#xEx## 199 | ##..O...#x..## 200 | ##..#...##O### 201 | #..##.......## 202 | xG....##....Gx 203 | xG....##....Gx 204 | ##.......GG### 205 | ###G##...#xx## 206 | ##x..#...O.x## 207 | ##.P.#...#xx## 208 | ######GG###### 209 | ######xx###### 210 | 211 | message congrats: level 5! 212 | 213 | ......##...... 214 | ....######.... 215 | ..##########.. 216 | ..#.OG..kk.#.. 217 | .##OPO..Gkk##. 218 | .##GOG..GGk##. 219 | ###...##...### 220 | ###...##...### 221 | .##kkG##ROR##. 222 | .##Gkk..OEO##. 223 | ..#.Gk..RO.#.. 224 | ..##########.. 225 | ....######.... 226 | ......##...... 227 | 228 | message now go play the real game 229 | -------------------------------------------------------------------------------- /src/demo/ebony and ivory.txt: -------------------------------------------------------------------------------- 1 | title Ebony & Ivory 2 | author Guilherme Töws 3 | homepage zarat.us 4 | 5 | ======== 6 | OBJECTS 7 | ======== 8 | 9 | Background 10 | Purple 11 | 12 | Gray 13 | GRAY 14 | 15 | White 16 | WHITE 17 | 18 | Black 19 | BLACK 20 | 21 | PlayerRed 22 | Red 23 | ..... 24 | .000. 25 | .000. 26 | .000. 27 | ..... 28 | 29 | PlayerGold 30 | Yellow 31 | ..... 32 | .000. 33 | .000. 34 | .000. 35 | ..... 36 | 37 | 38 | ======= 39 | LEGEND 40 | ======= 41 | 42 | . = White 43 | , = Black 44 | # = Gray 45 | : = PlayerRed and White 46 | ; = PlayerRed and Black 47 | Player = PlayerRed or PlayerGold 48 | 49 | ======= 50 | SOUNDS 51 | ======= 52 | 53 | SFX0 72488907 54 | 55 | ================ 56 | COLLISIONLAYERS 57 | ================ 58 | 59 | Background 60 | Black, White, Gray 61 | Player 62 | 63 | ====== 64 | RULES 65 | ====== 66 | 67 | [ PlayerGold ] -> [ PlayerRed ] 68 | [ > Player White | Black ] -> [ > Player White | > Black ] 69 | [ > Player Black | White ] -> [ > Player Black | > White ] 70 | [ > Black | White ] -> [ White | Black ] SFX0 71 | [ > White | Black ] -> [ Black | White ] SFX0 72 | [ > Player White | Black ] -> [ Player White | Black ] 73 | [ > Player Black | White ] -> [ Player Black | White ] 74 | [ > Player | Gray ] -> [ Player | Gray ] 75 | late [ Player | PlayerRed ] -> [ Player | PlayerGold ] 76 | 77 | ============== 78 | WINCONDITIONs 79 | ============== 80 | 81 | No PlayerRed 82 | 83 | ======= 84 | LEVELS 85 | ======= 86 | 87 | ######## 88 | #..,,,,# 89 | #.:.,.,# 90 | #...,,,# 91 | #.,.,;,# 92 | #....,,# 93 | ######## 94 | -------------------------------------------------------------------------------- /src/demo/leftrightnpcs.txt: -------------------------------------------------------------------------------- 1 | title Simple Block Pushing Game 2 | author increpare 3 | homepage www.puzzlescript.net 4 | 5 | ======== 6 | OBJECTS 7 | ======== 8 | 9 | Background 10 | LIGHTGREEN GREEN 11 | 11111 12 | 01111 13 | 11101 14 | 11111 15 | 10111 16 | 17 | 18 | Wall 19 | BROWN DARKBROWN 20 | 00010 21 | 11111 22 | 01000 23 | 11111 24 | 00010 25 | 26 | Player 27 | Black Orange White Blue 28 | .000. 29 | .111. 30 | 22222 31 | .333. 32 | .3.3. 33 | 34 | LeftPerson 35 | Orange Yellow 36 | ...0. 37 | ..0.. 38 | .0... 39 | ..0.. 40 | ...0. 41 | 42 | 43 | RightPerson 44 | Orange Yellow 45 | .0... 46 | ..0.. 47 | ...0. 48 | ..0.. 49 | .0... 50 | 51 | ======= 52 | LEGEND 53 | ======= 54 | 55 | . = Background 56 | # = Wall 57 | P = Player 58 | { = LeftPerson 59 | } = RightPerson 60 | 61 | ======= 62 | SOUNDS 63 | ======= 64 | 65 | ================ 66 | COLLISIONLAYERS 67 | ================ 68 | 69 | Background 70 | Player, Wall, LeftPerson, RightPerson 71 | 72 | ====== 73 | RULES 74 | ====== 75 | 76 | [ stationary LeftPerson ] -> [ left LeftPerson ] 77 | [ stationary RightPerson ] -> [ right RightPerson ] 78 | 79 | right [ wall |< LeftPerson ] -> [ wall | > RightPerson ] 80 | right [ > RightPerson | Wall ] -> [ < LeftPerson | Wall ] 81 | 82 | ============== 83 | WINCONDITIONS 84 | ============== 85 | 86 | 87 | ======= 88 | LEVELS 89 | ======= 90 | 91 | 92 | ####.. 93 | #.}#.. 94 | #..### 95 | #{P..# 96 | #..}.# 97 | #..### 98 | ####.. 99 | 100 | -------------------------------------------------------------------------------- /src/demo/lovendpieces.txt: -------------------------------------------------------------------------------- 1 | title Love and Pieces 2 | author lexaloffle 3 | homepage www.lexaloffle.com 4 | 5 | ======== 6 | OBJECTS 7 | ======== 8 | 9 | Background 10 | White LightBlue 11 | 00000 12 | 01110 13 | 01110 14 | 01110 15 | 00000 16 | 17 | 18 | Wall 19 | DarkBlue Black DarkGray LightGray White 20 | 23330 21 | 22300 22 | 22100 23 | 21110 24 | 11111 25 | 26 | Player 27 | Yellow Orange Red White LightBrown 28 | 20002 29 | 01130 30 | 01110 31 | 04110 32 | 20002 33 | 34 | GrayBlock 35 | Gray DarkGray Green 36 | 10001 37 | 01210 38 | 02220 39 | 01210 40 | 10001 41 | 42 | LitBlock 43 | Green DarkGray 44 | 00000 45 | 01110 46 | 01110 47 | 01110 48 | 00000 49 | 50 | 51 | ======= 52 | LEGEND 53 | ======= 54 | 55 | . = Background 56 | # = Wall 57 | P = Player 58 | o = GrayBlock 59 | Block = GrayBlock or Player 60 | 61 | ======= 62 | SOUNDS 63 | ======= 64 | 65 | GrayBlock MOVE 36772507 66 | 67 | ================ 68 | COLLISIONLAYERS 69 | ================ 70 | 71 | Background 72 | Player, Wall, GrayBlock, LitBlock 73 | 74 | ====== 75 | RULES 76 | ====== 77 | 78 | [ > Player | Wall ] -> cancel 79 | late [ Player | GrayBlock ] -> [ Player | Player ] 80 | 81 | ============== 82 | WINCONDITIONS 83 | ============== 84 | 85 | No GrayBlock 86 | 87 | ======= 88 | LEVELS 89 | ======= 90 | 91 | 92 | 93 | ############ 94 | #...#......# 95 | #..........# 96 | #.p..o..o..# 97 | #..........# 98 | #..#.......# 99 | #..........# 100 | #......#...# 101 | #..........# 102 | ############ 103 | 104 | ############ 105 | #..........# 106 | #..........# 107 | #....#o....# 108 | #..#.o.#...# 109 | #....#.....# 110 | #....o.....# 111 | #.o......p.# 112 | #..........# 113 | ############ 114 | 115 | ############ 116 | #o...o.....# 117 | #.o...o....# 118 | #..o...o...# 119 | #...o...o..# 120 | #o...o...o.# 121 | #.o...o...o# 122 | #..o...o.p.# 123 | #...o...o..# 124 | ############ 125 | 126 | ############ 127 | #..........# 128 | #..o....o..# 129 | #.p#....#o.# 130 | #..........# 131 | #..........# 132 | #.o#....#o.# 133 | #..o....o..# 134 | #..........# 135 | ############ 136 | 137 | 138 | ############ 139 | #..o.......# 140 | #.....oo...# 141 | #...o......# 142 | #.o#..p..o.# 143 | #....o.....# 144 | #..o....o..# 145 | #o.o...#...# 146 | #...o...o..# 147 | ############ 148 | 149 | ############ 150 | #p.o.......# 151 | #..........# 152 | #.o..o...### 153 | #........### 154 | ###.o......# 155 | ###......o.# 156 | #o.....##..# 157 | #......##.o# 158 | ############ 159 | 160 | 161 | ############ 162 | #........o.# 163 | #..o.##....# 164 | #....o.o...# 165 | #.#......#.# 166 | #.#..p.o.#.# 167 | #..o.......# 168 | #....##....# 169 | #.o......o.# 170 | ############ 171 | 172 | 173 | ############ 174 | ###........# 175 | ##....o.o..# 176 | #....#.#...# 177 | #...o.o.o..# 178 | #....#.#...# 179 | #...o.o....# 180 | ##........## 181 | ###.p....### 182 | ############ 183 | 184 | 185 | ###########o 186 | #....p....## 187 | #....p.....# 188 | #...ppp....# 189 | #ppppppppp.# 190 | #...ppp....# 191 | #..ppppp...# 192 | #.pp...pp..# 193 | #.p.....p..# 194 | ############ 195 | -------------------------------------------------------------------------------- /src/demo/lunar_lockout.txt: -------------------------------------------------------------------------------- 1 | title Lunar Lockout 2 | homepage http://bit.ly/WMmQrq 3 | 4 | ======== 5 | OBJECTS 6 | ======== 7 | 8 | Background 9 | Black 10 | 11 | Square 12 | LightGray Gray 13 | 11111 14 | 10001 15 | 10001 16 | 10001 17 | 11111 18 | 19 | Space 20 | Black 21 | 22 | Target 23 | Red 24 | ..... 25 | .000. 26 | .0.0. 27 | .000. 28 | ..... 29 | 30 | Soldier 31 | DarkBlue LightGray Gray 32 | 11111 33 | 10001 34 | 10201 35 | 10001 36 | 11111 37 | 38 | Captain 39 | Green LightGray Gray 40 | 11111 41 | 10001 42 | 10201 43 | 10001 44 | 11111 45 | 46 | Player 47 | Orange 48 | ..... 49 | ..... 50 | ..0.. 51 | ..... 52 | ..... 53 | 54 | 55 | ======= 56 | LEGEND 57 | ======= 58 | 59 | Pawn = Soldier or Captain 60 | Block = Pawn 61 | 62 | @ = Space 63 | _ = Square 64 | P = Square and Player 65 | * = Square and Target 66 | O = Soldier 67 | $ = Soldier and Target 68 | C = Captain 69 | 70 | ======= 71 | SOUNDS 72 | ======= 73 | 74 | 75 | ================ 76 | COLLISIONLAYERS 77 | ================ 78 | 79 | Background 80 | Space, Square 81 | Target 82 | Pawn, Captain 83 | Player 84 | 85 | ====== 86 | RULES 87 | ====== 88 | 89 | [ > Player | Space ] -> [ Player | Space ] 90 | [ > Player Pawn ] -> [ Player > Pawn ] 91 | [ > Pawn | Block ] -> [ Pawn | Block ] 92 | [ > Pawn | Square ] -> [ Square | > Pawn ] 93 | [ > Pawn | Space ] -> [ Square | Space ] 94 | 95 | ============== 96 | WINCONDITIONS 97 | ============== 98 | 99 | some Captain on Target 100 | 101 | ======= 102 | LEVELS 103 | ======= 104 | 105 | message challenge 4 106 | @@@@@@@ 107 | @O___O@ 108 | @___O_@ 109 | @_P*__@ 110 | @__O__@ 111 | @_C___@ 112 | @@@@@@@ 113 | 114 | message challenge 16 115 | @@@@@@@ 116 | @O_C__@ 117 | @_____@ 118 | @_O*_O@ 119 | @__P__@ 120 | @_O___@ 121 | @@@@@@@ 122 | 123 | message challenge 21 124 | @@@@@@@ 125 | @__C__@ 126 | @__O__@ 127 | @_P$_O@ 128 | @O____@ 129 | @___O_@ 130 | @@@@@@@ 131 | 132 | message challenge 37 133 | @@@@@@@ 134 | @O__OO@ 135 | @_____@ 136 | @_P*__@ 137 | @O__C_@ 138 | @_____@ 139 | @@@@@@@ 140 | 141 | -------------------------------------------------------------------------------- /src/demo/mazetest.txt: -------------------------------------------------------------------------------- 1 | title maze generator 2 | run_rules_on_level_start 3 | again_interval 0 4 | 5 | ======== 6 | OBJECTS 7 | ======== 8 | 9 | Background . 10 | black white 11 | 00000 12 | 01110 13 | 01110 14 | 01110 15 | 00000 16 | 17 | Player P 18 | transparent 19 | 20 | visited 21 | transparent 22 | 23 | filler 24 | transparent 25 | 26 | w_up 27 | white 28 | .000. 29 | .000. 30 | .000. 31 | .000. 32 | ..... 33 | 34 | w_down 35 | white 36 | ..... 37 | .000. 38 | .000. 39 | .000. 40 | .000. 41 | 42 | w_left 43 | white 44 | ..... 45 | 0000. 46 | 0000. 47 | 0000. 48 | ..... 49 | 50 | w_right 51 | white 52 | ..... 53 | .0000 54 | .0000 55 | .0000 56 | ..... 57 | 58 | to_delete 59 | transparent 60 | 61 | temp 62 | transparent 63 | 64 | tempA 65 | transparent 66 | 67 | ======= 68 | LEGEND 69 | ======= 70 | 71 | 72 | ======= 73 | SOUNDS 74 | ======= 75 | 76 | ================ 77 | COLLISIONLAYERS 78 | ================ 79 | 80 | Background 81 | Player 82 | filler 83 | visited 84 | w_up 85 | w_down 86 | w_left 87 | w_right 88 | to_delete 89 | temp 90 | tempA 91 | 92 | ====== 93 | RULES 94 | ====== 95 | 96 | (place player randomly on the first turn only) 97 | random [ no filler ] -> [player visited] 98 | [no filler] -> [filler] 99 | 100 | (propagate path until you can't move any more) 101 | random [ player | no visited ] -> [ visited > to_delete | < to_delete player ] again 102 | 103 | (if you can't extend the current path, continue from some random other neighbouring point) 104 | [player | no visited ] -> [ player tempA | ] 105 | random [player no tempA] [ visited | no visited ] -> [ visited ] [ visited player | ] again 106 | [tempA]->[] 107 | 108 | [ up to_delete ] -> [ w_up ] 109 | [ down to_delete ] -> [ w_down ] 110 | [ left to_delete ] -> [ w_left ] 111 | [ right to_delete ] -> [ w_right ] 112 | 113 | ============== 114 | WINCONDITIONS 115 | ============== 116 | 117 | 118 | ======= 119 | LEVELS 120 | ======= 121 | 122 | ........................................ 123 | ........................................ 124 | ........................................ 125 | ........................................ 126 | ........................................ 127 | ........................................ 128 | ........................................ 129 | ........................................ 130 | ........................................ 131 | ........................................ 132 | ........................................ 133 | ........................................ 134 | ........................................ 135 | ........................................ 136 | ........................................ 137 | ........................................ 138 | ........................................ 139 | ........................................ 140 | ........................................ 141 | ........................................ 142 | ........................................ 143 | ........................................ 144 | ........................................ 145 | ........................................ 146 | ........................................ 147 | ........................................ 148 | ........................................ 149 | ........................................ 150 | ........................................ 151 | ........................................ 152 | 153 | 154 | -------------------------------------------------------------------------------- /src/demo/microban.txt: -------------------------------------------------------------------------------- 1 | title Microban 2 | author David Skinner 3 | homepage www.sneezingtiger.com/sokoban/levels/microbanText.html 4 | 5 | ( 6 | My favourite set of sokoban levels - here're the first ten of the Microban set. 7 | 8 | I tried contacting this guy, but he seems to have vanished from the net. The levels are in lots of places online, so I'm just chancing my arm by including them. BUT BE WARNED. 9 | ) 10 | 11 | ======== 12 | OBJECTS 13 | ======== 14 | 15 | Background 16 | LIGHTGREEN GREEN 17 | 11111 18 | 01111 19 | 11101 20 | 11111 21 | 10111 22 | 23 | 24 | Target 25 | DarkBlue 26 | ..... 27 | .000. 28 | .0.0. 29 | .000. 30 | ..... 31 | 32 | Wall 33 | BROWN DARKBROWN 34 | 00010 35 | 11111 36 | 01000 37 | 11111 38 | 00010 39 | 40 | Player 41 | Black Orange White Blue 42 | .000. 43 | .111. 44 | 22222 45 | .333. 46 | .3.3. 47 | 48 | Crate 49 | Orange Yellow 50 | 00000 51 | 0...0 52 | 0...0 53 | 0...0 54 | 00000 55 | 56 | 57 | ======= 58 | LEGEND 59 | ======= 60 | 61 | . = Background 62 | # = Wall 63 | P = Player 64 | * = Crate 65 | @ = Crate and Target 66 | O = Target 67 | 68 | 69 | ======= 70 | SOUNDS 71 | ======= 72 | 73 | Crate MOVE 36772507 74 | endlevel 83744503 75 | startgame 92244503 76 | 77 | ================ 78 | COLLISIONLAYERS 79 | ================ 80 | 81 | Background 82 | Target 83 | Player, Wall, Crate 84 | 85 | ====== 86 | RULES 87 | ====== 88 | 89 | [ > Player | Crate ] -> [ > Player | > Crate ] 90 | 91 | ============== 92 | WINCONDITIONS 93 | ============== 94 | 95 | All Target on Crate 96 | 97 | ======= 98 | LEVELS 99 | ======= 100 | 101 | message level 1 of 10 102 | 103 | ####.. 104 | #.O#.. 105 | #..### 106 | #@P..# 107 | #..*.# 108 | #..### 109 | ####.. 110 | 111 | message level 2 of 10 112 | 113 | ###### 114 | #....# 115 | #.#P.# 116 | #.*@.# 117 | #.O@.# 118 | #....# 119 | ###### 120 | 121 | message level 3 of 10 122 | 123 | ..####... 124 | ###..#### 125 | #.....*.# 126 | #.#..#*.# 127 | #.O.O#P.# 128 | ######### 129 | 130 | message level 4 of 10 131 | 132 | ######## 133 | #......# 134 | #.O@@*P# 135 | #......# 136 | #####..# 137 | ....#### 138 | 139 | message level 5 of 10 140 | 141 | .####### 142 | .#.....# 143 | .#.O*O.# 144 | ##.*P*.# 145 | #..O*O.# 146 | #......# 147 | ######## 148 | 149 | message level 6 of 10 150 | 151 | ######.##### 152 | #....###...# 153 | #.**.....#P# 154 | #.*.#OOO...# 155 | #...######## 156 | #####....... 157 | 158 | message level 7 of 10 159 | 160 | ####### 161 | #.....# 162 | #.O*O.# 163 | #.*O*.# 164 | #.O*O.# 165 | #.*O*.# 166 | #..P..# 167 | ####### 168 | 169 | message level 8 of 10 170 | 171 | ..###### 172 | ..#.OOP# 173 | ..#.**.# 174 | ..##.### 175 | ...#.#.. 176 | ...#.#.. 177 | ####.#.. 178 | #....##. 179 | #.#...#. 180 | #...#.#. 181 | ###...#. 182 | ..#####. 183 | 184 | message level 9 of 10 185 | 186 | #####. 187 | #O..## 188 | #P**.# 189 | ##...# 190 | .##..# 191 | ..##O# 192 | ...### 193 | 194 | message level 10 of 10 195 | 196 | ......##### 197 | ......#O..# 198 | ......#O#.# 199 | #######O#.# 200 | #.P.*.*.*.# 201 | #.#.#.#.### 202 | #.......#.. 203 | #########.. 204 | 205 | message congratulations! 206 | -------------------------------------------------------------------------------- /src/demo/modality.txt: -------------------------------------------------------------------------------- 1 | title Modality 2 | author Sean Barrett 3 | homepage www.silverspaceship.com 4 | background_color #603060 5 | noaction 6 | 7 | ======== 8 | OBJECTS 9 | ======== 10 | 11 | White 12 | White 13 | 14 | Black 15 | #202020 16 | 17 | 18 | Grey 19 | #505050 #a0a0a0 20 | 01010 21 | 10101 22 | 01010 23 | 10101 24 | 01010 25 | 26 | 27 | Background 28 | Red 29 | 30 | Target 31 | #3030a0 32 | ..... 33 | .000. 34 | .0.0. 35 | .000. 36 | ..... 37 | 38 | Player 39 | Black Orange #c0c0c0 Blue 40 | .000. 41 | .111. 42 | 22222 43 | .333. 44 | .3.3. 45 | 46 | Crate 47 | Orange Yellow 48 | 00000 49 | 0...0 50 | 0...0 51 | 0...0 52 | 00000 53 | 54 | 55 | ======= 56 | LEGEND 57 | ======= 58 | 59 | . = Black 60 | + = White 61 | g = Grey 62 | p = Player and Black 63 | Q = Player and White 64 | * = Crate and Black 65 | @ = Crate and White 66 | t = Target and Black 67 | U = Target and White 68 | 69 | Nonwhite = Black or Grey 70 | Nonblack = White or Grey 71 | 72 | ======= 73 | SOUNDS 74 | ======= 75 | 76 | ================ 77 | COLLISIONLAYERS 78 | ================ 79 | 80 | Background 81 | White, Black, Grey 82 | Target 83 | Player, Crate 84 | 85 | ====== 86 | RULES 87 | ====== 88 | 89 | [ > Player Nonblack | Crate Nonblack ] -> [ > Player Nonblack | > Crate Nonblack ] 90 | [ > Player Black | Crate Black ] -> [ > Player Black | > Crate Black ] 91 | [ > Player White | Black ] -> CANCEL 92 | [ > Player Black | White ] -> CANCEL 93 | 94 | ============== 95 | WINCONDITIONS 96 | ============== 97 | 98 | All Crate on Target 99 | 100 | ======= 101 | LEVELS 102 | ======= 103 | 104 | 105 | u+... 106 | @+g.p 107 | +++.. 108 | 109 | ++++q 110 | +.*.+ 111 | u++.+ 112 | +g..+ 113 | +++++ 114 | 115 | ...... 116 | .++.+. 117 | .+q++. 118 | ..u.++ 119 | g.*.++ 120 | ++++++ 121 | 122 | ...t....... 123 | ...+....... 124 | .+.+.+...++ 125 | .+.++++..++ 126 | q@g++..++++ 127 | .+.++...+++ 128 | .+.+....+++ 129 | .+......+++ 130 | .++++++++++ 131 | 132 | -------------------------------------------------------------------------------- /src/demo/naughtysprite.txt: -------------------------------------------------------------------------------- 1 | title Spriteaporter 2 | author increpare 3 | homepage www.puzzlescript.net 4 | 5 | ======== 6 | OBJECTS 7 | ======== 8 | 9 | Temp 10 | black 11 | 12 | Background 13 | LIGHTGREEN GREEN 14 | 11111 15 | 01111 16 | 11101 17 | 11111 18 | 10111 19 | 20 | 21 | Target 22 | DarkBlue 23 | ..... 24 | .000. 25 | .0.0. 26 | .000. 27 | ..... 28 | 29 | Wall 30 | BROWN DARKBROWN 31 | 00010 32 | 11111 33 | 01000 34 | 11111 35 | 00010 36 | 37 | Player 38 | Black Orange White Blue 39 | .000. 40 | .111. 41 | 22222 42 | .333. 43 | .3.3. 44 | 45 | Sprite 46 | Pink Blue Red 47 | ..... 48 | .000. 49 | 00100 50 | 01110 51 | .202. 52 | 53 | ======= 54 | LEGEND 55 | ======= 56 | 57 | . = Background 58 | # = Wall 59 | P = Player 60 | O = Sprite 61 | 62 | 63 | ======= 64 | SOUNDS 65 | ======= 66 | 67 | SFX0 67117309 68 | 69 | ================ 70 | COLLISIONLAYERS 71 | ================ 72 | 73 | Temp 74 | Background 75 | Target 76 | Player, Wall, Sprite 77 | 78 | ====== 79 | RULES 80 | ====== 81 | 82 | late [ Sprite | ... | Player ] -> [ Temp | ... | Sprite ] 83 | late [ Temp ] -> [ Player ] 84 | 85 | ============== 86 | WINCONDITIONS 87 | ============== 88 | 89 | ======= 90 | LEVELS 91 | ======= 92 | 93 | ######### 94 | #.......# 95 | #....O..# 96 | #.P.....# 97 | #.......# 98 | #.......# 99 | ######### 100 | -------------------------------------------------------------------------------- /src/demo/nekopuzzle.txt: -------------------------------------------------------------------------------- 1 | title neko puzzle 2 | author lexaloffle 3 | homepage www.lexaloffle.com 4 | 5 | ( 6 | An inadequate but illustrative demake of one of my favourite puzzle games ever, by the extremely amicable Lexaloffle, and with his permission. 7 | 8 | www.lexaloffle.com/neko.htm 9 | 10 | The game proper has a lot of magic and love in it. 11 | ) 12 | 13 | ======== 14 | OBJECTS 15 | ======== 16 | 17 | Background . 18 | DarkBlue 19 | 20 | Fruit F 21 | Red Green LightRed 22 | ..1.. 23 | .000. 24 | 00020 25 | 00000 26 | .000. 27 | 28 | Player P 29 | Gray White 30 | .1.1. 31 | 10101 32 | 11111 33 | .111. 34 | 00.00 35 | 36 | ======= 37 | LEGEND 38 | ======= 39 | 40 | ========= 41 | SOUNDS 42 | ========= 43 | endlevel 97301508 44 | startgame 97301508 45 | endgame 97301508 46 | 47 | ================ 48 | COLLISIONLAYERS 49 | ================ 50 | 51 | Background 52 | Player, Fruit 53 | 54 | ====== 55 | RULES 56 | ====== 57 | 58 | [ > Player | ... | Fruit ] -> [ | ... | Player ] 59 | 60 | 61 | (if you're not sure what this line does, try removing it, and see what happens) 62 | [ > Player ] -> [ Player] 63 | 64 | ============== 65 | WINCONDITIONS 66 | ============== 67 | No fruit 68 | 69 | ======= 70 | LEVELS 71 | ======= 72 | 73 | message level 1 of 10 74 | 75 | ......F. 76 | ........ 77 | F......F 78 | ......FF 79 | ........ 80 | ........ 81 | P....... 82 | 83 | 84 | message level 2 of 10 85 | 86 | ........ 87 | ....P... 88 | ...F.F.. 89 | ........ 90 | ........ 91 | ..F.FF.. 92 | ........ 93 | 94 | message level 3 of 10 95 | 96 | ........ 97 | .FF....F 98 | ........ 99 | ........ 100 | F...P... 101 | ........ 102 | ........ 103 | F.F..... 104 | 105 | message level 4 of 10 106 | 107 | ....F..F 108 | ........ 109 | .......F 110 | F....... 111 | P....... 112 | ........ 113 | F...F... 114 | 115 | message level 5 of 10 116 | 117 | ........ 118 | ....F.P. 119 | F.F..... 120 | ........ 121 | F...F... 122 | ..F.F... 123 | ........ 124 | 125 | message level 6 of 10 126 | 127 | 128 | F.....F. 129 | ........ 130 | ........ 131 | FF..F... 132 | F.....F. 133 | ........ 134 | .P...... 135 | 136 | message level 7 of 10 137 | 138 | 139 | ...FP..F 140 | F.F..... 141 | F......F 142 | ........ 143 | ........ 144 | ..F..... 145 | ........ 146 | 147 | message level 8 of 10 148 | 149 | ..F..P.. 150 | ........ 151 | ........ 152 | .FFF.... 153 | F..F..F. 154 | ........ 155 | ........ 156 | 157 | message level 9 of 10 158 | 159 | ....F..F 160 | ........ 161 | .F..F... 162 | ........ 163 | .F.P..F. 164 | .F...... 165 | ........ 166 | 167 | message level 10 of 10 168 | 169 | ....F.F. 170 | ........ 171 | .F..F..F 172 | ...F..F. 173 | .......F 174 | ...FP... 175 | ........ 176 | 177 | message congratulations! 178 | -------------------------------------------------------------------------------- /src/demo/notsnake.txt: -------------------------------------------------------------------------------- 1 | title Notsnake 2 | author Terry Cavanagh 3 | homepage www.distractionware.com 4 | 5 | color_palette c64 6 | require_player_movement 7 | 8 | ======== 9 | OBJECTS 10 | ======== 11 | 12 | Background 13 | blue 14 | 15 | Player 16 | lightblue 17 | 18 | Trail 19 | purple 20 | 21 | 22 | ======= 23 | LEGEND 24 | ======= 25 | 26 | . = Background 27 | P = Player 28 | O = Trail 29 | 30 | ======= 31 | SOUNDS 32 | ======= 33 | 34 | startgame 50287705 35 | sfx0 660507 36 | sfx1 41058704 37 | endgame 74955903 38 | 39 | ================ 40 | COLLISIONLAYERS 41 | ================ 42 | 43 | Background 44 | Trail 45 | Player 46 | 47 | ====== 48 | RULES 49 | ====== 50 | 51 | [ > Player | No Trail ] -> [ Trail | Player ] sfx0 52 | [ > Player | Trail ] -> [ | Player ] sfx1 53 | 54 | ============== 55 | WINCONDITIONS 56 | ============== 57 | 58 | No Trail 59 | 60 | ======= 61 | LEVELS 62 | ======= 63 | 64 | OOOOOOOO 65 | OOOOOOOO 66 | O..POO.O 67 | OOOOOOOO 68 | OOOOOOOO 69 | -------------------------------------------------------------------------------- /src/demo/octat.txt: -------------------------------------------------------------------------------- 1 | title Octat 2 | author increpare 3 | homepage www.increpare.com 4 | 5 | noundo 6 | require_player_movement 7 | 8 | (A port of a flash game I made. The original's here: 9 | 10 | http://ded.increpare.com/~locus/octat/ 11 | 12 | ) 13 | 14 | ======== 15 | OBJECTS 16 | ======== 17 | 18 | Background 19 | purple 20 | ..... 21 | .000. 22 | .000. 23 | .000. 24 | ..... 25 | 26 | activetile 27 | pink red 28 | 00000 29 | 0...0 30 | 0...0 31 | 0...0 32 | 00000 33 | 34 | Target 35 | RED 36 | 0...0 37 | .0.0. 38 | ..0.. 39 | .0.0. 40 | 0...0 41 | 42 | Player 43 | white 44 | ..... 45 | .000. 46 | .000. 47 | .000. 48 | ..... 49 | 50 | void 0 51 | black 52 | 53 | temp 54 | black 55 | 56 | ======= 57 | LEGEND 58 | ======= 59 | 60 | . = Background 61 | P = Player and activetile 62 | a = activetile 63 | x = Target 64 | y = target and activetile 65 | 66 | ========= 67 | SOUNDS 68 | ========= 69 | 70 | ================ 71 | COLLISIONLAYERS 72 | ================ 73 | 74 | Background 75 | void 76 | activetile 77 | player 78 | temp 79 | Target 80 | 81 | ====== 82 | RULES 83 | ====== 84 | 85 | [ > player | no activetile ] -> cancel 86 | [ > player | ] -> [ | player ] 87 | 88 | [ activetile | player ] -> [ temp | player ] 89 | [ no temp | player ] -> [activetile | player ] 90 | [ temp ] -> [] 91 | 92 | [activetile void ] -> [ void ] 93 | 94 | ============== 95 | WINCONDITIONS 96 | ============== 97 | 98 | some player on target 99 | 100 | ======= 101 | LEVELS 102 | ======= 103 | 104 | message level 1 of 8 105 | 106 | .......... 107 | .......... 108 | .......... 109 | .......... 110 | .......... 111 | .x...ap... 112 | .......... 113 | .......... 114 | .......... 115 | .......... 116 | 117 | message level 2 of 8 118 | 119 | ........... 120 | ........... 121 | ........... 122 | ........... 123 | ........... 124 | ....xpa.... 125 | ........... 126 | ........... 127 | ........... 128 | ........... 129 | 130 | 131 | message level 3 of 8 132 | 133 | 134 | ........... 135 | ........... 136 | ........... 137 | ........... 138 | ..a........ 139 | .axaaap.... 140 | ..a........ 141 | ........... 142 | ........... 143 | ........... 144 | 145 | message level 4 of 8 146 | 147 | 148 | ........... 149 | ........... 150 | ...a....... 151 | ..a.a...... 152 | .a.a.a..... 153 | a.aya.a.ap. 154 | .a.a.a..... 155 | ..a.a...... 156 | ...a....... 157 | ........... 158 | 159 | message level 5 of 8 160 | 161 | 162 | ........... 163 | ........... 164 | ........... 165 | ........... 166 | aaaaaaaaaaa 167 | ...y..ap... 168 | aaaaaaaaaaa 169 | ........... 170 | ........... 171 | ........... 172 | 173 | message level 6 of 8 174 | 175 | 176 | 000000....0 177 | 000000..0.0 178 | 000000..0.. 179 | 000000000.. 180 | ....A...0.0 181 | .AY.A...AAP 182 | ....A...0.0 183 | 000000000.. 184 | 000000..0.. 185 | 000000..0.0 186 | 000000....0 187 | 188 | message level 7 of 8 189 | 190 | 191 | ..AAA...000 192 | .AY.A...AP. 193 | ..AAA...000 194 | 195 | message level 8 of 8 196 | 197 | 198 | 0AAAA..00 199 | 0AAAA..00 200 | YAAAA..AP 201 | 0AAAA..00 202 | 0AAAA..00 203 | 204 | message the end 205 | 206 | 207 | -------------------------------------------------------------------------------- /src/demo/randomrobots.txt: -------------------------------------------------------------------------------- 1 | title Random Robots 2 | author increpare 3 | homepage www.puzzlescript.net 4 | 5 | ======== 6 | OBJECTS 7 | ======== 8 | 9 | 10 | Background (special, automatically placed in its own layer) 11 | GREEN darkgreen 12 | 11111 13 | 01111 14 | 11101 15 | 11111 16 | 10111 17 | 18 | 19 | Player (Required by game) 20 | PINK 21 | ..0.. 22 | 00000 23 | ..0.. 24 | .000. 25 | .0.0. 26 | 27 | 28 | Robot 29 | gray black red 30 | .000. 31 | .200. 32 | ...0. 33 | 00000 34 | 01010 35 | 36 | 37 | ======= 38 | LEGEND 39 | ======= 40 | 41 | . = Background 42 | P = Player 43 | * = Robot 44 | 45 | ========= 46 | SOUNDS 47 | ========= 48 | 49 | ================ 50 | COLLISIONLAYERS 51 | ================ 52 | 53 | Background 54 | Player, Robot 55 | 56 | ====== 57 | RULES 58 | ====== 59 | 60 | [ stationary Robot ] -> [randomDir Robot] 61 | 62 | ============== 63 | WINCONDITIONS 64 | ============== 65 | 66 | ======= 67 | LEVELS 68 | ======= 69 | 70 | ........... 71 | .....*..... 72 | ........... 73 | .....*..... 74 | ........... 75 | .....*..... 76 | ..P........ 77 | .....*..... 78 | ........... 79 | -------------------------------------------------------------------------------- /src/demo/randomspawner.txt: -------------------------------------------------------------------------------- 1 | title Robot Spawner 2 | author increpare 3 | homepage www.puzzlescript.net 4 | 5 | ======== 6 | OBJECTS 7 | ======== 8 | 9 | 10 | Background (special, automatically placed in its own layer) 11 | GREEN darkgreen 12 | 11111 13 | 01111 14 | 11101 15 | 11111 16 | 10111 17 | 18 | Spawner (Name) 19 | YELLOW (Color) 20 | ..... (Sprite) 21 | ..0.. 22 | .000. 23 | ..0.. 24 | ..... 25 | 26 | Player (Required by game) 27 | PINK 28 | ..0.. 29 | 00000 30 | ..0.. 31 | .000. 32 | .0.0. 33 | 34 | RedRobot 35 | gray black red 36 | .000. 37 | .200. 38 | ...0. 39 | 00000 40 | 01010 41 | 42 | GreenRobot 43 | gray black lightgreen 44 | .000. 45 | .200. 46 | ...0. 47 | 00000 48 | 01010 49 | 50 | BlueRobot 51 | gray black lightblue 52 | .000. 53 | .200. 54 | ...0. 55 | 00000 56 | 01010 57 | 58 | ======= 59 | LEGEND 60 | ======= 61 | 62 | Robot = redRobot or greenRobot or blueRobot 63 | Obstacle = Player or Robot 64 | . = Background 65 | P = Player 66 | * = Robot 67 | O = Spawner 68 | 69 | ========= 70 | SOUNDS 71 | ========= 72 | 73 | ================ 74 | COLLISIONLAYERS 75 | ================ 76 | 77 | Background 78 | Spawner 79 | Player, Robot 80 | 81 | ====== 82 | RULES 83 | ====== 84 | 85 | [ stationary Robot ] -> [randomDir Robot] 86 | [ Spawner no Obstacle ] -> [ Spawner random Robot ] 87 | 88 | ============== 89 | WINCONDITIONS 90 | ============== 91 | 92 | ======= 93 | LEVELS 94 | ======= 95 | 96 | ....... 97 | ....... 98 | ....... 99 | ...O... 100 | ....... 101 | .P..... 102 | ....... 103 | -------------------------------------------------------------------------------- /src/demo/rigid_and_little.txt: -------------------------------------------------------------------------------- 1 | title One rigid body and wee crates 2 | author increpare 3 | homepage www.puzzlescript.net 4 | 5 | ======== 6 | OBJECTS 7 | ======== 8 | 9 | Background 10 | LIGHTGREEN GREEN 11 | 11111 12 | 01111 13 | 11101 14 | 11111 15 | 10111 16 | 17 | 18 | Target 19 | DarkBlue 20 | ..... 21 | .000. 22 | .0.0. 23 | .000. 24 | ..... 25 | 26 | Wall 27 | BROWN DARKBROWN 28 | 00010 29 | 11111 30 | 01000 31 | 11111 32 | 00010 33 | 34 | Player 35 | Black Orange White Blue 36 | .000. 37 | .111. 38 | 22222 39 | .333. 40 | .3.3. 41 | 42 | BigBlock 43 | Orange 44 | 00000 45 | 0...0 46 | 0...0 47 | 0...0 48 | 00000 49 | 50 | LittleBlock 51 | Orange 52 | ..... 53 | .000. 54 | .0.0. 55 | .000. 56 | ..... 57 | 58 | 59 | ======= 60 | LEGEND 61 | ======= 62 | 63 | . = Background 64 | # = Wall 65 | P = Player 66 | * = BigBlock 67 | @ = BigBlock and Target 68 | b = LittleBlock 69 | O = Target 70 | 71 | ========= 72 | SOUNDS 73 | ========= 74 | 75 | ================ 76 | COLLISIONLAYERS 77 | ================ 78 | 79 | Background 80 | Target 81 | Player, Wall, BigBlock, LittleBlock 82 | 83 | ====== 84 | RULES 85 | ====== 86 | 87 | [ > Player | LittleBlock ] -> [ > Player | > LittleBlock ] 88 | 89 | [ > LittleBlock | LittleBlock ] -> [ > LittleBlock | > LittleBlock ] 90 | 91 | rigid [ > LittleBlock | BigBlock ] -> [ > LittleBlock | > BigBlock ] 92 | + rigid [ > Player | BigBlock ] -> [ > Player | > BigBlock ] 93 | + rigid [ moving BigBlock | BigBlock ] -> [ moving BigBlock | moving BigBlock ] 94 | + [ > BigBlock | LittleBlock ] -> [ > BigBlock | > LittleBlock ] 95 | + [ > LittleBlock | LittleBlock ] -> [ > LittleBlock | > LittleBlock ] 96 | 97 | 98 | ============== 99 | WINCONDITIONS 100 | ============== 101 | 102 | ======= 103 | LEVELS 104 | ======= 105 | 106 | ............... 107 | ..........#.... 108 | ............... 109 | ..#***bb....... 110 | ..p*........... 111 | ...**......#... 112 | ..b*...#....... 113 | ............... 114 | ............... 115 | ..#......b..... 116 | .........#..... 117 | ............... 118 | ............... 119 | 120 | -------------------------------------------------------------------------------- /src/demo/rigid_one_object.txt: -------------------------------------------------------------------------------- 1 | title A single rigid body 2 | author increpare 3 | homepage www.puzzlescript.net 4 | 5 | ======== 6 | OBJECTS 7 | ======== 8 | 9 | Background 10 | brown 11 | 12 | Target 13 | YELLOW 14 | 15 | Player 16 | PINK 17 | 18 | BigBlock 19 | darkblue 20 | 21 | Wall 22 | darkbrown 23 | 24 | ======= 25 | LEGEND 26 | ======= 27 | 28 | . = Background 29 | # = Wall 30 | P = Player 31 | * = BigBlock 32 | @ = BigBlock and Target 33 | O = Target 34 | 35 | ========= 36 | SOUNDS 37 | ========= 38 | 39 | ================ 40 | COLLISIONLAYERS 41 | ================ 42 | 43 | Background 44 | Target 45 | Player, Wall, BigBlock 46 | 47 | ====== 48 | RULES 49 | ====== 50 | 51 | rigid [ > Player | BigBlock ] -> [ > Player | > BigBlock ] 52 | + rigid [ moving BigBlock | BigBlock ] -> [ moving BigBlock | moving BigBlock ] 53 | 54 | ============== 55 | WINCONDITIONS 56 | ============== 57 | 58 | ======= 59 | LEVELS 60 | ======= 61 | 62 | ............... 63 | ..........#.... 64 | ............... 65 | ..#............ 66 | .....***....... 67 | .....*.....#... 68 | ..P..**#....... 69 | .....*......... 70 | ............... 71 | ..#............ 72 | .........#..... 73 | ............... 74 | ............... 75 | 76 | -------------------------------------------------------------------------------- /src/demo/rigid_scott1.txt: -------------------------------------------------------------------------------- 1 | title Iterated Extended Rigid Body Test 2 | author Scott Hughes 3 | 4 | ( 5 | usable in the case where there's only a single player that's pushing stuff around. 6 | ) 7 | 8 | ======= 9 | OBJECTS 10 | ======= 11 | 12 | Background 13 | white 14 | 15 | Player 16 | pink 17 | 18 | Box1 19 | red 20 | 21 | Box2 22 | green 23 | 24 | Box3 25 | blue 26 | 27 | Box4 28 | orange 29 | 30 | Wall 31 | grey 32 | 33 | ====== 34 | LEGEND 35 | ====== 36 | 37 | . = Background 38 | @ = Player 39 | 1 = Box1 40 | 2 = Box2 41 | 3 = Box3 42 | 4 = Box4 43 | # = Wall 44 | 45 | Box = Box1 or Box2 or Box3 or Box4 46 | 47 | ====== 48 | SOUNDS 49 | ====== 50 | 51 | =============== 52 | COLLISIONLAYERS 53 | =============== 54 | 55 | Background 56 | Player, Box, Wall 57 | 58 | ===== 59 | RULES 60 | ===== 61 | 62 | [ > Player | Box ] -> [ > Player | > Box ] 63 | 64 | startloop 65 | 66 | [ moving Box1 | Box1 ] -> [ moving Box1 | moving Box1 ] 67 | [ moving Box2 | Box2 ] -> [ moving Box2 | moving Box2 ] 68 | [ moving Box3 | Box3 ] -> [ moving Box3 | moving Box3 ] 69 | [ moving Box4 | Box4 ] -> [ moving Box4 | moving Box4 ] 70 | 71 | [ > Box | Box ] -> [ > Box | > Box ] 72 | 73 | endloop 74 | 75 | [ > Box | Wall ] -> cancel 76 | 77 | ============= 78 | WINCONDITIONS 79 | ============= 80 | 81 | ====== 82 | LEVELS 83 | ====== 84 | 85 | ################ 86 | #....###.......# 87 | #....#.....##..# 88 | #...........#..# 89 | #...@..222..#..# 90 | ##.....2.......# 91 | #...3.....1....# 92 | #..33.....1....# 93 | #..3.....11....# 94 | #....4........## 95 | #...444...##...# 96 | #..#.....##....# 97 | ################ 98 | -------------------------------------------------------------------------------- /src/demo/rigidfail1.txt: -------------------------------------------------------------------------------- 1 | title Naive bodies 2 | author increpare 3 | homepage www.puzzlescript.net 4 | 5 | (naive implementation of rigid bodies) 6 | 7 | ======== 8 | OBJECTS 9 | ======== 10 | 11 | Background 12 | LIGHTGREEN GREEN 13 | 11111 14 | 01111 15 | 11101 16 | 11111 17 | 10111 18 | 19 | 20 | Target 21 | DarkBlue 22 | ..... 23 | .000. 24 | .0.0. 25 | .000. 26 | ..... 27 | 28 | Wall 29 | BROWN DARKBROWN 30 | 00010 31 | 11111 32 | 01000 33 | 11111 34 | 00010 35 | 36 | Player 37 | Black Orange White Blue 38 | .000. 39 | .111. 40 | 22222 41 | .333. 42 | .3.3. 43 | 44 | BigBlock 45 | Orange Yellow 46 | 00000 47 | 0...0 48 | 0...0 49 | 0...0 50 | 00000 51 | 52 | 53 | ======= 54 | LEGEND 55 | ======= 56 | 57 | . = Background 58 | # = Wall 59 | P = Player 60 | * = BigBlock 61 | @ = BigBlock and Target 62 | O = Target 63 | 64 | 65 | ======= 66 | SOUNDS 67 | ======= 68 | 69 | BigBlock MOVE 36772507 70 | 71 | ================ 72 | COLLISIONLAYERS 73 | ================ 74 | 75 | Background 76 | Target 77 | Player, Wall, BigBlock 78 | 79 | ====== 80 | RULES 81 | ====== 82 | 83 | [ > Player | BigBlock ] -> [ > Player | > BigBlock ] 84 | [ moving BigBlock | BigBlock ] -> [moving BigBlock|moving BigBlock] 85 | ============== 86 | WINCONDITIONS 87 | ============== 88 | 89 | ======= 90 | LEVELS 91 | ======= 92 | 93 | .#######. 94 | #.......# 95 | #..***..# 96 | #..p*...# 97 | #.......# 98 | .#######. 99 | -------------------------------------------------------------------------------- /src/demo/riverpuzzle.txt: -------------------------------------------------------------------------------- 1 | title Cliched River Puzzle 2 | author Weeble 3 | homepage www.puzzlescript.net 4 | 5 | ======== 6 | OBJECTS 7 | ======== 8 | 9 | Grass 10 | #559922 GREEN 11 | 11111 12 | 01111 13 | 11101 14 | 11111 15 | 10111 16 | 17 | 18 | Player 19 | Yellow 20 | 00.00 21 | 0...0 22 | ..... 23 | 0...0 24 | 00.00 25 | 26 | Water1 27 | #3333ff #5555ff #7777ff 28 | 00121 29 | 10100 30 | 12001 31 | 10010 32 | 01000 33 | 34 | Water2 35 | #3333ff #5555ff #7777ff 36 | 10000 37 | 00010 38 | 00121 39 | 01100 40 | 10001 41 | 42 | Carrot 43 | ORANGE #55cc00 44 | 11111 45 | .000. 46 | .000. 47 | .000. 48 | ..0.. 49 | 50 | Fox 51 | ORANGE WHITE BLACK 52 | .2.2. 53 | 00000 54 | 12021 55 | .111. 56 | ..2.. 57 | 58 | Rabbit 59 | WHITE #ff88bb 60 | 00.00 61 | .0.0. 62 | .000. 63 | .101. 64 | .000. 65 | 66 | EmptyBoat 67 | BROWN DARKBROWN 68 | .000. 69 | 01110 70 | 01110 71 | 01110 72 | 00000 73 | 74 | Platform 75 | GREY 76 | ..... 77 | ..... 78 | ..... 79 | ..... 80 | ..... 81 | 82 | LeftB 83 | BLUE 84 | ..... 85 | ..... 86 | ..... 87 | ..... 88 | ..... 89 | 90 | RightB 91 | RED 92 | ..... 93 | ..... 94 | ..... 95 | ..... 96 | ..... 97 | 98 | Dude 99 | BLACK 100 | ..0.. 101 | 00000 102 | ..0.. 103 | .0.0. 104 | 0...0 105 | 106 | Dock 107 | YELLOW 108 | ..... 109 | ..... 110 | ..... 111 | ..... 112 | ..... 113 | 114 | ======= 115 | LEGEND 116 | ======= 117 | 118 | . = Grass and LeftB 119 | , = Grass and RightB 120 | ~ = Water1 and LeftB 121 | u = Water1 and RightB 122 | P = Player and LeftB 123 | C = Carrot and Platform and LeftB 124 | F = Fox and Platform and LeftB 125 | R = Rabbit and Platform and LeftB 126 | _ = EmptyBoat and LeftB and Water1 127 | * = Platform and RightB 128 | { = Dude and Dock and LeftB 129 | } = Dock and RightB 130 | Water = Water1 or Water2 131 | Background = Grass or Water1 or Water2 132 | Object = Rabbit or Fox or Carrot 133 | Bank = LeftB or RightB 134 | ======= 135 | SOUNDS 136 | ======= 137 | 138 | SFX0 81232704 139 | SFX1 47027309 140 | SFX2 92562507 141 | SFX3 11245308 142 | 143 | ================ 144 | COLLISIONLAYERS 145 | ================ 146 | 147 | Background 148 | EmptyBoat, Platform, Dock 149 | LeftB, RightB 150 | Carrot, Rabbit, Fox, Dude 151 | Player 152 | 153 | ====== 154 | RULES 155 | ====== 156 | 157 | (Loading the boat) 158 | [ action Player Object Platform ] [ EmptyBoat no Object ] -> [ Player Platform ] [ EmptyBoat Object ] sfx2 159 | 160 | (Emptying the boat) 161 | [ action Player Object EmptyBoat LeftB ] [ Platform no Object LeftB ] -> [ Player EmptyBoat LeftB ] [ Platform Object LeftB ] sfx2 162 | [ action Player Object EmptyBoat RightB ] [ Platform no Object RightB ] -> [ Player EmptyBoat RightB ] [ Platform Object RightB ] sfx2 163 | 164 | ( Eating rules for stuff on the left bank ) 165 | late [ RightB Dude ] [ LeftB Rabbit ] [ LeftB Fox ] -> [ RightB Dude ] [ LeftB ] [ LeftB Fox ] sfx0 message Fox eats rabbit! Chomp! 166 | late [ RightB Dude ] [ LeftB Carrot ] [ LeftB Rabbit ] -> [ RightB Dude ] [ LeftB ] [ LeftB Rabbit ] sfx1 message Rabbit eats carrot! Chomp! 167 | 168 | ( Same rules for stuff on the right bank ) 169 | late [ LeftB Dude ] [ RightB Rabbit ] [ RightB Fox ] -> [ LeftB Dude ] [ RightB ] [ RightB Fox ] sfx0 message Fox eats rabbit! Chomp! 170 | late [ LeftB Dude ] [ RightB Carrot ] [ RightB Rabbit ] -> [ LeftB Dude ] [ RightB ] [ RightB Rabbit ] sfx1 message Rabbit eats carrot! Chomp! 171 | 172 | ( Animate the water ) 173 | [ Water ] -> [ action Water ] (action is considered as a movement) 174 | [ action Water ] -> [ random Water ] (random creates an object stationnary) 175 | 176 | ( Row across the river with an object ) 177 | [ action Player Dude | EmptyBoat Object | ... | | Dock ] -> [ | | ... | EmptyBoat Object | Player Dude Dock ] sfx3 178 | 179 | ( Row across the river without an object ) 180 | [ action Player Dude | EmptyBoat no Object | ... | | Dock ] -> [ | | ... | EmptyBoat | Player Dude Dock ] sfx3 181 | 182 | ( Victory condition ) 183 | [ RightB Platform Rabbit ] [ RightB Platform Fox ] [ RightB Platform Carrot] -> win 184 | 185 | ============== 186 | WINCONDITIONS 187 | ============== 188 | 189 | ======= 190 | LEVELS 191 | ======= 192 | 193 | .....~~~uu,,,,, 194 | .....~~~uu,,,,, 195 | ...F.~~~uu,*,,, 196 | ..RP{_~~uu},*,, 197 | ...C.~~~~u,*,,, 198 | .....~~~uu,,,,, 199 | .....~~~uu,,,,, 200 | 201 | -------------------------------------------------------------------------------- /src/demo/scriptcross.txt: -------------------------------------------------------------------------------- 1 | title ScriptCross 2 | author Dennis Au 3 | homepage www.puzzlescript.net 4 | 5 | ======== 6 | OBJECTS 7 | ======== 8 | 9 | Background 10 | White 11 | 12 | Target 13 | Black 14 | 15 | Fill 16 | Black 17 | 18 | Cross 19 | LightGrey 20 | 0...0 21 | .0.0. 22 | ..0.. 23 | .0.0. 24 | 0...0 25 | 26 | 27 | Player 28 | Green 29 | 00000 30 | 0...0 31 | 0...0 32 | 0...0 33 | 00000 34 | 35 | Border # 36 | LightGrey 37 | 38 | (Clues 0-9) 39 | Clue0 0 40 | LightGrey 41 | 42 | Clue1 1 43 | LightGrey Black 44 | 00000 45 | 0...0 46 | 0.1.0 47 | 0...0 48 | 00000 49 | 50 | Clue2 2 51 | LightGrey Black 52 | 00000 53 | 0..10 54 | 0...0 55 | 01..0 56 | 00000 57 | 58 | Clue3 3 59 | LightGrey Black 60 | 00000 61 | 0..10 62 | 0.1.0 63 | 01..0 64 | 00000 65 | 66 | Clue4 4 67 | LightGrey Black 68 | 00000 69 | 01.10 70 | 0...0 71 | 01.10 72 | 00000 73 | 74 | Clue5 5 75 | LightGrey Black 76 | 00000 77 | 01.10 78 | 0.1.0 79 | 01.10 80 | 00000 81 | 82 | Clue6 6 83 | LightGrey Black 84 | 00000 85 | 01.10 86 | 01.10 87 | 01.10 88 | 00000 89 | 90 | Clue7 7 91 | LightGrey Black 92 | 00000 93 | 01110 94 | 0.1.0 95 | 01110 96 | 00000 97 | 98 | Clue8 8 99 | LightGrey Black 100 | 00000 101 | 01110 102 | 0.110 103 | 01110 104 | 00000 105 | 106 | Clue9 9 107 | LightGrey Black 108 | 00000 109 | 01110 110 | 01110 111 | 01110 112 | 00000 113 | 114 | 115 | ======= 116 | LEGEND 117 | ======= 118 | 119 | . = Background 120 | P = Player and Border 121 | b = Target 122 | Clue = Clue0 or Clue1 or Clue2 or Clue3 or Clue4 or Clue5 or Clue6 or Clue7 or Clue8 or Clue9 123 | NoEmpty = Fill or Cross or Clue or Border 124 | 125 | ======= 126 | SOUNDS 127 | ======= 128 | EndLevel 37348103 129 | EndGame 64173909 130 | 131 | ================ 132 | COLLISIONLAYERS 133 | ================ 134 | 135 | (switch order of target and background to see the solutions) 136 | Target 137 | Background 138 | Border, Clue, Fill, Cross 139 | Player 140 | 141 | 142 | ====== 143 | RULES 144 | ====== 145 | 146 | [Action Player no NoEmpty] -> [Player Fill] 147 | [Action Player Fill] -> [Player Cross] 148 | [Action Player Cross] -> [Player] 149 | 150 | 151 | 152 | ============== 153 | WINCONDITIONS 154 | ============== 155 | 156 | All Target on Fill 157 | All Fill on Target 158 | 159 | ======= 160 | LEVELS 161 | ======= 162 | 163 | (P123456789) 164 | 165 | message level 1 - oh so stable 166 | 167 | P12 168 | 1.b 169 | 2bb 170 | 171 | message level 2 - it is what it is 172 | P##1## 173 | ##113# 174 | ##311# 175 | 3.bbb. 176 | 1...b. 177 | 3.bbb. 178 | 1.b... 179 | 3.bbb. 180 | 181 | message level 3 - i see you! 182 | P##1#1# 183 | ###111# 184 | ##..... 185 | 11.b.b. 186 | ##..... 187 | #3.bbb. 188 | ##..... 189 | 190 | message level 4 - that's ace 191 | P#######1#### 192 | #######111### 193 | ######14141## 194 | #####8111118# 195 | ###7.bbbbbbb. 196 | ##11.b.....b. 197 | #131.b.bbb.b. 198 | 1111.b.b.b.b. 199 | #131.b.bbb.b. 200 | 1111.b.b.b.b. 201 | ##11.b.....b. 202 | ###7.bbbbbbb. 203 | ####......... 204 | 205 | message congratulations! 206 | -------------------------------------------------------------------------------- /src/demo/several_rigid_bodies.txt: -------------------------------------------------------------------------------- 1 | title Several Rigid Bodies 2 | author increpare 3 | homepage www.puzzlescript.net 4 | 5 | ======== 6 | OBJECTS 7 | ======== 8 | 9 | Background 10 | darkgreen 11 | 12 | Target 13 | YELLOW 14 | 15 | Player 16 | PINK 17 | 18 | RedCrate q 19 | RED 20 | 21 | GreenCrate w 22 | Green 23 | 24 | BlueCrate e 25 | Blue 26 | 27 | SmallCrate r 28 | Purple 29 | ..... 30 | .000. 31 | .000. 32 | .000. 33 | ..... 34 | 35 | Wall 36 | DARKBROWN 37 | 38 | ======= 39 | LEGEND 40 | ======= 41 | 42 | . = Background 43 | # = Wall 44 | P = Player 45 | bigcrate = redcrate or greencrate or bluecrate 46 | Crate = smallcrate or bigcrate 47 | O = Target 48 | 49 | ========= 50 | SOUNDS 51 | ========= 52 | 53 | ================ 54 | COLLISIONLAYERS 55 | ================ 56 | 57 | Background 58 | Target 59 | Player, Wall, Crate 60 | 61 | ====== 62 | RULES 63 | ====== 64 | 65 | startloop 66 | 67 | [ > Player | Smallcrate ] -> [ > Player | > SmallCrate ] 68 | 69 | [ > Player | RedCrate ] -> [ > Player | > RedCrate ] 70 | + rigid [ moving RedCrate | RedCrate ] -> [ moving RedCrate | moving RedCrate ] 71 | + [ > Crate | RedCrate ] -> [ > Crate | > RedCrate ] 72 | 73 | [ > Player | GreenCrate ] -> [ > Player | > GreenCrate ] 74 | + rigid [ moving GreenCrate | GreenCrate ] -> [ moving GreenCrate | moving GreenCrate ] 75 | + [ > Crate | GreenCrate ] -> [ > Crate | > GreenCrate ] 76 | 77 | 78 | [ > Player | BlueCrate ] -> [ > Player | > BlueCrate ] 79 | + rigid [ moving BlueCrate | BlueCrate ] -> [ moving BlueCrate | moving BlueCrate ] 80 | + [ > Crate | BlueCrate ] -> [ > Crate | > BlueCrate ] 81 | 82 | [ > Crate | SmallCrate ] -> [ > Crate | > SmallCrate ] 83 | 84 | endloop 85 | 86 | ============== 87 | WINCONDITIONS 88 | ============== 89 | 90 | ======= 91 | LEVELS 92 | ======= 93 | 94 | ............... 95 | ............... 96 | ............... 97 | .....#......... 98 | ............... 99 | ...r.r......... 100 | ..P....#....... 101 | ..qq..w.eer.... 102 | ..q.wwweer..... 103 | ..q.#.......... 104 | ............... 105 | ............... 106 | ............... 107 | 108 | -------------------------------------------------------------------------------- /src/demo/sokoban_basic.txt: -------------------------------------------------------------------------------- 1 | title Simple Block Pushing Game 2 | author David Skinner 3 | homepage www.puzzlescript.net 4 | 5 | ======== 6 | OBJECTS 7 | ======== 8 | 9 | Background 10 | LIGHTGREEN GREEN 11 | 11111 12 | 01111 13 | 11101 14 | 11111 15 | 10111 16 | 17 | 18 | Target 19 | DarkBlue 20 | ..... 21 | .000. 22 | .0.0. 23 | .000. 24 | ..... 25 | 26 | Wall 27 | BROWN DARKBROWN 28 | 00010 29 | 11111 30 | 01000 31 | 11111 32 | 00010 33 | 34 | Player 35 | Black Orange White Blue 36 | .000. 37 | .111. 38 | 22222 39 | .333. 40 | .3.3. 41 | 42 | Crate 43 | Orange Yellow 44 | 00000 45 | 0...0 46 | 0...0 47 | 0...0 48 | 00000 49 | 50 | 51 | ======= 52 | LEGEND 53 | ======= 54 | 55 | . = Background 56 | # = Wall 57 | P = Player 58 | * = Crate 59 | @ = Crate and Target 60 | O = Target 61 | 62 | 63 | ======= 64 | SOUNDS 65 | ======= 66 | 67 | Crate MOVE 36772507 68 | 69 | ================ 70 | COLLISIONLAYERS 71 | ================ 72 | 73 | Background 74 | Target 75 | Player, Wall, Crate 76 | 77 | ====== 78 | RULES 79 | ====== 80 | 81 | [ > Player | Crate ] -> [ > Player | > Crate ] 82 | 83 | ============== 84 | WINCONDITIONS 85 | ============== 86 | 87 | All Target on Crate 88 | 89 | ======= 90 | LEVELS 91 | ======= 92 | 93 | 94 | ####.. 95 | #.O#.. 96 | #..### 97 | #@P..# 98 | #..*.# 99 | #..### 100 | ####.. 101 | 102 | 103 | ###### 104 | #....# 105 | #.#P.# 106 | #.*@.# 107 | #.O@.# 108 | #....# 109 | ###### 110 | -------------------------------------------------------------------------------- /src/demo/sokoban_eyeball.txt: -------------------------------------------------------------------------------- 1 | title EYE EYE EYE 2 | author increpare 3 | homepage www.puzzlescript.net 4 | 5 | ======== 6 | OBJECTS 7 | ======== 8 | 9 | Background 10 | LIGHTGREEN GREEN 11 | 11111 12 | 01111 13 | 11101 14 | 11111 15 | 10111 16 | 17 | 18 | Target 19 | DarkBlue 20 | ..... 21 | .000. 22 | .0.0. 23 | .000. 24 | ..... 25 | 26 | Wall 27 | BROWN DARKBROWN 28 | 00010 29 | 11111 30 | 01000 31 | 11111 32 | 00010 33 | 34 | Player 35 | Black Orange White Blue 36 | .000. 37 | .111. 38 | 22222 39 | .333. 40 | .3.3. 41 | 42 | EyeBall 43 | White Blue Red 44 | .000. 45 | 00100 46 | 01110 47 | 20102 48 | .202. 49 | 50 | ======= 51 | LEGEND 52 | ======= 53 | 54 | . = Background 55 | # = Wall 56 | P = Player 57 | O = EyeBall 58 | 59 | 60 | ======= 61 | SOUNDS 62 | ======= 63 | 64 | SFX0 67117309 65 | 66 | ================ 67 | COLLISIONLAYERS 68 | ================ 69 | 70 | Background 71 | Target 72 | Player, Wall, EyeBall 73 | 74 | ====== 75 | RULES 76 | ====== 77 | 78 | [ Eyeball | ... | Player ] -> [ > Eyeball | ... | Player ] SFX0 79 | 80 | ============== 81 | WINCONDITIONS 82 | ============== 83 | 84 | (there's no way to win against a floating eyeball :S ) 85 | 86 | ======= 87 | LEVELS 88 | ======= 89 | 90 | ######### 91 | #.......# 92 | #....O..# 93 | #.P.....# 94 | #.......# 95 | #.......# 96 | ######### 97 | -------------------------------------------------------------------------------- /src/demo/sokoban_horizontal.txt: -------------------------------------------------------------------------------- 1 | title Horizontal Block Pushing Game 2 | author increpare 3 | homepage www.puzzlescript.net 4 | 5 | ======== 6 | OBJECTS 7 | ======== 8 | 9 | Background 10 | LIGHTGREEN GREEN 11 | 11111 12 | 01111 13 | 11101 14 | 11111 15 | 10111 16 | 17 | 18 | Target 19 | DarkBlue 20 | ..... 21 | .000. 22 | .0.0. 23 | .000. 24 | ..... 25 | 26 | Wall 27 | BROWN DARKBROWN 28 | 00010 29 | 11111 30 | 01000 31 | 11111 32 | 00010 33 | 34 | Player 35 | Black Orange White Blue 36 | .000. 37 | .111. 38 | 22222 39 | .333. 40 | .3.3. 41 | 42 | Crate 43 | Blue White 44 | 00000 45 | 00000 46 | 01110 47 | 00000 48 | 00000 49 | 50 | 51 | ======= 52 | LEGEND 53 | ======= 54 | 55 | . = Background 56 | # = Wall 57 | P = Player 58 | * = Crate 59 | @ = Crate and Target 60 | O = Target 61 | 62 | 63 | ======= 64 | SOUNDS 65 | ======= 66 | 67 | Crate MOVE 36772507 68 | 69 | ================ 70 | COLLISIONLAYERS 71 | ================ 72 | 73 | Background 74 | Target 75 | Player, Wall, Crate 76 | 77 | ====== 78 | RULES 79 | ====== 80 | 81 | horizontal [ > Player | Crate ] -> [ > Player | > Crate ] 82 | 83 | ============== 84 | WINCONDITIONS 85 | ============== 86 | 87 | All Target on Crate 88 | 89 | ======= 90 | LEVELS 91 | ======= 92 | 93 | ######### 94 | #.......# 95 | #.....@.# 96 | #.P.*.O.# 97 | #.......# 98 | #.......# 99 | ######### 100 | 101 | .#######. 102 | .#.....#. 103 | .#O##..## 104 | ##.##.*.# 105 | #.*..**.# 106 | #.OOO.#.# 107 | #.P.....# 108 | ######### 109 | -------------------------------------------------------------------------------- /src/demo/sokoban_match3.txt: -------------------------------------------------------------------------------- 1 | title Match 3 Block Push 2 | author increpare 3 | homepage www.puzzlescript.net 4 | 5 | ======== 6 | OBJECTS 7 | ======== 8 | 9 | Background 10 | LIGHTGREEN GREEN 11 | 11111 12 | 01111 13 | 11101 14 | 11111 15 | 10111 16 | 17 | 18 | Target 19 | DarkBlue 20 | ..... 21 | .000. 22 | .0.0. 23 | .000. 24 | ..... 25 | 26 | Wall 27 | BROWN DARKBROWN 28 | 00010 29 | 11111 30 | 01000 31 | 11111 32 | 00010 33 | 34 | Player 35 | Black Orange White Blue 36 | .000. 37 | .111. 38 | 22222 39 | .333. 40 | .3.3. 41 | 42 | Crate 43 | Orange Yellow 44 | 00000 45 | 0...0 46 | 0...0 47 | 0...0 48 | 00000 49 | 50 | 51 | ======= 52 | LEGEND 53 | ======= 54 | 55 | . = Background 56 | # = Wall 57 | P = Player 58 | * = Crate 59 | @ = Crate and Target 60 | O = Target 61 | 62 | 63 | ======= 64 | SOUNDS 65 | ======= 66 | 67 | Crate MOVE 36772507 68 | 69 | ================ 70 | COLLISIONLAYERS 71 | ================ 72 | 73 | Background 74 | Target 75 | Player, Wall, Crate 76 | 77 | ====== 78 | RULES 79 | ====== 80 | 81 | [ > Player | Crate ] -> [ > Player | > Crate ] 82 | 83 | late [ Crate | Crate | Crate ] -> [ | |] 84 | 85 | ============== 86 | WINCONDITIONS 87 | ============== 88 | 89 | All Crate on Target 90 | 91 | ======= 92 | LEVELS 93 | ======= 94 | 95 | ######### 96 | #.......# 97 | #.*.*.@.# 98 | #.P...O.# 99 | #...*.*.# 100 | #.......# 101 | ######### 102 | 103 | .#######. 104 | .#.....#. 105 | .#O##..## 106 | ##.##.*.# 107 | #.*..**.# 108 | #.OOO.#.# 109 | #.P.....# 110 | ######### 111 | -------------------------------------------------------------------------------- /src/demo/sokoban_sticky.txt: -------------------------------------------------------------------------------- 1 | title Sticky Blocks 2 | author increpare 3 | homepage www.puzzlescript.net 4 | 5 | ======== 6 | OBJECTS 7 | ======== 8 | 9 | Background 10 | LIGHTGREEN GREEN 11 | 11111 12 | 01111 13 | 11101 14 | 11111 15 | 10111 16 | 17 | 18 | Target 19 | DarkBlue 20 | ..... 21 | .000. 22 | .0.0. 23 | .000. 24 | ..... 25 | 26 | Wall 27 | BROWN DARKBROWN 28 | 00010 29 | 11111 30 | 01000 31 | 11111 32 | 00010 33 | 34 | Player 35 | Black Orange White Blue 36 | .000. 37 | .111. 38 | 22222 39 | .333. 40 | .3.3. 41 | 42 | Crate 43 | Orange Yellow 44 | 00000 45 | 0...0 46 | 0...0 47 | 0...0 48 | 00000 49 | 50 | 51 | ======= 52 | LEGEND 53 | ======= 54 | 55 | . = Background 56 | # = Wall 57 | P = Player 58 | * = Crate 59 | @ = Crate and Target 60 | O = Target 61 | 62 | 63 | ======= 64 | SOUNDS 65 | ======= 66 | 67 | Crate MOVE 36772507 68 | 69 | ================ 70 | COLLISIONLAYERS 71 | ================ 72 | 73 | Background 74 | Target 75 | Player, Wall, Crate 76 | 77 | ====== 78 | RULES 79 | ====== 80 | 81 | [ < Player | Crate ] -> [ < Player | < Crate ] 82 | 83 | ============== 84 | WINCONDITIONS 85 | ============== 86 | 87 | All Target on Crate 88 | 89 | ======= 90 | LEVELS 91 | ======= 92 | 93 | ######### 94 | #.......# 95 | #.....@.# 96 | #.P.*.O.# 97 | #.......# 98 | #.......# 99 | ######### 100 | 101 | .#######. 102 | .#.....#. 103 | .#O##..## 104 | ##.##.*.# 105 | #.*..**.# 106 | #.OOO.#.# 107 | #.P.....# 108 | ######### 109 | -------------------------------------------------------------------------------- /src/demo/sumo.txt: -------------------------------------------------------------------------------- 1 | title Multiple Patterns 2 | author increpare 3 | homepage www.puzzlescript.net 4 | 5 | ======== 6 | OBJECTS 7 | ======== 8 | 9 | Background 10 | LIGHTGREEN GREEN 11 | 11111 12 | 01111 13 | 11101 14 | 11111 15 | 10111 16 | 17 | 18 | Wall 19 | BROWN DARKBROWN 20 | 00010 21 | 11111 22 | 01000 23 | 11111 24 | 00010 25 | 26 | Player 27 | Black Orange White Blue 28 | .000. 29 | .111. 30 | 22222 31 | .333. 32 | .3.3. 33 | 34 | Sumo 35 | Pink White 36 | ..0.. 37 | 00000 38 | .000. 39 | .111. 40 | .0.0. 41 | 42 | ======= 43 | LEGEND 44 | ======= 45 | 46 | . = Background 47 | # = Wall 48 | P = Player 49 | S = Sumo 50 | 51 | ======= 52 | SOUNDS 53 | ======= 54 | 55 | Sumo MOVE 48878907 56 | 57 | ================ 58 | COLLISIONLAYERS 59 | ================ 60 | 61 | Background 62 | Player, Wall, Sumo 63 | 64 | ====== 65 | RULES 66 | ====== 67 | 68 | [ > Player ] [ Sumo ] -> [ > Player ] [ > Sumo ] 69 | 70 | ============== 71 | WINCONDITIONS 72 | ============== 73 | 74 | ======= 75 | LEVELS 76 | ======= 77 | 78 | ######## 79 | #......# 80 | #......# 81 | #.P..S.# 82 | #......# 83 | #......# 84 | ######## 85 | -------------------------------------------------------------------------------- /src/demo/twolittlecrates1.txt: -------------------------------------------------------------------------------- 1 | title Simple Block Pushing Game 2 | author increpare 3 | homepage www.puzzlescript.net 4 | 5 | ======== 6 | OBJECTS 7 | ======== 8 | 9 | Background 10 | LIGHTGREEN GREEN 11 | 11111 12 | 01111 13 | 11101 14 | 11111 15 | 10111 16 | 17 | 18 | Target 19 | DarkBlue 20 | ..... 21 | .000. 22 | .0.0. 23 | .000. 24 | ..... 25 | 26 | Wall 27 | BROWN DARKBROWN 28 | 00010 29 | 11111 30 | 01000 31 | 11111 32 | 00010 33 | 34 | Player 35 | Black Orange White Blue 36 | .000. 37 | .111. 38 | 22222 39 | .333. 40 | .3.3. 41 | 42 | BlueCrate B 43 | lightblue 44 | 00000 45 | 0...0 46 | 0...0 47 | 0...0 48 | 00000 49 | 50 | 51 | OrangeCrate O 52 | Orange 53 | 00000 54 | 0...0 55 | 0...0 56 | 0...0 57 | 00000 58 | 59 | 60 | ======= 61 | LEGEND 62 | ======= 63 | 64 | Crate = OrangeCrate or BlueCrate 65 | . = Background 66 | # = Wall 67 | P = Player 68 | 69 | 70 | ======= 71 | SOUNDS 72 | ======= 73 | 74 | Crate MOVE 36772507 75 | 76 | ================ 77 | COLLISIONLAYERS 78 | ================ 79 | 80 | Background 81 | Target 82 | Player, Wall, Crate 83 | 84 | ====== 85 | RULES 86 | ====== 87 | 88 | [ > Player | Crate ] -> [ > Player | > Crate ] 89 | 90 | [ > Crate | Crate ] -> [ > Crate | > Crate ] 91 | 92 | ============== 93 | WINCONDITIONS 94 | ============== 95 | 96 | ======= 97 | LEVELS 98 | ======= 99 | 100 | ######### 101 | #.......# 102 | #...B...# 103 | #.P.B.O.# 104 | #....O..# 105 | #.......# 106 | ######### 107 | 108 | -------------------------------------------------------------------------------- /src/demo/twolittlecrates2.txt: -------------------------------------------------------------------------------- 1 | title Simple Block Pushing Game 2 | author increpare 3 | homepage www.puzzlescript.net 4 | 5 | ======== 6 | OBJECTS 7 | ======== 8 | 9 | Background 10 | LIGHTGREEN GREEN 11 | 11111 12 | 01111 13 | 11101 14 | 11111 15 | 10111 16 | 17 | 18 | Target 19 | DarkBlue 20 | ..... 21 | .000. 22 | .0.0. 23 | .000. 24 | ..... 25 | 26 | Wall 27 | BROWN DARKBROWN 28 | 00010 29 | 11111 30 | 01000 31 | 11111 32 | 00010 33 | 34 | Player 35 | Black Orange White Blue 36 | .000. 37 | .111. 38 | 22222 39 | .333. 40 | .3.3. 41 | 42 | BlueCrate B 43 | lightblue 44 | 00000 45 | 0...0 46 | 0...0 47 | 0...0 48 | 00000 49 | 50 | 51 | OrangeCrate O 52 | Orange 53 | 00000 54 | 0...0 55 | 0...0 56 | 0...0 57 | 00000 58 | 59 | 60 | ======= 61 | LEGEND 62 | ======= 63 | 64 | Crate = OrangeCrate or BlueCrate 65 | . = Background 66 | # = Wall 67 | P = Player 68 | 69 | 70 | ======= 71 | SOUNDS 72 | ======= 73 | 74 | Crate MOVE 36772507 75 | 76 | ================ 77 | COLLISIONLAYERS 78 | ================ 79 | 80 | Background 81 | Target 82 | Player, Wall, Crate 83 | 84 | ====== 85 | RULES 86 | ====== 87 | 88 | [ > Player | Crate ] -> [ > Player | > Crate ] 89 | 90 | 91 | [ > OrangeCrate | OrangeCrate ] -> [ > OrangeCrate | > OrangeCrate ] 92 | [ > OrangeCrate | BlueCrate ] -> [ > OrangeCrate | > BlueCrate ] 93 | [ > BlueCrate | OrangeCrate ] -> [ > BlueCrate | > OrangeCrate ] 94 | [ > BlueCrate | BlueCrate ] -> [ > BlueCrate | > BlueCrate ] 95 | 96 | ============== 97 | WINCONDITIONS 98 | ============== 99 | 100 | ======= 101 | LEVELS 102 | ======= 103 | 104 | ################ 105 | #..............# 106 | #..............# 107 | #.P.BOBOBOBOB..# 108 | #..............# 109 | #..............# 110 | ################ 111 | 112 | -------------------------------------------------------------------------------- /src/demo/twolittlecrates3.txt: -------------------------------------------------------------------------------- 1 | title Simple Block Pushing Game 2 | author increpare 3 | homepage www.puzzlescript.net 4 | 5 | ======== 6 | OBJECTS 7 | ======== 8 | 9 | Background 10 | LIGHTGREEN GREEN 11 | 11111 12 | 01111 13 | 11101 14 | 11111 15 | 10111 16 | 17 | 18 | Target 19 | DarkBlue 20 | ..... 21 | .000. 22 | .0.0. 23 | .000. 24 | ..... 25 | 26 | Wall 27 | BROWN DARKBROWN 28 | 00010 29 | 11111 30 | 01000 31 | 11111 32 | 00010 33 | 34 | Player 35 | Black Orange White Blue 36 | .000. 37 | .111. 38 | 22222 39 | .333. 40 | .3.3. 41 | 42 | BlueCrate B 43 | lightblue 44 | 00000 45 | 0...0 46 | 0...0 47 | 0...0 48 | 00000 49 | 50 | 51 | OrangeCrate O 52 | Orange 53 | 00000 54 | 0...0 55 | 0...0 56 | 0...0 57 | 00000 58 | 59 | 60 | ======= 61 | LEGEND 62 | ======= 63 | 64 | Crate = OrangeCrate or BlueCrate 65 | . = Background 66 | # = Wall 67 | P = Player 68 | 69 | ======= 70 | SOUNDS 71 | ======= 72 | 73 | Crate MOVE 36772507 74 | 75 | ================ 76 | COLLISIONLAYERS 77 | ================ 78 | 79 | Background 80 | Target 81 | Player, Wall, Crate 82 | 83 | ====== 84 | RULES 85 | ====== 86 | 87 | [ > Player | Crate ] -> [ > Player | > Crate ] 88 | 89 | startLoop 90 | 91 | [ > OrangeCrate | OrangeCrate ] -> [ > OrangeCrate | > OrangeCrate ] 92 | [ > OrangeCrate | BlueCrate ] -> [ > OrangeCrate | > BlueCrate ] 93 | [ > BlueCrate | OrangeCrate ] -> [ > BlueCrate | > OrangeCrate ] 94 | [ > BlueCrate | BlueCrate ] -> [ > BlueCrate | > BlueCrate ] 95 | 96 | endLoop 97 | 98 | ============== 99 | WINCONDITIONS 100 | ============== 101 | 102 | ======= 103 | LEVELS 104 | ======= 105 | 106 | ################ 107 | #..............# 108 | #..............# 109 | #.P.BOBOBOBOB..# 110 | #..............# 111 | #..............# 112 | ################ 113 | -------------------------------------------------------------------------------- /src/demo/twolittlecrates4.txt: -------------------------------------------------------------------------------- 1 | title Simple Block Pushing Game 2 | author increpare 3 | homepage www.puzzlescript.net 4 | 5 | ======== 6 | OBJECTS 7 | ======== 8 | 9 | Background 10 | LIGHTGREEN GREEN 11 | 11111 12 | 01111 13 | 11101 14 | 11111 15 | 10111 16 | 17 | 18 | Target 19 | DarkBlue 20 | ..... 21 | .000. 22 | .0.0. 23 | .000. 24 | ..... 25 | 26 | Wall 27 | BROWN DARKBROWN 28 | 00010 29 | 11111 30 | 01000 31 | 11111 32 | 00010 33 | 34 | Player 35 | Black Orange White Blue 36 | .000. 37 | .111. 38 | 22222 39 | .333. 40 | .3.3. 41 | 42 | BlueCrate B 43 | lightblue 44 | 00000 45 | 0...0 46 | 0...0 47 | 0...0 48 | 00000 49 | 50 | 51 | OrangeCrate O 52 | Orange 53 | 00000 54 | 0...0 55 | 0...0 56 | 0...0 57 | 00000 58 | 59 | 60 | ======= 61 | LEGEND 62 | ======= 63 | 64 | Crate = OrangeCrate or BlueCrate 65 | . = Background 66 | # = Wall 67 | P = Player 68 | 69 | ======= 70 | SOUNDS 71 | ======= 72 | 73 | Crate MOVE 36772507 74 | 75 | ================ 76 | COLLISIONLAYERS 77 | ================ 78 | 79 | Background 80 | Target 81 | Player, Wall, Crate 82 | 83 | ====== 84 | RULES 85 | ====== 86 | 87 | [ > Player | Crate ] -> [ > Player | > Crate ] 88 | 89 | 90 | [ > OrangeCrate | OrangeCrate ] -> [ > OrangeCrate | > OrangeCrate ] 91 | +[ > OrangeCrate | BlueCrate ] -> [ > OrangeCrate | > BlueCrate ] 92 | +[ > BlueCrate | OrangeCrate ] -> [ > BlueCrate | > OrangeCrate ] 93 | +[ > BlueCrate | BlueCrate ] -> [ > BlueCrate | > BlueCrate ] 94 | 95 | ============== 96 | WINCONDITIONS 97 | ============== 98 | 99 | ======= 100 | LEVELS 101 | ======= 102 | 103 | ################ 104 | #..............# 105 | #..............# 106 | #.P.BOBOBOBOB..# 107 | #..............# 108 | #..............# 109 | ################ 110 | -------------------------------------------------------------------------------- /src/demo/wordgame.txt: -------------------------------------------------------------------------------- 1 | title Multi-word Dictionary Game 2 | author Sarah Northway 3 | homepage www.sarahnorthway.com 4 | 5 | (included with permission of Sarah Northway) 6 | 7 | ======== 8 | OBJECTS 9 | ======== 10 | 11 | Background 12 | pink 13 | 14 | Wall 15 | grey 16 | 17 | Player 18 | Blue 19 | 20 | Won 21 | yellow 22 | 23 | LetterC 24 | white black 25 | .111. 26 | 1.... 27 | 1.... 28 | 1.... 29 | .111. 30 | 31 | LetterA 32 | white black 33 | .111. 34 | 1...1 35 | 11111 36 | 1...1 37 | 1...1 38 | 39 | LetterT 40 | white black 41 | 11111 42 | ..1.. 43 | ..1.. 44 | ..1.. 45 | ..1.. 46 | 47 | ======= 48 | LEGEND 49 | ======= 50 | 51 | Letter = LetterA or LetterC or LetterT 52 | . = Background 53 | # = Wall 54 | P = Player 55 | W = Won 56 | C = LetterC 57 | A = LetterA 58 | T = LetterT 59 | 60 | ======= 61 | SOUNDS 62 | ======= 63 | 64 | ================ 65 | COLLISIONLAYERS 66 | ================ 67 | 68 | Background 69 | Won 70 | Player, Wall, Letter 71 | 72 | ====== 73 | RULES 74 | ====== 75 | 76 | [ > Player | Letter ] -> [ > Player | > Letter ] 77 | [ < Player | Letter ] -> [ < Player | < Letter ] 78 | 79 | late right [LetterC | LetterA | LetterT ] -> [ Won LetterC | Won LetterA | Won LetterT ] message You spelled CAT! 80 | late right [LetterA | LetterC | LetterT] -> [ Won LetterA | Won LetterC | Won LetterT ] message You spelled ACT! 81 | 82 | ============== 83 | WINCONDITIONS 84 | ============== 85 | 86 | Some Won 87 | 88 | ======= 89 | LEVELS 90 | ======= 91 | 92 | ######### 93 | #.......# 94 | #.A..C..# 95 | #.......# 96 | #...P...# 97 | #.T.....# 98 | ######### 99 | -------------------------------------------------------------------------------- /src/demo/wrappingrecipe.txt: -------------------------------------------------------------------------------- 1 | title Wrapping Recipe 2 | author increpare 3 | homepage http://www.puzzlescript.net 4 | 5 | ======== 6 | OBJECTS 7 | ======== 8 | 9 | Wrap 10 | Black 11 | 12 | Background 13 | White 14 | 15 | Player 16 | Blue 17 | 18 | ======= 19 | LEGEND 20 | ======= 21 | 22 | . = Background 23 | ~ = Wrap 24 | @ = Player 25 | 26 | ======= 27 | SOUNDS 28 | ======= 29 | 30 | ================ 31 | COLLISIONLAYERS 32 | ================ 33 | 34 | Background 35 | Wrap 36 | Player 37 | 38 | ====== 39 | RULES 40 | ====== 41 | 42 | [ Wrap | < Player | ... | | Wrap ] -> [ Wrap | | ... | Player | Wrap ] 43 | 44 | ============== 45 | WINCONDITIONS 46 | ============== 47 | 48 | ======= 49 | LEVELS 50 | ======= 51 | 52 | ~~~~~~~ 53 | ~.....~ 54 | ~.....~ 55 | ~..@..~ 56 | ~.....~ 57 | ~.....~ 58 | ~~~~~~~ 59 | -------------------------------------------------------------------------------- /src/demo/zenpuzzlegarden.txt: -------------------------------------------------------------------------------- 1 | title Zen Puzzle Garden 2 | author lexaloffle 3 | homepage www.lexaloffle.com 4 | 5 | ( 6 | 7 | A replication, with some really bad levels, of the rather superior Zen Puzzle Garden. Made with permission of the unfailingly lovely Joseph White. 8 | 9 | http://www.lexaloffle.com/zen.htm 10 | 11 | ) 12 | 13 | ======== 14 | OBJECTS 15 | ======== 16 | 17 | Background 18 | orange brown 19 | 00100 20 | 00000 21 | 00010 22 | 10000 23 | 00000 24 | 25 | Player 26 | white black 27 | .0.0. 28 | 01010 29 | 00000 30 | .000. 31 | 11.11 32 | 33 | Rock 34 | grey darkgrey yellow 35 | 21002 36 | 11000 37 | 11000 38 | 11000 39 | 11101 40 | 41 | 42 | UnbrushedSand 43 | yellow orange 44 | 00000 45 | 01000 46 | 00000 47 | 00010 48 | 00000 49 | 50 | HBrushedSand 51 | yellow orange 52 | 00000 53 | 01011 54 | 00000 55 | 11010 56 | 00000 57 | 58 | VBrushedSand 59 | yellow orange 60 | 01000 61 | 01010 62 | 00000 63 | 01010 64 | 00010 65 | 66 | ======= 67 | LEGEND 68 | ======= 69 | 70 | BrushedSand = HBrushedSand or VBrushedSand 71 | Sand = UnbrushedSand or BrushedSand 72 | Obstacle = BrushedSand or Rock 73 | ; = Background 74 | O = Rock 75 | . = UnbrushedSand 76 | P = Player 77 | 78 | ========= 79 | SOUNDS 80 | ========= 81 | 82 | closemessage 52854909 83 | startgame 64192309 84 | endlevel 16398509 85 | endgame 62100709 86 | 87 | ================ 88 | COLLISIONLAYERS 89 | ================ 90 | 91 | Background 92 | Sand 93 | Player, Rock 94 | 95 | ====== 96 | RULES 97 | ====== 98 | 99 | 100 | (the h and v sand effects are cosmetic - how could this be done in a single line if there was only one type brushed sand? ) 101 | 102 | Horizontal [ UnbrushedSand > Player ] -> [ HBrushedSand > Player ] 103 | Vertical [ UnbrushedSand > Player ] -> [ VBrushedSand > Player ] 104 | 105 | late [ Player BrushedSand ] -> cancel 106 | 107 | ============== 108 | WINCONDITIONS 109 | ============== 110 | no UnbrushedSand 111 | 112 | ======= 113 | LEVELS 114 | ======= 115 | 116 | message level 1 of 5 117 | 118 | ;;;;;;;;;;;; 119 | ;;;;;;;;;;;; 120 | ;;;;;;;;;;;; 121 | ;;;......;;; 122 | ;;;......;;; 123 | ;;;......;;; 124 | ;P;..OO..;;; 125 | ;;;......;;; 126 | ;;;......;;; 127 | ;;;;;;;;;;;; 128 | ;;;;;;;;;;;; 129 | ;;;;;;;;;;;; 130 | 131 | message level 2 of 5 132 | 133 | ;;;;;;;;;;;; 134 | ;;;;;;;;;;;; 135 | ;;;;;;;;;;;; 136 | ;;;......;;; 137 | ;;;....O.;;; 138 | ;;;......;;; 139 | ;P;..O...;;; 140 | ;;;......;;; 141 | ;;;......;;; 142 | ;;;;;;;;;;;; 143 | ;;;;;;;;;;;; 144 | ;;;;;;;;;;;; 145 | 146 | 147 | message level 3 of 5 148 | 149 | ;;;;;;;;;;;; 150 | ;;;;;;;;;;;; 151 | ;;;;;;;;;;;; 152 | ;;;......;;; 153 | ;;;...O..;;; 154 | ;;;......;;; 155 | ;P;.O....;;; 156 | ;;;....O.;;; 157 | ;;;......;;; 158 | ;;;;;;;;;;;; 159 | ;;;;;;;;;;;; 160 | ;;;;;;;;;;;; 161 | 162 | 163 | message level 4 of 5 164 | 165 | ;;;;;;;;;;;; 166 | ;;;;;;;;;;;; 167 | ;;;;;;;;;;;; 168 | ;;;..OO..;;; 169 | ;;;O....O;;; 170 | ;P;..OO..;;; 171 | ;;;O....O;;; 172 | ;;;..OO..;;; 173 | ;;;;;;;;;;;; 174 | ;;;;;;;;;;;; 175 | ;;;;;;;;;;;; 176 | 177 | 178 | message level 5 of 5 179 | 180 | ;;;;;;;;;;;; 181 | ;;;;;;;;;;;; 182 | ;;;;;;;;;;;; 183 | ;;;O.....;;; 184 | ;;;..O.O.;;; 185 | ;;;O...O.;;; 186 | ;P;..O...;;; 187 | ;;;O...O.;;; 188 | ;;;..O...;;; 189 | ;;;;;;;;;;;; 190 | ;;;;;;;;;;;; 191 | ;;;;;;;;;;;; 192 | 193 | message congratulations! 194 | -------------------------------------------------------------------------------- /src/fonts/PuzzleScripTt.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/fonts/PuzzleScripTt.woff -------------------------------------------------------------------------------- /src/fonts/SourceSansPro-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/fonts/SourceSansPro-Regular.ttf -------------------------------------------------------------------------------- /src/fonts/SourceSansPro-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/fonts/SourceSansPro-Regular.woff -------------------------------------------------------------------------------- /src/fonts/font-5x12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/fonts/font-5x12.png -------------------------------------------------------------------------------- /src/images/audio1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/images/audio1.gif -------------------------------------------------------------------------------- /src/images/audio10.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/images/audio10.gif -------------------------------------------------------------------------------- /src/images/audio2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/images/audio2.gif -------------------------------------------------------------------------------- /src/images/audio3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/images/audio3.gif -------------------------------------------------------------------------------- /src/images/audio4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/images/audio4.gif -------------------------------------------------------------------------------- /src/images/audio5.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/images/audio5.gif -------------------------------------------------------------------------------- /src/images/audio6.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/images/audio6.gif -------------------------------------------------------------------------------- /src/images/audio7.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/images/audio7.gif -------------------------------------------------------------------------------- /src/images/audio8.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/images/audio8.gif -------------------------------------------------------------------------------- /src/images/audio9.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/images/audio9.gif -------------------------------------------------------------------------------- /src/images/birdy.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/images/birdy.gif -------------------------------------------------------------------------------- /src/images/clearConsole.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/images/clearConsole.gif -------------------------------------------------------------------------------- /src/images/debugRules.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/images/debugRules.png -------------------------------------------------------------------------------- /src/images/mascot_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/images/mascot_128.png -------------------------------------------------------------------------------- /src/images/mascot_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/images/mascot_256.png -------------------------------------------------------------------------------- /src/images/mascot_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/images/mascot_32.png -------------------------------------------------------------------------------- /src/images/mascot_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/images/mascot_512.png -------------------------------------------------------------------------------- /src/images/mascot_512_colorful.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/images/mascot_512_colorful.png -------------------------------------------------------------------------------- /src/images/mascot_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/images/mascot_64.png -------------------------------------------------------------------------------- /src/images/mascot_colorful.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClementSparrow/Pattern-Script/82e2c7452ba598c3a26b4fde3b70ea30ea05d2bf/src/images/mascot_colorful.png -------------------------------------------------------------------------------- /src/js/addlisteners.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | onmousemove="mouseMove(event)" 4 | onmouseout="mouseOut()" 5 | 6 | var el = document.getElementById("gameCanvas"); 7 | if (el.addEventListener) { 8 | el.addEventListener("contextmenu", rightClickCanvas, false); 9 | el.addEventListener("mousemove", mouseMove, false); 10 | el.addEventListener("mouseout", mouseOut, false); 11 | } else { 12 | el.attachEvent('oncontextmenu', rightClickCanvas); 13 | el.attachEvent('onmousemove', mouseMove); 14 | el.attachEvent('onmouseout', mouseOut); 15 | } 16 | -------------------------------------------------------------------------------- /src/js/addlisteners_editor.js: -------------------------------------------------------------------------------- 1 | 2 | for (var i=0;i<10;i++) { 3 | var idname = "newsound"+i; 4 | var el = document.getElementById(idname); 5 | el.addEventListener("click", (function(n){return function(){return newSound(n);};})(i), false); 6 | } 7 | 8 | document.getElementById("exampleDropdown").addEventListener("change", dropdownChange, false); 9 | document.getElementById("loadDropDown").addEventListener("change", loadDropDownChange, false); 10 | 11 | var horizontalDragbar = document.getElementById("horizontaldragbar"); 12 | horizontalDragbar.addEventListener("mousedown", horizontalDragbarMouseDown, false); 13 | 14 | var verticalDragbar = document.getElementById("verticaldragbar"); 15 | verticalDragbar.addEventListener("mousedown", verticalDragbarMouseDown, false); 16 | 17 | window.addEventListener("resize", resize_all, false); 18 | window.addEventListener("load", reset_panels, false); 19 | 20 | /* https://github.com/ndrake/PuzzleScript/commit/de4ac2a38865b74e66c1d711a25f0691079a290d */ 21 | window.onbeforeunload = function (e) { 22 | var e = e || window.event; 23 | var msg = 'You have unsaved changes!'; 24 | 25 | if(_editorDirty) { 26 | 27 | // For IE and Firefox prior to version 4 28 | if (e) { 29 | e.returnValue = msg; 30 | } 31 | 32 | // For Safari 33 | return msg; 34 | } 35 | }; 36 | 37 | var gestureHandler = Mobile.enable(); 38 | if (gestureHandler) { 39 | gestureHandler.setFocusElement(document.getElementById('gameCanvas')); 40 | } 41 | 42 | -------------------------------------------------------------------------------- /src/js/buildStandalone.js: -------------------------------------------------------------------------------- 1 | 2 | function downloadBlob(blob, filename) 3 | { 4 | var a = document.createElement('a') 5 | a.download = filename 6 | a.href = window.URL.createObjectURL(blob) 7 | a.dispatchEvent( new MouseEvent('click', { view: window, bubbles: true, cancelable: true }) ) 8 | } 9 | 10 | function getLocalFile(relative_url, error_message, success_callback) 11 | { 12 | var request = new XMLHttpRequest(); 13 | request.open('GET', relative_url); 14 | request.onreadystatechange = function() 15 | { 16 | if(request.readyState != 4) 17 | return; 18 | if (request.responseText === "") 19 | consolePrint(error_message, true) 20 | success_callback(request.responseText) 21 | } 22 | request.send(); 23 | } 24 | 25 | var standalone_JS_Strings = [] 26 | const standalone_JS_Files = [ 27 | 'globalVariables', 'debug_off', 'font', 'rng', 'riffwave', 'editor/random_sound_generators', 'sfxr2', 'codemirror/stringstream', 'colors', 'engine/screen_layout', 'graphics', 28 | 'editor/error_messages', 'engine/log', 29 | 'engine/message_screen', 'engine/level', 'engine/bitvec', 'engine/commands_set', 'engine/rule', 'engine/cell_pattern', 'engine/engine_base', 'parser', 'compiler/identifiers', 30 | 'compiler/rule', 'compiler/rule_parser', 'compiler/rule_expansion', 'compiler/rule_groups', 'compiler/sprites', 'compiler', 'inputoutput', 'mobile' 31 | ] 32 | 33 | function record_js_file(i, text, next_step) 34 | { 35 | standalone_JS_Strings[i] = text 36 | if ((standalone_JS_Strings.length == standalone_JS_Files.length) && (!standalone_JS_Strings.includes(undefined))) 37 | { 38 | next_step( standalone_JS_Strings.join("\n\n") ) 39 | } 40 | } 41 | 42 | 43 | function buildStandalone(sourceCode) 44 | { 45 | getLocalFile('standalone.html', "Couldn't find standalone template. Is there a connection problem to the internet?", (t) => buildStandaloneJS(sourceCode, t)) 46 | } 47 | 48 | 49 | function buildStandaloneJS(sourceCode, htmlString) 50 | { 51 | standalone_JS_Strings = [] // don't care about caching the files as the browser should do it, so just re-download them. 52 | const next_step = function(js_string) { buildStandalonePack(sourceCode, htmlString, js_string) } 53 | standalone_JS_Files.forEach( (filename, i) => getLocalFile('js/'+filename+'.js', 'Cannot download js/'+filename+'.js!', (t) => record_js_file(i, t, next_step) ) ) 54 | } 55 | 56 | function buildStandalonePack(sourceCode, htmlString, standalone_JS_String) 57 | { 58 | if ('background_color' in state.metadata) 59 | { 60 | htmlString = htmlString.replace(/black;\/\*Don\'t/g, state.bgcolor+';\/\*Don\'t'); 61 | } 62 | if ('text_color' in state.metadata) 63 | { 64 | htmlString = htmlString.replace(/lightblue;\/\*Don\'t/g, state.fgcolor+';\/\*Don\'t'); 65 | } 66 | 67 | htmlString = htmlString.replace(/__GAMETITLE__/g, (state.metadata.title !== undefined) ? state.metadata.title : "Pattern:Script Game"); 68 | htmlString = htmlString.replace(/__HOMEPAGE__/g, (state.metadata.homepage !== undefined) ? state.metadata.homepage : "www.puzzlescript.net"); 69 | 70 | // $ has special meaning to JavaScript's String.replace ($0, $1, etc.) Escape $ as $$. 71 | sourceCode = sourceCode.replace(/\$/g, '$$$$'); 72 | htmlString = htmlString.replace(/__GAMEDAT__/g, sourceCode); 73 | 74 | standalone_JS_String = standalone_JS_String.replace(/\/\/ <-- FONT START -->(?:.|\s)*?\/\/ <-- FONT END -->/m, 'font.src = "'+font.asDataURL() + '"') 75 | 76 | htmlString = htmlString.split('__JAVASCRIPT_GOES_HERE__', 2).join(standalone_JS_String) // using replace would cause a bug, as standalone_JS_String contains $ characters 77 | 78 | downloadBlob(new Blob([htmlString], {type: "text/plain;charset=utf-8"}), 'index.html') 79 | } 80 | -------------------------------------------------------------------------------- /src/js/codemirror/active-line.js: -------------------------------------------------------------------------------- 1 | // Because sometimes you need to style the cursor's line. 2 | // 3 | // Adds an option 'styleActiveLine' which, when enabled, gives the 4 | // active line's wrapping
the CSS class "CodeMirror-activeline", 5 | // and gives its background
the class "CodeMirror-activeline-background". 6 | 7 | (function(mod) { 8 | if (typeof exports == "object" && typeof module == "object") // CommonJS 9 | mod(require("../../lib/codemirror")); 10 | else if (typeof define == "function" && define.amd) // AMD 11 | define(["../../lib/codemirror"], mod); 12 | else // Plain browser env 13 | mod(CodeMirror); 14 | })(function(CodeMirror) { 15 | "use strict"; 16 | var WRAP_CLASS = "CodeMirror-activeline"; 17 | var BACK_CLASS = "CodeMirror-activeline-background"; 18 | 19 | CodeMirror.defineOption("styleActiveLine", false, function(cm, val, old) { 20 | var prev = old && old != CodeMirror.Init; 21 | if (val && !prev) { 22 | cm.state.activeLines = []; 23 | updateActiveLines(cm, cm.listSelections()); 24 | cm.on("beforeSelectionChange", selectionChange); 25 | } else if (!val && prev) { 26 | cm.off("beforeSelectionChange", selectionChange); 27 | clearActiveLines(cm); 28 | delete cm.state.activeLines; 29 | } 30 | }); 31 | 32 | function clearActiveLines(cm) { 33 | for (var i = 0; i < cm.state.activeLines.length; i++) { 34 | cm.removeLineClass(cm.state.activeLines[i], "wrap", WRAP_CLASS); 35 | cm.removeLineClass(cm.state.activeLines[i], "background", BACK_CLASS); 36 | } 37 | } 38 | 39 | function sameArray(a, b) { 40 | if (a.length != b.length) return false; 41 | for (var i = 0; i < a.length; i++) 42 | if (a[i] != b[i]) return false; 43 | return true; 44 | } 45 | 46 | function updateActiveLines(cm, ranges) { 47 | var active = []; 48 | for (var i = 0; i < ranges.length; i++) { 49 | var line = cm.getLineHandleVisualStart(ranges[i].head.line); 50 | if (active[active.length - 1] != line) active.push(line); 51 | } 52 | if (sameArray(cm.state.activeLines, active)) return; 53 | cm.operation(function() { 54 | clearActiveLines(cm); 55 | for (var i = 0; i < active.length; i++) { 56 | cm.addLineClass(active[i], "wrap", WRAP_CLASS); 57 | cm.addLineClass(active[i], "background", BACK_CLASS); 58 | } 59 | cm.state.activeLines = active; 60 | }); 61 | } 62 | 63 | function selectionChange(cm, sel) { 64 | updateActiveLines(cm, sel.ranges); 65 | } 66 | }); 67 | -------------------------------------------------------------------------------- /src/js/codemirror/match-highlighter.js: -------------------------------------------------------------------------------- 1 | // Highlighting text that matches the selection 2 | // 3 | // Defines an option highlightSelectionMatches, which, when enabled, 4 | // will style strings that match the selection throughout the 5 | // document. 6 | // 7 | // The option can be set to true to simply enable it, or to a 8 | // {minChars, style, showToken} object to explicitly configure it. 9 | // minChars is the minimum amount of characters that should be 10 | // selected for the behavior to occur, and style is the token style to 11 | // apply to the matches. This will be prefixed by "cm-" to create an 12 | // actual CSS class name. showToken, when enabled, will cause the 13 | // current token to be highlighted when nothing is selected. 14 | 15 | (function(mod) { 16 | if (typeof exports == "object" && typeof module == "object") // CommonJS 17 | mod(require("../../lib/codemirror")); 18 | else if (typeof define == "function" && define.amd) // AMD 19 | define(["../../lib/codemirror"], mod); 20 | else // Plain browser env 21 | mod(CodeMirror); 22 | })(function(CodeMirror) { 23 | "use strict"; 24 | 25 | var DEFAULT_MIN_CHARS = 2; 26 | var DEFAULT_TOKEN_STYLE = "matchhighlight"; 27 | var DEFAULT_DELAY = 100; 28 | 29 | function State(options) { 30 | if (typeof options == "object") { 31 | this.minChars = options.minChars; 32 | this.style = options.style; 33 | this.showToken = options.showToken; 34 | this.delay = options.delay; 35 | } 36 | if (this.style == null) this.style = DEFAULT_TOKEN_STYLE; 37 | if (this.minChars == null) this.minChars = DEFAULT_MIN_CHARS; 38 | if (this.delay == null) this.delay = DEFAULT_DELAY; 39 | this.overlay = this.timeout = null; 40 | } 41 | 42 | CodeMirror.defineOption("highlightSelectionMatches", false, function(cm, val, old) { 43 | if (old && old != CodeMirror.Init) { 44 | var over = cm.state.matchHighlighter.overlay; 45 | if (over) cm.removeOverlay(over); 46 | clearTimeout(cm.state.matchHighlighter.timeout); 47 | cm.state.matchHighlighter = null; 48 | cm.off("cursorActivity", cursorActivity); 49 | } 50 | if (val) { 51 | cm.state.matchHighlighter = new State(val); 52 | highlightMatches(cm); 53 | cm.on("cursorActivity", cursorActivity); 54 | } 55 | }); 56 | 57 | function cursorActivity(cm) { 58 | var state = cm.state.matchHighlighter; 59 | clearTimeout(state.timeout); 60 | state.timeout = setTimeout(function() {highlightMatches(cm);}, state.delay); 61 | } 62 | 63 | function highlightMatches(cm) { 64 | cm.operation(function() { 65 | var state = cm.state.matchHighlighter; 66 | if (state.overlay) { 67 | cm.removeOverlay(state.overlay); 68 | state.overlay = null; 69 | } 70 | if (!cm.somethingSelected() && state.showToken) { 71 | var re = state.showToken === true ? /[\w$]/ : state.showToken; 72 | var cur = cm.getCursor(), line = cm.getLine(cur.line), start = cur.ch, end = start; 73 | while (start && re.test(line.charAt(start - 1))) --start; 74 | while (end < line.length && re.test(line.charAt(end))) ++end; 75 | if (start < end) 76 | cm.addOverlay(state.overlay = makeOverlay(line.slice(start, end), re, state.style)); 77 | return; 78 | } 79 | if (cm.getCursor("head").line != cm.getCursor("anchor").line) return; 80 | var selection = cm.getSelections()[0].replace(/^\s+|\s+$/g, ""); 81 | if (selection.length >= state.minChars) 82 | cm.addOverlay(state.overlay = makeOverlay(selection, false, state.style)); 83 | }); 84 | } 85 | 86 | function boundariesAround(stream, re) { 87 | return (!stream.start || !re.test(stream.string.charAt(stream.start - 1))) && 88 | (stream.pos == stream.string.length || !re.test(stream.string.charAt(stream.pos))); 89 | } 90 | 91 | function makeOverlay(query, hasBoundary, style) { 92 | return {token: function(stream) { 93 | if (stream.match(query) && 94 | (!hasBoundary || boundariesAround(stream, hasBoundary))) 95 | return style; 96 | stream.next(); 97 | stream.skipTo(query.charAt(0)) || stream.skipToEnd(); 98 | }}; 99 | } 100 | }); 101 | -------------------------------------------------------------------------------- /src/js/codemirror/stringstream.js: -------------------------------------------------------------------------------- 1 | /* 2 | Code extracted from codemirror/codemirror.js that is used for parsing and is the only reason why PuzzleScript player had to include codemirror. 3 | */ 4 | 5 | function CodeMirrorStringStream(string, tabSize) 6 | { 7 | this.pos = this.start = 0; 8 | this.string = string; 9 | this.tabSize = tabSize || 8; 10 | this.lastColumnPos = this.lastColumnValue = 0; 11 | this.lineStart = 0; 12 | } 13 | 14 | CodeMirrorStringStream.prototype = { 15 | eol: function() {return this.pos >= this.string.length}, 16 | sol: function() {return this.pos == this.lineStart}, 17 | peek: function() {return this.string.charAt(this.pos) || undefined}, 18 | next: function() 19 | { 20 | if (this.pos < this.string.length) 21 | return this.string.charAt(this.pos++) 22 | }, 23 | eat: function(match) 24 | { 25 | var ch = this.string.charAt(this.pos) 26 | if (typeof match == "string") 27 | var ok = ch == match 28 | else 29 | var ok = ch && (match.test ? match.test(ch) : match(ch)); 30 | if (ok) 31 | { 32 | ++this.pos; 33 | return ch; 34 | } 35 | }, 36 | eatWhile: function(match) 37 | { 38 | var start = this.pos 39 | while (this.eat(match)) { } 40 | return this.pos > start 41 | }, 42 | skipToEnd: function() { this.pos = this.string.length }, 43 | skipTo: function(ch) 44 | { 45 | const found = this.string.indexOf(ch, this.pos) 46 | if (found > -1) 47 | { 48 | this.pos = found 49 | return true 50 | } 51 | }, 52 | match: function(pattern, consume, caseInsensitive) 53 | { 54 | if (typeof pattern == "string") 55 | { 56 | var cased = (str) => (caseInsensitive ? str.toLowerCase() : str) 57 | var substr = this.string.substr(this.pos, pattern.length) 58 | if (cased(substr) == cased(pattern)) 59 | { 60 | if (consume !== false) 61 | this.pos += pattern.length 62 | return true 63 | } 64 | } 65 | else 66 | { 67 | var match = this.string.slice(this.pos).match(pattern) 68 | if (match && match.index > 0) return null 69 | if (match && consume !== false) 70 | this.pos += match[0].length 71 | return match 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/js/compiler/rule.js: -------------------------------------------------------------------------------- 1 | 2 | // ======= CLONING RULES ======= 3 | 4 | function deepCloneCellRow(cellrow) 5 | { 6 | return cellrow.map( 7 | cell => cell.map( oc => (oc === null) ? null : ({dir: oc.dir, ii: oc.ii, no: oc.no, random: oc.random}) ) 8 | ); 9 | } 10 | 11 | function deepCloneHS(HS) 12 | { 13 | return HS.map( deepCloneCellRow ); 14 | } 15 | 16 | function deepCloneRule(rule) 17 | { 18 | return { 19 | lineNumber: rule.lineNumber, 20 | groupNumber: rule.groupNumber, 21 | direction: rule.direction, 22 | tag_classes: rule.tag_classes, 23 | tag_classes_replacements: rule.tag_classes_replacements, 24 | parameter_properties: rule.parameter_properties, 25 | parameter_properties_replacements: rule.parameter_properties_replacements, 26 | parameter_expansion_string: rule.parameter_expansion_string, 27 | late: rule.late, 28 | rigid: rule.rigid, 29 | randomRule:rule.randomRule, 30 | lhs: deepCloneHS(rule.lhs), 31 | rhs: deepCloneHS(rule.rhs), 32 | commands: rule.commands, // should be deepCloned too? 33 | is_directional: rule.is_directional 34 | }; 35 | } 36 | 37 | 38 | 39 | // ======= PRINTING RULES ======= 40 | 41 | function printCell(identifiers, cell) 42 | { 43 | var result = ''; 44 | for (const oc of cell) 45 | { 46 | if (oc === null) 47 | { 48 | result += '... ' 49 | } 50 | else 51 | { 52 | if (oc.no) 53 | result += 'no ' 54 | if (oc.random) 55 | result += 'random ' 56 | result += oc.dir + ' ' 57 | result += identifiers.names[oc.ii]+' ' 58 | } 59 | } 60 | return result 61 | } 62 | 63 | function printCellRow(identifiers, cellRow) 64 | { 65 | return '[ ' + cellRow.map(c => printCell(identifiers,c)).join('| ') + '] '; 66 | } 67 | 68 | function cacheRuleStringRep(identifiers, rule) 69 | { 70 | var result='('+makeLinkToLine(rule.lineNumber)+') '+ rule.direction.toString().toUpperCase()+ ' '; 71 | if (rule.tag_classes.size > 0) 72 | { 73 | result += [...rule.tag_classes].map( (tc_ii, i) => (identifiers.names[tc_ii].toUpperCase()+'='+identifiers.names[rule.tag_classes_replacements[i]]) ).join(', ') + ' ' 74 | } 75 | if (rule.parameter_properties.size > 0) 76 | { 77 | result += [...rule.parameter_properties].map( (pp_ii, i) => (identifiers.names[pp_ii].toUpperCase()+'='+identifiers.names[rule.parameter_properties_replacements[i]]) ).join(', ') + ' ' 78 | } 79 | if (rule.rigid) { 80 | result = "RIGID "+result+" "; 81 | } 82 | if (rule.randomRule) { 83 | result = "RANDOM "+result+" "; 84 | } 85 | if (rule.late) { 86 | result = "LATE "+result+" "; 87 | } 88 | for (const cellRow of rule.lhs) { 89 | result = result + printCellRow(identifiers, cellRow); 90 | } 91 | result = result + "-> "; 92 | for (const cellRow of rule.rhs) { 93 | result = result + printCellRow(identifiers, cellRow); 94 | } 95 | result += rule.commands.get_representation() 96 | rule.stringRep = result 97 | } 98 | 99 | function cacheAllRuleNames(state) 100 | { 101 | for (const rule of state.rules) 102 | { 103 | cacheRuleStringRep(state.identifiers, rule); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/js/debug.js: -------------------------------------------------------------------------------- 1 | var canSetHTMLColors=false; 2 | var canDump=true; 3 | var canYoutube=false; 4 | var inputHistory=[]; 5 | var compiledText; 6 | var IDE=true; 7 | var recordingStartsFromLevel = 0 // for input recorder 8 | 9 | Level.prototype.convertToString = function(def_char = '=') 10 | { 11 | var out = '' 12 | var seenCells = {} 13 | var i = 0 14 | for (var y = 0; y < this.height; y++) 15 | { 16 | for (var x = 0; x < this.width; x++) 17 | { 18 | const bitmask = this.getCell(x + y*this.width) // TODO: it should be y + x*this.height 19 | var objs = []; 20 | for (var bit = 0; bit < 32 * STRIDE_OBJ; ++bit) 21 | { 22 | if (bitmask.get(bit)) 23 | { 24 | objs.push(state.identifiers.objects[state.idDict[bit]].name) 25 | } 26 | } 27 | objs.sort() 28 | objs = objs.join(' ') 29 | /* replace repeated object combinations with numbers */ 30 | if (!seenCells.hasOwnProperty(objs)) 31 | { 32 | seenCells[objs] = i++ 33 | out += objs + def_char 34 | } 35 | out += seenCells[objs] + ',' 36 | } 37 | out += '\n' 38 | } 39 | return out 40 | } 41 | 42 | function levelFromUnitTestString(str) 43 | { 44 | const lines = str.split('\n') 45 | const height = lines.length - 1 46 | const width = lines[0].split(',').length - 1 47 | var lev = new Level(width, height, new Int32Array(width * height * STRIDE_OBJ)) 48 | execution_context.resetCommands() 49 | var masks = [] 50 | for (const [y, line] of lines.entries()) 51 | { 52 | for (const [x, cell_content] of line.split(',').entries()) 53 | { 54 | if (cell_content.length == 0) 55 | continue 56 | var cell_parts = cell_content.split(/[:=]/) // : is used by vanilla PuzzleScript but appears in names of objects with tags so it is replaced with = in Pattern:Script. 57 | if (cell_parts.length > 1) 58 | { 59 | const object_names = cell_parts[0].split(' ') 60 | const objects = object_names.map( object_name => state.identifiers.objects.find( o => (object_name === o.name) ) ) 61 | const mask = makeMaskFromGlyph( objects.map( o => o.id ) ) 62 | masks.push(mask) 63 | } 64 | const mask_id = parseInt(cell_parts[cell_parts.length - 1]) 65 | const maskint = masks[mask_id] 66 | lev.setCell(x + y*width, maskint) 67 | } 68 | } 69 | return lev 70 | } 71 | 72 | function loadUnitTestStringLevel(str) 73 | { 74 | loadLevelFromLevelDat(state, levelFromUnitTestString(str), null) 75 | } 76 | 77 | 78 | function stripHTMLTags(html_str) 79 | { 80 | if (typeof html_str !== 'string') 81 | return html_str 82 | var div = document.createElement("div"); 83 | div.innerHTML = html_str; 84 | var text = div.textContent || div.innerText || ""; 85 | return text.trim(); 86 | } 87 | 88 | function dumpTestCase() 89 | { 90 | //compiler error data 91 | const levelDat = compiledText 92 | const resultstring = '\t[
\t\t`' + (state.metadata.title||'untitled test') + '`,
\t\t' + 93 | JSON.stringify( [levelDat, errorStrings.map(stripHTMLTags), warningStrings.map(stripHTMLTags)] ) + '
\t],
' 94 | consolePrint('
Compilation error/warning data (for error message tests - errormessage_testdata.js):

' + makeSelectableText(resultstring) + '
', true) 95 | 96 | //normal session recording data 97 | if (level !== undefined) 98 | { 99 | const resultstring = '\t[
\t\t`' + (state.metadata.title||'untitled test') + '`,
\t\t' + 100 | JSON.stringify( [levelDat, inputHistory.concat([]), level.convertToString(), recordingStartsFromLevel, RandomGen.seed] ) + '
\t],
' 101 | consolePrint('
Recorded play session data (for play session tests - testdata.js):

'+makeSelectableText(resultstring) + '
', true) 102 | } 103 | } 104 | 105 | function clearInputHistory() 106 | { 107 | if (canDump === true) 108 | { 109 | inputHistory=[] 110 | recordingStartsFromLevel = curlevel 111 | } 112 | } 113 | 114 | function pushInput(inp) { 115 | if (canDump===true) { 116 | inputHistory.push(inp); 117 | } 118 | } 119 | 120 | 121 | function print_ruleset(rule_set) 122 | { 123 | var output = '' 124 | for (const rulegroup of rule_set) 125 | { 126 | output += '  ' + rulegroup.map(rule => rule.string_representation).join('
+ ') + '
' 127 | } 128 | return output 129 | } 130 | -------------------------------------------------------------------------------- /src/js/debug_off.js: -------------------------------------------------------------------------------- 1 | // from console.js 2 | 3 | function addErrorMessage(str) 4 | { 5 | var errorText = document.getElementById("errormessage") 6 | 7 | var div = document.createElement("div"); 8 | div.innerHTML = str; 9 | str = div.textContent || div.innerText || ""; 10 | 11 | errorText.innerHTML += str + "
" 12 | } 13 | 14 | function consolePrint(str, urgent) { /* addErrorMessage(str) */ } 15 | 16 | function consolePrintFromRule(str, rule, urgent) { /* addErrorMessage(str) */ } 17 | 18 | function consoleCacheDump(str) { } 19 | 20 | function consoleError(str, lineNumber) { addErrorMessage(str) } 21 | 22 | 23 | 24 | // from debug.js 25 | 26 | var canSetHTMLColors=true; 27 | var canDump=false; 28 | var canYoutube=true; 29 | var IDE=false; 30 | 31 | function clearInputHistory() { } 32 | function pushInput(inp) { } -------------------------------------------------------------------------------- /src/js/engine/commands_set.js: -------------------------------------------------------------------------------- 1 | 2 | function CommandsSet() 3 | { 4 | BitVec.call(this, 13) // todo 5 | this.message = null 6 | this.nb_commands = 0 7 | } 8 | CommandsSet.prototype = Object.create(BitVec.prototype) 9 | 10 | // DO NOT CHANGE THE ORDER OF COMMANDS 11 | CommandsSet.commandwords = [ 'cancel', 'restart', 'again', 'win', 'checkpoint', 'nosave', 'sfx0', 'sfx1', 'sfx2', 'sfx3', 'sfx4', 'sfx5', 'sfx6', 'sfx7', 'sfx8', 'sfx9', 'sfx10', 'message' ] 12 | CommandsSet.command_keys = {} 13 | CommandsSet.commandwords.forEach( (word, index) => { CommandsSet.command_keys[word] = index} ) 14 | 15 | CommandsSet.prototype.is_command = function(word) 16 | { 17 | return CommandsSet.command_keys.hasOwnProperty(word) 18 | } 19 | 20 | CommandsSet.prototype.addCommand = function(command) 21 | { 22 | const key = CommandsSet.command_keys[command] 23 | if (this.get(key)) 24 | return 25 | this.ibitset(key) 26 | this.nb_commands++ 27 | } 28 | 29 | CommandsSet.prototype.setMessage = function(msg_text) 30 | { 31 | this.message = msg_text 32 | this.addCommand('message') 33 | } 34 | 35 | CommandsSet.prototype.reset = function() 36 | { 37 | this.setZero() 38 | this.message = null 39 | } 40 | 41 | CommandsSet.prototype.get_representation = function() 42 | { 43 | return CommandsSet.commandwords.filter( (k,i) => this.get(i) ).join(' ').replace('message', '(message, "'+this.message+'")') 44 | } -------------------------------------------------------------------------------- /src/js/engine/generate_matches.js: -------------------------------------------------------------------------------- 1 | 2 | /* THIS FILE IS NOT FOR EXECUTION !!!! 3 | * it is for documenting this complex part of the engine that is the generation of specific rule-matching functions 4 | */ 5 | 6 | 7 | // Cells 8 | // ===== 9 | 10 | // The generated functions are a specialized case of: 11 | function matchCell() 12 | { 13 | return ( 14 | ((level.objects[i] & cell_pattern.objectsPresent) == cell_pattern.objectsPresent) 15 | && ((level.objects[i] & cell_pattern.objectsMissing) == 0) 16 | && ((level.movements[i] & cell_pattern.movementsPresent) == cell_pattern.movementsPresent) 17 | && ((level.movements[i] & cell_pattern.movementsMissing) == 0) 18 | && cell_pattern.anyObjectsPresent.every( s => ((level.objects[i] & s) != 0) ) 19 | ) 20 | } 21 | // - Note that there is no anyMovementPresent, because the objects in an anyObjectsPresent slot are all in the same layer and thus share the same movement, which has been 22 | // put in movementsPresent / movementsMissing. 23 | // - Also, there is no anyObjectMissing, because that would correspond to object conditions like 'no single-layer-property', which has been translated into 'no obj1 no obj2...' 24 | // and put in objectsMissing. 25 | // - The case of 'no aggregate' = 'no obj1 or no obj2 or...' could be dealt easily with a test like: 26 | // ((level.objects[i] & cell_pattern.aggregateMissing) !== cell_pattern.aggregateMissing) 27 | 28 | // Cell Rows 29 | // ========= 30 | 31 | // This function has been replaced with a direct call to Rule.cellRowMatches[cellRowIndex](this.patterns[cellRowIndex], tuple[cellRowIndex], delta_index), 32 | // i.e. a direct call to the function generated by Rule.generateCellRowMatchesFunction. 33 | function DoesCellRowMatch(delta_index, cellRow, start_cell_index) 34 | { 35 | var targetIndex = start_cell_index 36 | for (const cellPattern of cellRow) 37 | { 38 | if ( ! cellPattern.matches(targetIndex) ) 39 | return false 40 | targetIndex += delta_index 41 | } 42 | return true 43 | } 44 | 45 | // Say cellRow has length 3 46 | // CellRow Matches can be specialized to look something like: 47 | function cellRowMatchesFunctionGenerate(delta_index, cellRow, i) 48 | { 49 | return cellRow[0].matches(i) && cellRow[1].matches(i+delta_index) && cellRow[2].matches(i+2*delta_index) 50 | } 51 | 52 | function DoesCellRowMatchWildCard(delta_index, cellRow, start_cell_index, maxk, mink=0) 53 | { 54 | var targetIndex = start_cell_index 55 | 56 | for (var j=0; j= cellRow.length) 75 | return true 76 | } 77 | break 78 | } 79 | else if (!cellPattern.matches(targetIndex)) 80 | break 81 | targetIndex += delta_index 82 | } 83 | return false 84 | } 85 | 86 | // Say cellRow has length 3, with a split in the middle 87 | // CellRow Matches WildCards can be specialized to look something like: 88 | function cellRowMatchesWildcardFunctionGenerate(delta_index, cellRow,i, maxk, mink) 89 | { 90 | var result = [] 91 | var matchfirsthalf = cellRow[0].matches(i) 92 | if (matchfirsthalf) 93 | { 94 | for (var k=mink; k' + ((anchor_text === null) ? l : anchor_text) + ''; 15 | } 16 | 17 | function logErrorCacheable(str, lineNumber, urgent) 18 | { 19 | logErrorAux(str, lineNumber, urgent, 'errorText', errorStrings) 20 | } 21 | 22 | function logError(str, lineNumber, urgent) 23 | { 24 | logErrorAux(str, lineNumber, urgent, 'errorText', errorStrings, true) 25 | } 26 | 27 | function logWarning(str, lineNumber, urgent) 28 | { 29 | logErrorAux(str, lineNumber, urgent, 'warningText', warningStrings, true) 30 | } 31 | 32 | function logErrorAux(str, lineNumber, urgent = false, text_class, text_cache, print_immediately) 33 | { 34 | if (compiling||urgent) 35 | { 36 | const txt = get_error_message(str) 37 | const lineString = (lineNumber !== undefined) ? makeLinkToLine(lineNumber, ' line ' + lineNumber.toString() + '') + ': ' : '' 38 | const errorString = lineString + '' + txt + '' 39 | const key = (typeof str === 'string') ? str : [str, lineNumber] 40 | if (text_cache.findIndex(x => error_message_equal(x, key)) < 0 || urgent) 41 | { 42 | // not a duplicate error, we need to log it 43 | consolePrint(errorString, print_immediately) 44 | text_cache.push(key) 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/js/font.js: -------------------------------------------------------------------------------- 1 | const font_width = 5 2 | const font_height = 12 3 | 4 | const chars_in_font = '0123456789abcdefghijklmnopqrstuvwx×yzABCDEFGHIJKLMNOPQRSTUVWXYZ.·•…†‡ƒ‚„,;:?¿!¡@£$%‰^&*()+÷±-–—_= {}[]\'‘’“”"/\\|¦<‹«>›»~˜`#' + 5 | 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßẞàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘř' + 6 | 'ŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽž€™¢¤¥§¨©®ªº¬¯°' 7 | 8 | var font = new Image() 9 | // <-- FONT START --> 10 | // <-- Do not edit these comments, they are used by buildStandalone.js to replace the loading of the font image with an inline version of the image. --> 11 | // <-- Note that ideally, we should keep track of all colors/chars used in the game and integrate only these in the inlined font picture. --> 12 | font.src = 'fonts/font-5x12.png' 13 | 14 | font.asDataURL = function() 15 | { 16 | var canvas = document.createElement('canvas') 17 | canvas.width = this.width 18 | canvas.height = this.height 19 | canvas.getContext('2d').drawImage(this, 0, 0) 20 | return canvas.toDataURL("image/png") 21 | } 22 | // <-- FONT END --> 23 | font.on_load = function() {} 24 | font.addEventListener('load', function() 25 | { 26 | const canvas = document.createElement('canvas') 27 | canvas.width = font.width 28 | canvas.height = font.height 29 | const fctx = canvas.getContext('2d') 30 | fctx.drawImage(font, 0, 0) 31 | font.pixels = fctx.getImageData(0, 0, canvas.width, canvas.height).data 32 | font.on_load() 33 | }) 34 | 35 | font.colored_fonts = { '1-#FFFFFFFF': font } 36 | 37 | font.colored_font = function(css_color) 38 | { 39 | const key = css_color 40 | if (key in this.colored_fonts) 41 | return this.colored_fonts[key] 42 | 43 | if (font.pixels === undefined) // image is not loaded yet 44 | return null 45 | 46 | const color = Array.from( [1,3,5], i => parseInt(css_color.substr(i,2), 16) ) 47 | const f_alpha = parseInt(css_color.substr(7,2), 16) || 255 48 | 49 | var canvas = document.createElement('canvas') 50 | canvas.width = this.width 51 | canvas.height = this.height 52 | var fctx = canvas.getContext('2d') 53 | 54 | for (var i = 0; i < this.pixels.length; i += 4) 55 | { 56 | const alpha = this.pixels[i+3]/255 // alpha channel. 0=transparent, 255=opaque 57 | if (alpha === 0) 58 | continue 59 | fctx.fillStyle = 'rgba(' + color.map(x => Math.round(x*alpha)).join() + ',' + f_alpha + ')' 60 | fctx.fillRect( ((i/4) % this.width), Math.floor((i/4) / this.width), 1, 1) 61 | } 62 | this.colored_fonts[key] = canvas 63 | return canvas 64 | } 65 | 66 | function draw_char(ctx, colored_font_image, ch, x, y, w, h) // draws char ch at position (x,y) in the canvas ctx with width w and height h 67 | { 68 | const ch_index = chars_in_font.indexOf(ch) 69 | if (ch_index < 0) 70 | return 71 | ctx.drawImage(colored_font_image, ch_index*w, 0, w, h, x, y, w, h) 72 | } 73 | -------------------------------------------------------------------------------- /src/js/gamedat.js: -------------------------------------------------------------------------------- 1 | //var sourceCode = "title orthogonal rule test\n\n========\nOBJECTS\n========\n\nBackground .\nLIGHTGREEN GREEN\n11111\n01111\n11101\n11111\n10111\n\nPlayer p\nPink\n\nDiamond \nBlue\n.....\n.....\n..0..\n.....\n.....\n\nCrate\nOrange\n00000\n0...0\n0...0\n0...0\n00000\n\n=======\nLEGEND\n=======\n=======\nSOUNDS\n=======\n================\nCOLLISIONLAYERS\n================\n\nBackground\nPlayer\nCrate\nDiamond\n\n======\nRULES\n======\n\n[ ] -> [ Diamond ]\n\n==============\nWINCONDITIONS\n==============\n=======\nLEVELS\n=======\n\n.....\n.....\n..p..\n.....\n....."; 2 | var sourceCode = __GAMEDAT__; 3 | compile(["restart"],sourceCode); 4 | -------------------------------------------------------------------------------- /src/js/globalVariables.js: -------------------------------------------------------------------------------- 1 | var unitTesting=false; 2 | var curlevel=0; 3 | var muted=0; 4 | 5 | const storage_get = (key) => localStorage.getItem(key) 6 | const storage_has = (key) => (localStorage.getItem(key) !== null) 7 | const storage_set = (key, value) => localStorage.setItem(key, value) 8 | const storage_remove = (key) => localStorage.removeItem(key) 9 | 10 | var debug = false 11 | var verbose_logging=false; 12 | var throttle_movement=false; 13 | var cache_console_messages=false; 14 | const deltatime = 17 15 | var timer=0; 16 | var repeatinterval=150; 17 | var autotick=0; 18 | var autotickinterval=0; 19 | var winning=false; 20 | var againing=false; 21 | var againinterval=150; 22 | var norepeat_action=false; 23 | var oldflickscreendat=[];//used for buffering old flickscreen/scrollscreen positions, in case player vanishes 24 | var keybuffer = [] 25 | 26 | var level 27 | 28 | var sprite_width = 5 29 | var sprite_height = 5 30 | 31 | function clamp(min, value, max) 32 | { 33 | return (value < max) ? ( (value < min) ? min : value ) : max 34 | } -------------------------------------------------------------------------------- /src/js/makegif.js: -------------------------------------------------------------------------------- 1 | function makeGIF() 2 | { 3 | var randomseed = RandomGen.seed; 4 | const inputDat = Array.from(inputHistory) 5 | 6 | unitTesting=true; 7 | levelString=compiledText; 8 | 9 | var encoder = new GIFEncoder(); 10 | encoder.setRepeat(0); //auto-loop 11 | encoder.setDelay(200); 12 | encoder.start(); 13 | 14 | // TODO: we should not have to recompile. Actually, we don't want to recompile. We want to use the replay the inputHistory in the same state (already compiled) than 15 | // when we created the inputHistory. 16 | compile(curlevel, levelString, randomseed) 17 | 18 | var gifcanvas = document.createElement('canvas'); 19 | const [virtual_screen_w, virtual_screen_h] = screen_layout.content.get_virtual_screen_size() 20 | gifcanvas.width = gifcanvas.style.width = virtual_screen_w * screen_layout.magnification 21 | gifcanvas.height = gifcanvas.style.height = virtual_screen_h * screen_layout.magnification 22 | var gifctx = gifcanvas.getContext('2d'); 23 | 24 | gifctx.drawImage(screen_layout.canvas, -screen_layout.margins[0], -screen_layout.margins[1]); 25 | encoder.addFrame(gifctx); 26 | var autotimer=0; 27 | 28 | for(const val of inputDat) 29 | { 30 | var realtimeframe = false 31 | switch (val) 32 | { 33 | case 'undo': 34 | execution_context.doUndo() 35 | break 36 | case 'restart': 37 | DoRestart() 38 | break 39 | case 'tick': 40 | processInput(processing_causes.autotick) 41 | realtimeframe = true 42 | break 43 | default: 44 | processInput(val) 45 | } 46 | 47 | redraw() 48 | gifctx.drawImage(screen_layout.canvas, -screen_layout.margins[0], -screen_layout.margins[1]) 49 | encoder.addFrame(gifctx) 50 | encoder.setDelay(realtimeframe ? autotickinterval : repeatinterval) 51 | autotimer += repeatinterval 52 | 53 | while (againing) 54 | { 55 | processInput(processing_causes.again_frame) 56 | redraw() 57 | 58 | encoder.setDelay(againinterval) 59 | gifctx.drawImage(screen_layout.canvas, -screen_layout.margins[0], -screen_layout.margins[1]) 60 | encoder.addFrame(gifctx) 61 | } 62 | } 63 | 64 | encoder.finish(); 65 | const data_url = 'data:image/gif;base64,'+btoa(encoder.stream().getData()); 66 | consolePrint(''); 67 | consolePrint('Download GIF'); 68 | 69 | inputHistory = inputDat 70 | unitTesting = false 71 | } 72 | -------------------------------------------------------------------------------- /src/js/rng.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Seedable random number generator functions. 3 | * @version 1.0.0 4 | * @license Public Domain 5 | * 6 | * @example 7 | * var rng = new RNG('Example'); 8 | * rng.random(40, 50); // => 42 9 | * rng.uniform(); // => 0.7972798995050903 10 | */ 11 | 12 | /** 13 | * Get the underlying bytes of this string. 14 | * @return {Array} An array of bytes 15 | */ 16 | String.prototype.getBytes = function() { 17 | var output = []; 18 | for (var i = 0; i < this.length; i++) { 19 | var c = this.charCodeAt(i); 20 | var bytes = []; 21 | do { 22 | bytes.push(c & 0xFF); 23 | c = c >> 8; 24 | } while (c > 0); 25 | output = output.concat(bytes.reverse()); 26 | } 27 | return output; 28 | } 29 | 30 | /** 31 | * @param {String} seed A string to seed the generator. 32 | * @constructor 33 | */ 34 | function RC4(seed) { 35 | this.s = new Array(256); 36 | this.i = 0; 37 | this.j = 0; 38 | for (var i = 0; i < 256; i++) { 39 | this.s[i] = i; 40 | } 41 | if (seed) { 42 | this.mix(seed); 43 | } 44 | } 45 | 46 | RC4.prototype._swap = function(i, j) { 47 | var tmp = this.s[i]; 48 | this.s[i] = this.s[j]; 49 | this.s[j] = tmp; 50 | } 51 | 52 | /** 53 | * Mix additional entropy into this generator. 54 | * @param {String} seed 55 | */ 56 | RC4.prototype.mix = function(seed) 57 | { 58 | const input = seed.getBytes() 59 | var j = 0; 60 | for (var i = 0; i < this.s.length; i++) { 61 | j += this.s[i] + input[i % input.length]; 62 | j %= 256; 63 | this._swap(i, j); 64 | } 65 | } 66 | 67 | /** 68 | * @return {number} The next byte of output from the generator. 69 | */ 70 | RC4.prototype.next = function() { 71 | this.i = (this.i + 1) % 256; 72 | this.j = (this.j + this.s[this.i]) % 256; 73 | this._swap(this.i, this.j); 74 | return this.s[(this.s[this.i] + this.s[this.j]) % 256]; 75 | } 76 | 77 | /** 78 | * Create a new random number generator with optional seed. If the 79 | * provided seed is a function (i.e. Math.random) it will be used as 80 | * the uniform number generator. 81 | * @param seed An arbitrary object used to seed the generator. 82 | * @constructor 83 | */ 84 | function RNG(seed) 85 | { 86 | if (seed == null) { 87 | seed = (Math.random() + Date.now()).toString() 88 | } 89 | else if (Object.prototype.toString.call(seed) !== '[object String]') { 90 | seed = JSON.stringify(seed); 91 | } 92 | this.seed = seed 93 | this._state = seed ? new RC4(seed) : null 94 | } 95 | 96 | /** 97 | * @return {number} Uniform random number between 0 and 255. 98 | */ 99 | RNG.prototype.nextByte = function() { 100 | return this._state.next(); 101 | } 102 | 103 | /** 104 | * @return {number} Uniform random number between 0 and 1. 105 | */ 106 | RNG.prototype.uniform = function() { 107 | const BYTES = 7; // 56 bits to make a 53-bit double 108 | var output = 0; 109 | for (var i = 0; i < BYTES; i++) { 110 | output *= 256; 111 | output += this.nextByte(); 112 | } 113 | return output / (Math.pow(2, BYTES * 8) - 1); 114 | } 115 | 116 | // Returns an integer in [0,max[ 117 | RNG.prototype.integer = function(max) { return Math.floor(max*this.uniform()) } 118 | 119 | // Returns a random element of an array 120 | RNG.prototype.pickInArray = function(arr) { return arr[this.integer(arr.length)] } 121 | -------------------------------------------------------------------------------- /src/js/soundbar.js: -------------------------------------------------------------------------------- 1 | 2 | var audio; 3 | 4 | 5 | function newSound(instrument) 6 | { 7 | const seed = instrument + 100 * ((Math.random() * 1000000) | 0) 8 | consolePrint(generatorNames[instrument] + ' : ' + '' + seed.toString() + '',true); 9 | var params = generateFromSeed(seed); 10 | params.sample_rate = SAMPLE_RATE; 11 | params.bit_depth = BIT_DEPTH; 12 | var sound = SoundEffect.generate(params); 13 | sound.play(); 14 | } 15 | 16 | function buttonPress() { 17 | var generatortype = 3; 18 | var seed = document.getElementById('sounddat').value; 19 | var params = generateFromSeed(seed); 20 | params.sample_rate = SAMPLE_RATE; 21 | params.bit_depth = BIT_DEPTH; 22 | var sound = SoundEffect.generate(params); 23 | sound.play(); 24 | } 25 | -------------------------------------------------------------------------------- /src/runserver: -------------------------------------------------------------------------------- 1 | cd ../ 2 | python -m SimpleHTTPServer 1234 3 | -------------------------------------------------------------------------------- /src/tests/demo_list.txt: -------------------------------------------------------------------------------- 1 | I'm too far gone.txt 2 | Loop Deleter.txt 3 | README 4 | actiontest.txt 5 | againexample.txt 6 | atlas shrank.txt 7 | blank.txt 8 | blockfaker.txt 9 | bouncers.txt 10 | byyourside.txt 11 | cakemonsters.txt 12 | castlecloset.txt 13 | castlemouse.txt 14 | chaos wizard.txt 15 | coincounter.txt 16 | collapse.txt 17 | color chained.txt 18 | constellationz.txt 19 | cratopia.txt 20 | cute train.txt 21 | dropswap.txt 22 | dungeon janitor.txt 23 | easyenigma.txt 24 | ebony and ivory.txt 25 | gobble_rush.txt 26 | heroes_of_sokoban.txt 27 | heroes_of_sokoban_2.txt 28 | heroes_of_sokoban_3.txt 29 | icecrates.txt 30 | it dies in the light.txt 31 | kettle.txt 32 | kishoutenketsu.html 33 | ledchallenge.txt 34 | leftrightnpcs.txt 35 | legend of zokoban.txt 36 | limerick.txt 37 | lovendpieces.txt 38 | lunar_lockout.txt 39 | m c eschers armageddon.txt 40 | manic_ammo.txt 41 | mazetest.txt 42 | mazezam.txt 43 | microban.txt 44 | midas.txt 45 | modality.txt 46 | naughtysprite.txt 47 | nekopuzzle.txt 48 | notsnake.txt 49 | octat.txt 50 | ponies jumping synchronously.txt 51 | push.txt 52 | puzzles.txt 53 | randomrobots.txt 54 | randomspawner.txt 55 | rigid_and_little.txt 56 | rigid_one_object.txt 57 | rigid_scott1.txt 58 | rigidfail1.txt 59 | riverpuzzle.txt 60 | robotarm.txt 61 | scriptcross.txt 62 | several_rigid_bodies.txt 63 | slidings.txt 64 | smother.txt 65 | sok7.txt 66 | sokoban_basic.txt 67 | sokoban_eyeball.txt 68 | sokoban_horizontal.txt 69 | sokoban_match3.txt 70 | sokoban_sticky.txt 71 | sokobond demake.txt 72 | stick_candy_puzzle_saga.txt 73 | sumo.txt 74 | take heart lass.txt 75 | the_saga_of_the_candy_scroll.txt 76 | threes.txt 77 | tiny treasure hunt.txt 78 | tunnel rat.txt 79 | twolittlecrates1.txt 80 | twolittlecrates2.txt 81 | twolittlecrates3.txt 82 | twolittlecrates4.txt 83 | whaleworld.txt 84 | wordgame.txt 85 | wrappingrecipe.txt 86 | zenpuzzlegarden.txt 87 | -------------------------------------------------------------------------------- /src/tests/resources/testingFrameWork.js: -------------------------------------------------------------------------------- 1 | function runTest(dataarray) { 2 | unitTesting=true; 3 | levelString=dataarray[0]; 4 | errorStrings = [] 5 | warningStrings = [] 6 | 7 | for (const s of errorStrings) 8 | { 9 | throw s 10 | } 11 | 12 | const inputDat = dataarray[1] 13 | const targetlevel = dataarray[3] || 0 14 | const randomseed = dataarray[4] || null 15 | 16 | compile(targetlevel, levelString, randomseed) 17 | 18 | if (errorStrings.length > 0) 19 | return false 20 | 21 | while (againing) 22 | { 23 | againing = false 24 | processInput(processing_causes.again_frame) 25 | } 26 | 27 | for(const val of inputDat) 28 | { 29 | if (val === "undo") { 30 | execution_context.doUndo() 31 | } else if (val === "restart") { 32 | DoRestart() 33 | } else if (val === "tick") { 34 | processInput(processing_causes.autotick) 35 | } else { 36 | processInput(val) 37 | } 38 | while (againing) 39 | { 40 | againing = false 41 | processInput(processing_causes.again_frame) 42 | } 43 | } 44 | 45 | unitTesting = false 46 | return (level.convertToString( (dataarray[2].indexOf('=') >= 0) ? '=' : ':' ) === dataarray[2]) 47 | } 48 | 49 | function runCompilationTest(game_string, recordedErrorStrings, recordedWarningStrings) 50 | { 51 | unitTesting = true 52 | errorStrings = [] 53 | warningStrings = [] 54 | 55 | try{ 56 | compile(null, game_string) 57 | } catch (error){ 58 | console.log(error) 59 | } 60 | 61 | return error_message_equal(errorStrings, recordedErrorStrings) && error_message_equal(warningStrings, recordedWarningStrings) 62 | } 63 | -------------------------------------------------------------------------------- /src/tests/resources/tests.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | var inputVals = {0 : 'U', 1: 'L', 2:'D', 3:'R', 4:' Action ', tick:' Tick ', undo:' Undo ', restart:' Restart '} 4 | 5 | // tests of results of inputs 6 | function test_module_with_inputs(testdata_list) 7 | { 8 | for (const [testname, td] of testdata_list) 9 | { 10 | const [testcode, testinput, testresult] = td 11 | const level_num = td[3]||0 12 | const seed = td[4] // undefined is ok 13 | const input = testinput.map( j => inputVals[j] ).join('').replaceAll(/([^t\s]{5})(?=[^\s])/gu, '$1 ').replaceAll(/\s\s+/g, ' ') 14 | const description = "level: " + level_num + "
input: " + input + '
Game:
' + testcode + '
' 15 | test( 16 | testname, 17 | [ [testname, testcode, input, testresult, level_num, seed ], ['test name', 'game code', 'input', 'expected level state', 'level number', 'random seed'] ], 18 | function(tdat) 19 | { 20 | const display_content = description 21 | return function() 22 | { 23 | ok( 24 | runTest(tdat), 25 | ((errorStrings.length > 0) ? ('Got errors:
    ' + errorStrings.map(m => '
  • ' + JSON.stringify(stripHTMLTags(m)) + '
  • ').join('') + '
') : '') + 26 | ((warningStrings.length > 0) ? ('Got warnings:
    ' + warningStrings.map(m => '
  • ' + JSON.stringify(stripHTMLTags(m)) + '
  • ').join('') + '
') : '') 27 | + display_content 28 | ) 29 | }; 30 | }(td) 31 | ) 32 | } 33 | } 34 | 35 | QUnit.module('Game parts') // replay game parts to check the execution of rules 36 | test_module_with_inputs(testdata) 37 | 38 | QUnit.module('Increpare Games') // replay game parts to check the execution of rules 39 | test_module_with_inputs(increpare_testdata) 40 | 41 | 42 | 43 | 44 | QUnit.module('Errors and warnings') // check that they are well triggered 45 | 46 | function test_compile(testcode, errors, warnings) 47 | { 48 | return function() 49 | { 50 | const testerrors = 'Expected errors:
    ' + errors.map( m => '
  • '+JSON.stringify(m)+'
  • ').join('') + '
' 51 | const testwarnings = 'Expected warnings:
    ' + warnings.map(m => '
  • '+JSON.stringify(m)+'
  • ').join('') + '
' 52 | ok(runCompilationTest(testcode, errors, warnings), 53 | testerrors + testwarnings + 54 | 'Got errors:
    ' + errorStrings.map(m => '
  • ' + JSON.stringify(stripHTMLTags(m)) + '
  • ').join('') + '
' + 55 | 'Got warnings:
    ' + warningStrings.map(m => '
  • ' + JSON.stringify(stripHTMLTags(m)) + '
  • ').join('') + '
' + 56 | 'Game:
' + testcode + '
' 57 | ) 58 | } 59 | } 60 | 61 | for (const [testname, td] of errormessage_testdata) 62 | { 63 | test( 64 | testname, 65 | [ [testname, td[0]], ['test name', 'game code'] ], 66 | test_compile(td[0], td[1], td[2]) 67 | ) 68 | } 69 | 70 | 71 | QUnit.module('Demos') // Test that demos compile without error or warning 72 | 73 | function get_textfile(filename, callback) 74 | { 75 | var fileOpenClient = new XMLHttpRequest() 76 | fileOpenClient.open('GET', filename) 77 | fileOpenClient.onreadystatechange = function() 78 | { 79 | if(fileOpenClient.readyState == 4) 80 | { 81 | callback(fileOpenClient.responseText) 82 | } 83 | } 84 | fileOpenClient.send() 85 | } 86 | 87 | get_textfile('demo_list.txt', demo_list => demo_list.split('\n').forEach(test_demo_file) ) 88 | 89 | function test_demo_file(demo_filename) 90 | { 91 | if (demo_filename === 'README' || demo_filename === 'blank.txt' || demo_filename === '') 92 | return 93 | get_textfile('../demo/'+demo_filename, function(demo_text) 94 | { 95 | // const errormessage_entry = errormessage_testdata.findIndex( ([name, data]) => data[0].replace(/\s/g, '') === demo_text.replace(/\s/g, '')) 96 | // if (errormessage_entry >= 0) 97 | // console.log('can erase entry #'+errormessage_entry+' ('+errormessage_testdata[errormessage_entry][0]+') of error messages, as it is the same as '+demo_filename) 98 | test( 99 | demo_filename, 100 | [ [demo_text, demo_filename], ['game code', 'filename'] ], 101 | test_compile(demo_text, [], []) 102 | ) 103 | }) 104 | } 105 | -------------------------------------------------------------------------------- /src/tests/resources/wrapper.js: -------------------------------------------------------------------------------- 1 | var lastDownTarget = null; 2 | var canvas = null; 3 | var input = document.createElement('TEXTAREA'); 4 | 5 | function canvasResize() {} 6 | 7 | function redraw() {} 8 | 9 | function forceRegenImages() {} 10 | 11 | var levelString; 12 | var inputString; 13 | var outputString; 14 | 15 | function consolePrintFromRule(text){} 16 | function consolePrint(text) {} 17 | function consoleError(text) { 18 | // window.console.log(text); 19 | } 20 | 21 | function consoleCacheDump() {} 22 | var editor = { 23 | getValue : function () { return levelString } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /src/tests/tests.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | QUnit Tests for Pattern:Script 6 | 7 | 8 | 9 |
10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | --------------------------------------------------------------------------------