├── .gitignore ├── LICENSE ├── README.md └── src └── gmtest ├── gmtest.yyp ├── objects ├── obj_an_object │ └── obj_an_object.yy └── obj_another_object │ └── obj_another_object.yy ├── options ├── linux │ ├── icon64.png │ ├── icons │ │ └── icon64.png │ ├── options_linux.yy │ ├── splash.png │ └── splash │ │ └── splash.png ├── mac │ ├── icon512.png │ ├── icons │ │ └── icon512.png │ ├── options_mac.yy │ ├── splash.png │ └── splash │ │ └── splash.png ├── main │ ├── inherited │ │ └── options_main.inherited.yy │ └── options_main.yy └── windows │ ├── License.txt │ ├── RunnerInstaller.nsi │ ├── Runner_Icon_256.ico │ ├── Runner_finish.bmp │ ├── Runner_header.bmp │ ├── installer │ ├── license.txt │ └── runnerinstaller.nsi │ ├── options_windows.yy │ ├── runner_icon.ico │ └── splash.png ├── rooms └── rm_test_asserts │ ├── RoomCreationCode.gml │ └── rm_test_asserts.yy ├── scripts ├── assert │ ├── assert.gml │ └── assert.yy ├── gmtest_methods │ ├── gmtest_methods.gml │ └── gmtest_methods.yy ├── test_asserts │ ├── test_asserts.gml │ └── test_asserts.yy └── test_main │ ├── test_main.gml │ └── test_main.yy └── sprites └── spr_box ├── 61b3ae8b-3460-4fd2-aaad-be502a046c2e.png ├── layers └── 61b3ae8b-3460-4fd2-aaad-be502a046c2e │ └── 8146f226-818c-4d31-a359-f372654c9847.png └── spr_box.yy /.gitignore: -------------------------------------------------------------------------------- 1 | *.yymp 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Michael Barrett 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | GMTest - Testing automation for GameMaker: Studio 2 | ======= 3 | 4 | Version 5.0.0 5 | 6 | ## Table of Contents 7 | 1. [Introduction](#introduction) 8 | 2. [Installation](#installation) 9 | 3. [Usage](#usage) 10 | 4. [API](#api) 11 | 5. [GM Core](#gm-core) 12 | 6. [License](#license) 13 | 14 | 15 | ## Introduction 16 | 17 | GMTest is a behavioral testing suite for GameMaker: Studio 2.3 and above. 18 | 19 | ## Installation 20 | 21 | Download the latest [gmtest.yymps from releases](https://github.com/gm-core/gmtest/releases) and import the package into your project. For detailed instructiosn, see [Installing .yymp Packages](https://gmcore.io/installing.html) on the GM Core website. 22 | 23 | ## Usage 24 | 25 | ### 1. Define some tests 26 | 27 | In a script function or in an object create script, define a test suite using `test_describe`. This function will contain all of the tests related to a single subject. Let's write tests for a function called `hurt_player` which takes an amount of damage to apply to the player. Begin by defining the test suite. In this case, we'll write our test in a script resource called `test_hurt_player`. 28 | 29 | ```GML 30 | function test_hurt_player() { 31 | test_describe('hurt_player', function() { 32 | // Tests will go here! 33 | }); 34 | } 35 | ``` 36 | 37 | 38 | ### 2. Write some tests 39 | 40 | Now we can write the actual tests. We will describe the behavior of our `hurt_player` function using the `test_it` function. The first parameter we provide is a string describing the expected behavior. It can be written like a statement - `test_it("subtracts health from the player"...`. Read it aloud! "It subtracts health from the player". 41 | 42 | The second parameter of `test_it` is a function to be run to test this behavior. We will call the `hurt_player` function and test that the `health` variable has been altered as we expect, using one of the `assert` methods provided by GM Test. We will get into "asserts" later, but for now, just know that `assert_equal` tests that two values are equal. 43 | 44 | So, our full script now looks like this: 45 | 46 | 47 | ```GML 48 | function test_hurt_player() { 49 | test_describe('hurt_player', function() { 50 | 51 | test_it("subtracts health from the player", function() { 52 | health = 100; 53 | hurt_player(10); 54 | assert_equal(health, 90); 55 | }); 56 | 57 | }); 58 | } 59 | ``` 60 | 61 | Lookin' good. You can have as many `test_it` calls as you want inside of a `test_describe`, and you can have as many `test_describe` calls as you want as well. In general, you should use a new `test_describe` for each new component you want to test, and a `test_it` for each behavior of the component you are testing. 62 | 63 | ### 3. Run your tests 64 | 65 | We've got the test written but now we need to run it. Create an empty room, or a new Object, and in the creation code for either the room or the object, we will write just a few lines of code to run our tests. Reminder: if you are doing this in an object, be sure to place the object in the first room in your game so the code runs! 66 | 67 | We just need to call the function that contains our test code to set up the test, then run the tests with `test_run_all()`. 68 | 69 | ``` 70 | // Register our test 71 | test_hurt_player(); 72 | 73 | // Run the tests! 74 | test_run_all(); 75 | ``` 76 | 77 | Now, run your project. In the debug console output, you will see the results of your test: 78 | 79 | ``` 80 | hurt_player 81 | |- It subtracts health from the player 82 | 83 | [1/1] Test exeuction end 84 | 85 | ----------- 86 | All tests passing! 87 | ``` 88 | 89 | We've got a passing test! Great! If you've got the feel for things, check out the API docs below. 90 | 91 | If you want some more deeper examples, check out the docs on the [GMTest website @ GM Core](https://gmcore.io/gmtest) 92 | 93 | 94 | ## API 95 | 96 | ### Test Management 97 | 98 | #### `test_describe(suiteName, suiteMethod)` 99 | 100 | Wraps a suite of tests 101 | 102 | ```gml 103 | @param {string} testName The name of the test suite 104 | @param {method} testSuiteMethod A method containing the individual tests 105 | 106 | test_describe("hurt_player", function() { 107 | // ... 108 | }); 109 | ``` 110 | 111 | #### `test_it(description, testMethod)` 112 | 113 | Defines an individual test. 114 | 115 | ```gml 116 | @param {string} description The description of the functionality being tested 117 | @param {method} testMethod A method containing the test 118 | 119 | test_it("subtracts from the health variable", function() { 120 | // ... 121 | }); 122 | ``` 123 | 124 | #### `test_before(beforeMethod)` 125 | 126 | Defines a setup function for a suite of tests. This function is run once before the any tests in the test suite runs. 127 | 128 | ```gml 129 | @param {method} setupMethod A method containing the setup for a test suite 130 | 131 | test_before(function() { 132 | health = 100; 133 | }); 134 | ``` 135 | 136 | #### `test_before_each(beforeEachMethod)` 137 | 138 | Defines a setup function for each test in a suite. This function is before each test defined in a suite. 139 | 140 | ```gml 141 | @param {method} setupMethod A method containing the setup for eachtest in a suite. 142 | 143 | test_beforeEach(function() { 144 | health = 100; 145 | }); 146 | ``` 147 | 148 | #### `test_after(afterMethod)` 149 | 150 | Defines a cleanup function for a suite of tests. This function is run once after all tests in the suite have finished. 151 | 152 | ```gml 153 | @param {method} cleanupMethod A method containing the cleanup for a test suite 154 | 155 | test_after(function() { 156 | score = 0; 157 | }); 158 | ``` 159 | 160 | #### `test_after_each(afterMethod)` 161 | 162 | Defines a cleanup function for each test in a suite of tests. 163 | 164 | ```gml 165 | @param {method} cleanupMethod A method containing the cleanup for a test suite 166 | 167 | test_after_each(function() { 168 | score = 0; 169 | }); 170 | ``` 171 | 172 | #### `test_run_all(optionalAutoEnd)` 173 | 174 | Runs every test that has been defined within a `test_describe` before calling. 175 | 176 | ```gml 177 | @param autoEnd {boolean} If GM Test should close the game upon completion of the tests. Defaults to false. 178 | 179 | test_run_all(true); 180 | ``` 181 | 182 | ### Assert Types 183 | 184 | All assertions can optionally take a custom error message as a third argument. 185 | 186 | #### `assert(value, [, customMessage])` 187 | 188 | Ensures that the given `value` is true (convenience for `assert_is_true`). 189 | 190 | #### `assert_equal(value, expectedValue [, customMessage])` 191 | 192 | Ensures that the given `value` is equal to `expectedValue`. 193 | 194 | #### `assert_not_equal(value, unexpectedValue [, customMessage])` 195 | 196 | Ensures that the given `value` is NOT equal to `unexpectedValue`. 197 | 198 | #### `assert_exists(object [, customMessage])` 199 | 200 | Ensures that an instance of `object` exists in the room. 201 | 202 | #### `assert_does_not_exist(object [, customMessage])` 203 | 204 | Ensures that an instance of `object` does not exist in the room. 205 | 206 | #### `assert_is_true(value [, customMessage])` 207 | 208 | Ensures the given `value` is `true`. 209 | 210 | #### `assert_is_false(value [, customMessage])` 211 | 212 | Ensures the given `value` is `false`. 213 | 214 | #### `assert_is_undefined(value [, customMessage])` 215 | 216 | Ensures the given `value` passes `is_undefined()`. 217 | 218 | #### `assert_throws(function [, expectedErrorMessage])` 219 | 220 | Ensures the given function throws an error message. Optionally specify `expectedErrorMessage` to validate the error message. 221 | 222 | ```gml 223 | assert_throws(function() { 224 | throw "test"; 225 | }, "test"); 226 | ``` 227 | 228 | ## GM Core 229 | 230 | GMTest is a part of the [GM Core](https://github.com/gm-core) project. 231 | 232 | ## License 233 | 234 | Copyright (c) 2017 Michael Barrett 235 | 236 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 237 | 238 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 239 | 240 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 241 | -------------------------------------------------------------------------------- /src/gmtest/gmtest.yyp: -------------------------------------------------------------------------------- 1 | { 2 | "resources": [ 3 | {"id":{"name":"test_main","path":"scripts/test_main/test_main.yy",},"order":1,}, 4 | {"id":{"name":"spr_box","path":"sprites/spr_box/spr_box.yy",},"order":0,}, 5 | {"id":{"name":"test_asserts","path":"scripts/test_asserts/test_asserts.yy",},"order":0,}, 6 | {"id":{"name":"assert","path":"scripts/assert/assert.yy",},"order":3,}, 7 | {"id":{"name":"obj_an_object","path":"objects/obj_an_object/obj_an_object.yy",},"order":2,}, 8 | {"id":{"name":"gmtest_methods","path":"scripts/gmtest_methods/gmtest_methods.yy",},"order":4,}, 9 | {"id":{"name":"obj_another_object","path":"objects/obj_another_object/obj_another_object.yy",},"order":1,}, 10 | {"id":{"name":"rm_test_asserts","path":"rooms/rm_test_asserts/rm_test_asserts.yy",},"order":0,}, 11 | ], 12 | "Options": [ 13 | {"name":"Linux","path":"options/linux/options_linux.yy",}, 14 | {"name":"Windows","path":"options/windows/options_windows.yy",}, 15 | {"name":"macOS","path":"options/mac/options_mac.yy",}, 16 | {"name":"Main","path":"options/main/options_main.yy",}, 17 | ], 18 | "isDnDProject": false, 19 | "isEcma": false, 20 | "tutorialPath": "", 21 | "configs": { 22 | "name": "Default", 23 | "children": [], 24 | }, 25 | "RoomOrder": [ 26 | {"name":"rm_test_asserts","path":"rooms/rm_test_asserts/rm_test_asserts.yy",}, 27 | ], 28 | "Folders": [ 29 | {"folderPath":"folders/Sprites.yy","order":0,"resourceVersion":"1.0","name":"Sprites","tags":[],"resourceType":"GMFolder",}, 30 | {"folderPath":"folders/Tile Sets.yy","order":3,"resourceVersion":"1.0","name":"Tile Sets","tags":[],"resourceType":"GMFolder",}, 31 | {"folderPath":"folders/Sounds.yy","order":4,"resourceVersion":"1.0","name":"Sounds","tags":[],"resourceType":"GMFolder",}, 32 | {"folderPath":"folders/Paths.yy","order":5,"resourceVersion":"1.0","name":"Paths","tags":[],"resourceType":"GMFolder",}, 33 | {"folderPath":"folders/Scripts.yy","order":6,"resourceVersion":"1.0","name":"Scripts","tags":[],"resourceType":"GMFolder",}, 34 | {"folderPath":"folders/Scripts/gmtest.yy","order":0,"resourceVersion":"1.0","name":"gmtest","tags":[],"resourceType":"GMFolder",}, 35 | {"folderPath":"folders/Shaders.yy","order":7,"resourceVersion":"1.0","name":"Shaders","tags":[],"resourceType":"GMFolder",}, 36 | {"folderPath":"folders/Fonts.yy","order":8,"resourceVersion":"1.0","name":"Fonts","tags":[],"resourceType":"GMFolder",}, 37 | {"folderPath":"folders/Timelines.yy","order":9,"resourceVersion":"1.0","name":"Timelines","tags":[],"resourceType":"GMFolder",}, 38 | {"folderPath":"folders/Objects.yy","order":10,"resourceVersion":"1.0","name":"Objects","tags":[],"resourceType":"GMFolder",}, 39 | {"folderPath":"folders/Rooms.yy","order":11,"resourceVersion":"1.0","name":"Rooms","tags":[],"resourceType":"GMFolder",}, 40 | {"folderPath":"folders/Notes.yy","order":12,"resourceVersion":"1.0","name":"Notes","tags":[],"resourceType":"GMFolder",}, 41 | {"folderPath":"folders/Extensions.yy","order":13,"resourceVersion":"1.0","name":"Extensions","tags":[],"resourceType":"GMFolder",}, 42 | {"folderPath":"folders/Sequences.yy","order":1,"resourceVersion":"1.0","name":"Sequences","tags":[],"resourceType":"GMFolder",}, 43 | {"folderPath":"folders/Animation Curves.yy","order":2,"resourceVersion":"1.0","name":"Animation Curves","tags":[],"resourceType":"GMFolder",}, 44 | {"folderPath":"folders/Scripts/tests.yy","order":1,"resourceVersion":"1.0","name":"tests","tags":[],"resourceType":"GMFolder",}, 45 | ], 46 | "AudioGroups": [ 47 | {"targets":461609314234257646,"resourceVersion":"1.0","name":"audiogroup_default","resourceType":"GMAudioGroup",}, 48 | ], 49 | "TextureGroups": [ 50 | {"isScaled":false,"autocrop":false,"border":2,"mipsToGenerate":0,"targets":461609314234257646,"resourceVersion":"1.0","name":"Default","resourceType":"GMTextureGroup",}, 51 | ], 52 | "IncludedFiles": [], 53 | "MetaData": { 54 | "IDEVersion": "2.3.0.529", 55 | }, 56 | "resourceVersion": "1.3", 57 | "name": "gmtest", 58 | "tags": [], 59 | "resourceType": "GMProject", 60 | } -------------------------------------------------------------------------------- /src/gmtest/objects/obj_an_object/obj_an_object.yy: -------------------------------------------------------------------------------- 1 | { 2 | "spriteId": null, 3 | "solid": false, 4 | "visible": true, 5 | "spriteMaskId": null, 6 | "persistent": false, 7 | "parentObjectId": null, 8 | "physicsObject": false, 9 | "physicsSensor": false, 10 | "physicsShape": 1, 11 | "physicsGroup": 1, 12 | "physicsDensity": 0.5, 13 | "physicsRestitution": 0.1, 14 | "physicsLinearDamping": 0.1, 15 | "physicsAngularDamping": 0.1, 16 | "physicsFriction": 0.2, 17 | "physicsStartAwake": true, 18 | "physicsKinematic": false, 19 | "physicsShapePoints": [], 20 | "eventList": [], 21 | "properties": [], 22 | "overriddenProperties": [], 23 | "parent": { 24 | "name": "Objects", 25 | "path": "folders/Objects.yy", 26 | }, 27 | "resourceVersion": "1.0", 28 | "name": "obj_an_object", 29 | "tags": [], 30 | "resourceType": "GMObject", 31 | } -------------------------------------------------------------------------------- /src/gmtest/objects/obj_another_object/obj_another_object.yy: -------------------------------------------------------------------------------- 1 | { 2 | "spriteId": null, 3 | "solid": false, 4 | "visible": true, 5 | "spriteMaskId": null, 6 | "persistent": false, 7 | "parentObjectId": null, 8 | "physicsObject": false, 9 | "physicsSensor": false, 10 | "physicsShape": 0, 11 | "physicsGroup": 0, 12 | "physicsDensity": 0.5, 13 | "physicsRestitution": 0.1, 14 | "physicsLinearDamping": 0.1, 15 | "physicsAngularDamping": 0.1, 16 | "physicsFriction": 0.2, 17 | "physicsStartAwake": true, 18 | "physicsKinematic": false, 19 | "physicsShapePoints": [], 20 | "eventList": [], 21 | "properties": [], 22 | "overriddenProperties": [], 23 | "parent": { 24 | "name": "Objects", 25 | "path": "folders/Objects.yy", 26 | }, 27 | "resourceVersion": "1.0", 28 | "name": "obj_another_object", 29 | "tags": [], 30 | "resourceType": "GMObject", 31 | } -------------------------------------------------------------------------------- /src/gmtest/options/linux/icon64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gm-core/GMTest/29027a96973476cd6486494d44ce2b9719d3304b/src/gmtest/options/linux/icon64.png -------------------------------------------------------------------------------- /src/gmtest/options/linux/icons/icon64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gm-core/GMTest/29027a96973476cd6486494d44ce2b9719d3304b/src/gmtest/options/linux/icons/icon64.png -------------------------------------------------------------------------------- /src/gmtest/options/linux/options_linux.yy: -------------------------------------------------------------------------------- 1 | { 2 | "option_linux_display_name": "GameMaker-Testing-Automation", 3 | "option_linux_version": "1.0.0.0", 4 | "option_linux_maintainer_email": "", 5 | "option_linux_homepage": "http://www.GameMaker-Testing-Automation.com", 6 | "option_linux_short_desc": "GameMaker-Testing-Automation", 7 | "option_linux_long_desc": "GameMaker-Testing-Automation", 8 | "option_linux_splash_screen": "${options_dir}\\linux\\splash\\splash.png", 9 | "option_linux_display_splash": false, 10 | "option_linux_icon": "${options_dir}\\linux\\icons\\icon64.png", 11 | "option_linux_start_fullscreen": false, 12 | "option_linux_allow_fullscreen": true, 13 | "option_linux_interpolate_pixels": false, 14 | "option_linux_display_cursor": false, 15 | "option_linux_sync": false, 16 | "option_linux_resize_window": false, 17 | "option_linux_scale": 0, 18 | "option_linux_texture_page": "2048x2048", 19 | "option_linux_enable_steam": false, 20 | "option_linux_disable_sandbox": false, 21 | "resourceVersion": "1.0", 22 | "name": "Linux", 23 | "tags": [], 24 | "resourceType": "GMLinuxOptions", 25 | } -------------------------------------------------------------------------------- /src/gmtest/options/linux/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gm-core/GMTest/29027a96973476cd6486494d44ce2b9719d3304b/src/gmtest/options/linux/splash.png -------------------------------------------------------------------------------- /src/gmtest/options/linux/splash/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gm-core/GMTest/29027a96973476cd6486494d44ce2b9719d3304b/src/gmtest/options/linux/splash/splash.png -------------------------------------------------------------------------------- /src/gmtest/options/mac/icon512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gm-core/GMTest/29027a96973476cd6486494d44ce2b9719d3304b/src/gmtest/options/mac/icon512.png -------------------------------------------------------------------------------- /src/gmtest/options/mac/icons/icon512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gm-core/GMTest/29027a96973476cd6486494d44ce2b9719d3304b/src/gmtest/options/mac/icons/icon512.png -------------------------------------------------------------------------------- /src/gmtest/options/mac/options_mac.yy: -------------------------------------------------------------------------------- 1 | { 2 | "option_mac_display_name": "GameMaker-Testing-Automation", 3 | "option_mac_app_id": "", 4 | "option_mac_version": "1.0.0.0", 5 | "option_mac_output_dir": "~/GameMaker-Studio/GameMaker-Testing-Automation", 6 | "option_mac_team_id": null, 7 | "option_mac_signing_identity": "Developer ID Application:", 8 | "option_mac_copyright": "(c)2012 CompanyName Ltd...", 9 | "option_mac_splash_png": "${options_dir}\\mac\\splash\\splash.png", 10 | "option_mac_icon_png": "${options_dir}\\mac\\icons\\icon512.png", 11 | "option_mac_menu_dock": false, 12 | "option_mac_display_cursor": true, 13 | "option_mac_start_fullscreen": false, 14 | "option_mac_allow_fullscreen": true, 15 | "option_mac_interpolate_pixels": false, 16 | "option_mac_vsync": false, 17 | "option_mac_resize_window": false, 18 | "option_mac_enable_retina": false, 19 | "option_mac_scale": 0, 20 | "option_mac_texture_page": "2048x2048", 21 | "option_mac_build_app_store": true, 22 | "option_mac_allow_incoming_network": false, 23 | "option_mac_allow_outgoing_network": false, 24 | "option_mac_app_category": "Games", 25 | "option_mac_enable_steam": false, 26 | "option_mac_disable_sandbox": false, 27 | "option_mac_apple_sign_in": false, 28 | "resourceVersion": "1.0", 29 | "name": "macOS", 30 | "tags": [], 31 | "resourceType": "GMMacOptions", 32 | } -------------------------------------------------------------------------------- /src/gmtest/options/mac/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gm-core/GMTest/29027a96973476cd6486494d44ce2b9719d3304b/src/gmtest/options/mac/splash.png -------------------------------------------------------------------------------- /src/gmtest/options/mac/splash/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gm-core/GMTest/29027a96973476cd6486494d44ce2b9719d3304b/src/gmtest/options/mac/splash/splash.png -------------------------------------------------------------------------------- /src/gmtest/options/main/inherited/options_main.inherited.yy: -------------------------------------------------------------------------------- 1 | 1.0.0←ed6a955d-5826-4f98-a450-10b414266c27←ed6a955d-5826-4f98-a450-10b414266c27|{ 2 | "option_gameguid": "{2398388C-7700-45B0-8B68-409E3DD49408}", 3 | "option_steam_app_id": "0", 4 | "option_game_speed": 30 5 | }←1225f6b0-ac20-43bd-a82e-be73fa0b6f4f|{ 6 | "autocrop": false, 7 | "scaled": false, 8 | "targets": 461609314234257646 9 | }←7b2c4976-1e09-44e5-8256-c527145e03bb|{ 10 | "targets": 461609314234257646 11 | } -------------------------------------------------------------------------------- /src/gmtest/options/main/options_main.yy: -------------------------------------------------------------------------------- 1 | { 2 | "option_gameguid": "{2398388C-7700-45B0-8B68-409E3DD49408}", 3 | "option_game_speed": 30, 4 | "option_mips_for_3d_textures": false, 5 | "option_draw_colour": 4294967295, 6 | "option_window_colour": 255, 7 | "option_steam_app_id": "0", 8 | "option_sci_usesci": false, 9 | "option_author": "", 10 | "option_lastchanged": "", 11 | "option_spine_licence": false, 12 | "resourceVersion": "1.2", 13 | "name": "Main", 14 | "tags": [], 15 | "resourceType": "GMMainOptions", 16 | } -------------------------------------------------------------------------------- /src/gmtest/options/windows/License.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gm-core/GMTest/29027a96973476cd6486494d44ce2b9719d3304b/src/gmtest/options/windows/License.txt -------------------------------------------------------------------------------- /src/gmtest/options/windows/RunnerInstaller.nsi: -------------------------------------------------------------------------------- 1 | ; RunnerInstaller.nsi 2 | ; 3 | ; This script is based on example1.nsi, but it remember the directory, 4 | ; has uninstall support and (optionally) installs start menu shortcuts. 5 | ; 6 | ; It will install example2.nsi into a directory that the user selects, 7 | 8 | ;-------------------------------- 9 | !include MUI2.nsh 10 | 11 | !ifndef FULL_VERSION 12 | !define FULL_VERSION "1.0.0.0" 13 | !endif 14 | !ifndef SOURCE_DIR 15 | !define SOURCE_DIR "C:\source\temp\InstallerTest\runner" 16 | !endif 17 | !ifndef INSTALLER_FILENAME 18 | !define INSTALLER_FILENAME "C:\source\temp\InstallerTest\RunnerInstaller.exe" 19 | !endif 20 | 21 | !ifndef MAKENSIS 22 | !define MAKENSIS "%appdata%\GameMaker-Studio\makensis" 23 | !endif 24 | 25 | !ifndef COMPANY_NAME 26 | !define COMPANY_NAME "" 27 | !endif 28 | 29 | !ifndef COPYRIGHT_TXT 30 | !define COPYRIGHT_TXT "(c)Copyright 2013" 31 | !endif 32 | 33 | !ifndef FILE_DESC 34 | !define FILE_DESC "Created with GameMaker:Studio" 35 | !endif 36 | 37 | !ifndef LICENSE_NAME 38 | !define LICENSE_NAME "License.txt" 39 | !endif 40 | 41 | !ifndef ICON_FILE 42 | !define ICON_FILE "icon.ico" 43 | !endif 44 | 45 | !ifndef IMAGE_FINISHED 46 | !define IMAGE_FINISHED "Runner_finish.bmp" 47 | !endif 48 | 49 | !ifndef IMAGE_HEADER 50 | !define IMAGE_HEADER "Runner_header.bmp" 51 | !endif 52 | 53 | !ifndef PRODUCT_NAME 54 | !define PRODUCT_NAME "Runner" 55 | !endif 56 | 57 | !define APP_NAME "${PRODUCT_NAME}" 58 | !define SHORT_NAME "${PRODUCT_NAME}" 59 | 60 | ;;USAGE: 61 | !define MIN_FRA_MAJOR "2" 62 | !define MIN_FRA_MINOR "0" 63 | !define MIN_FRA_BUILD "*" 64 | 65 | !addplugindir "." 66 | 67 | ;-------------------------------- 68 | 69 | ; The name of the installer 70 | Name "${APP_NAME}" 71 | Caption "${APP_NAME}" 72 | BrandingText "${APP_NAME}" 73 | 74 | ; The file to write 75 | OutFile "${INSTALLER_FILENAME}" 76 | 77 | ; The default installation directory 78 | InstallDir "$PROFILE\${APP_NAME}" 79 | 80 | ; Registry key to check for directory (so if you install again, it will 81 | ; overwrite the old one automatically) 82 | InstallDirRegKey HKCU "Software\Runner" "Install_Dir" 83 | 84 | ; Request application privileges for Windows Vista 85 | RequestExecutionLevel user 86 | 87 | 88 | VIProductVersion "${FULL_VERSION}" 89 | VIAddVersionKey /LANG=1033 "FileVersion" "${FULL_VERSION}" 90 | VIAddVersionKey /LANG=1033 "ProductVersion" "${FULL_VERSION}" 91 | VIAddVersionKey /LANG=1033 "ProductName" "${PRODUCT_NAME}" 92 | VIAddVersionKey /LANG=1033 "CompanyName" "${PRODUCT_PUBLISHER}" 93 | VIAddVersionKey /LANG=1033 "LegalCopyright" "${COPYRIGHT_TXT}" 94 | VIAddVersionKey /LANG=1033 "FileDescription" "${FILE_DESC}" 95 | 96 | 97 | 98 | !define MUI_HEADERIMAGE 99 | !define MUI_HEADERIMAGE_BITMAP_NOSTRETCH 100 | !define MUI_ICON "${ICON_FILE}" 101 | !define MUI_WELCOMEFINISHPAGE_BITMAP "${IMAGE_FINISHED}" 102 | !define MUI_HEADERIMAGE_BITMAP "${IMAGE_HEADER}" 103 | !define MUI_WELCOMEFINISHPAGE_BITMAP_NOSTRETCH 104 | 105 | 106 | ;-------------------------------- 107 | 108 | ; Pages 109 | !insertmacro MUI_PAGE_LICENSE "${LICENSE_NAME}" 110 | !insertmacro MUI_PAGE_COMPONENTS 111 | !insertmacro MUI_PAGE_DIRECTORY 112 | !insertmacro MUI_PAGE_INSTFILES 113 | # These indented statements modify settings for MUI_PAGE_FINISH 114 | !define MUI_FINISHPAGE_NOAUTOCLOSE 115 | !define MUI_FINISHPAGE_RUN_TEXT "Start ${PRODUCT_NAME}" 116 | !define MUI_FINISHPAGE_RUN "$INSTDIR\${PRODUCT_NAME}.exe" 117 | !insertmacro MUI_PAGE_FINISH 118 | 119 | Var DirectXSetupError 120 | 121 | UninstPage uninstConfirm 122 | UninstPage instfiles 123 | 124 | !insertmacro MUI_LANGUAGE "English" 125 | ;-------------------------------- 126 | 127 | ; The stuff to install 128 | Section `${APP_NAME}` 129 | SectionIn RO 130 | 131 | ; Set output path to the installation directory. 132 | SetOutPath $INSTDIR 133 | 134 | ; Put file there 135 | File "${LICENSE_NAME}" 136 | File /r "${SOURCE_DIR}\*.*" 137 | 138 | ; Write the uninstall keys for Windows 139 | WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${SHORT_NAME}" "DisplayName" "${APP_NAME}" 140 | WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${SHORT_NAME}" "UninstallString" '"$INSTDIR\uninstall.exe"' 141 | WriteRegDWORD SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${SHORT_NAME}" "NoModify" 1 142 | WriteRegDWORD SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${SHORT_NAME}" "NoRepair" 1 143 | WriteUninstaller "uninstall.exe" 144 | 145 | SectionEnd 146 | 147 | ; Optional section (can be disabled by the user) 148 | Section "Start Menu Shortcuts" 149 | 150 | CreateDirectory "$SMPROGRAMS\${APP_NAME}" 151 | CreateShortCut "$SMPROGRAMS\${APP_NAME}\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0 152 | CreateShortCut "$SMPROGRAMS\${APP_NAME}\${APP_NAME}.lnk" "$INSTDIR\${PRODUCT_NAME}.exe" "" "$INSTDIR\${PRODUCT_NAME}.exe" 153 | CreateShortCut "$SMPROGRAMS\${APP_NAME}\${APP_NAME} License.lnk" "notepad.exe" "$INSTDIR\License.txt" 154 | 155 | SectionEnd 156 | 157 | 158 | ; Optional section (can be enabled by the user) 159 | Section /o "Desktop shortcut" 160 | 161 | CreateShortCut "$DESKTOP\${APP_NAME}.lnk" "$INSTDIR\${PRODUCT_NAME}.exe" "" 162 | 163 | SectionEnd 164 | 165 | 166 | ;-------------------------------- 167 | 168 | ; Uninstaller 169 | 170 | Section "Uninstall" 171 | ; Remove registry keys 172 | DeleteRegKey SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${SHORT_NAME}" 173 | 174 | ; Remove files and uninstaller (everything) 175 | RMDir /r "$INSTDIR" 176 | 177 | ; Remove desktop icon 178 | Delete "$DESKTOP\${APP_NAME}.lnk" 179 | 180 | ; Remove shortcuts, if any 181 | Delete "$SMPROGRAMS\${APP_NAME}\*.*" 182 | 183 | ; Remove directories used 184 | RMDir "$SMPROGRAMS\${APP_NAME}" 185 | RMDir "$INSTDIR" 186 | 187 | SectionEnd 188 | 189 | 190 | ;-------------------------------- 191 | ; 192 | ; This should be the LAST section available.... 193 | ; 194 | Section "DirectX Install" SEC_DIRECTX 195 | 196 | SectionIn RO 197 | 198 | SetOutPath "$TEMP" 199 | File "${MAKENSIS}\dxwebsetup.exe" 200 | DetailPrint "Running DirectX Setup..." 201 | ExecWait '"$TEMP\dxwebsetup.exe" /Q' $DirectXSetupError 202 | DetailPrint "Finished DirectX Setup" 203 | 204 | Delete "$TEMP\dxwebsetup.exe" 205 | 206 | SetOutPath "$INSTDIR" 207 | 208 | SectionEnd 209 | -------------------------------------------------------------------------------- /src/gmtest/options/windows/Runner_Icon_256.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gm-core/GMTest/29027a96973476cd6486494d44ce2b9719d3304b/src/gmtest/options/windows/Runner_Icon_256.ico -------------------------------------------------------------------------------- /src/gmtest/options/windows/Runner_finish.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gm-core/GMTest/29027a96973476cd6486494d44ce2b9719d3304b/src/gmtest/options/windows/Runner_finish.bmp -------------------------------------------------------------------------------- /src/gmtest/options/windows/Runner_header.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gm-core/GMTest/29027a96973476cd6486494d44ce2b9719d3304b/src/gmtest/options/windows/Runner_header.bmp -------------------------------------------------------------------------------- /src/gmtest/options/windows/installer/license.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gm-core/GMTest/29027a96973476cd6486494d44ce2b9719d3304b/src/gmtest/options/windows/installer/license.txt -------------------------------------------------------------------------------- /src/gmtest/options/windows/installer/runnerinstaller.nsi: -------------------------------------------------------------------------------- 1 | ; RunnerInstaller.nsi 2 | ; 3 | ; This script is based on example1.nsi, but it remember the directory, 4 | ; has uninstall support and (optionally) installs start menu shortcuts. 5 | ; 6 | ; It will install example2.nsi into a directory that the user selects, 7 | 8 | ;-------------------------------- 9 | !include MUI2.nsh 10 | 11 | !ifndef FULL_VERSION 12 | !define FULL_VERSION "1.0.0.0" 13 | !endif 14 | !ifndef SOURCE_DIR 15 | !define SOURCE_DIR "C:\source\temp\InstallerTest\runner" 16 | !endif 17 | !ifndef INSTALLER_FILENAME 18 | !define INSTALLER_FILENAME "C:\source\temp\InstallerTest\RunnerInstaller.exe" 19 | !endif 20 | 21 | !ifndef MAKENSIS 22 | !define MAKENSIS "%appdata%\GameMaker-Studio\makensis" 23 | !endif 24 | 25 | !ifndef COMPANY_NAME 26 | !define COMPANY_NAME "" 27 | !endif 28 | 29 | !ifndef COPYRIGHT_TXT 30 | !define COPYRIGHT_TXT "(c)Copyright 2013" 31 | !endif 32 | 33 | !ifndef FILE_DESC 34 | !define FILE_DESC "Created with GameMaker:Studio" 35 | !endif 36 | 37 | !ifndef LICENSE_NAME 38 | !define LICENSE_NAME "License.txt" 39 | !endif 40 | 41 | !ifndef ICON_FILE 42 | !define ICON_FILE "icon.ico" 43 | !endif 44 | 45 | !ifndef IMAGE_FINISHED 46 | !define IMAGE_FINISHED "Runner_finish.bmp" 47 | !endif 48 | 49 | !ifndef IMAGE_HEADER 50 | !define IMAGE_HEADER "Runner_header.bmp" 51 | !endif 52 | 53 | !ifndef PRODUCT_NAME 54 | !define PRODUCT_NAME "Runner" 55 | !endif 56 | 57 | !define APP_NAME "${PRODUCT_NAME}" 58 | !define SHORT_NAME "${PRODUCT_NAME}" 59 | 60 | ;;USAGE: 61 | !define MIN_FRA_MAJOR "2" 62 | !define MIN_FRA_MINOR "0" 63 | !define MIN_FRA_BUILD "*" 64 | 65 | !addplugindir "." 66 | 67 | ;-------------------------------- 68 | 69 | ; The name of the installer 70 | Name "${APP_NAME}" 71 | Caption "${APP_NAME}" 72 | BrandingText "${APP_NAME}" 73 | 74 | ; The file to write 75 | OutFile "${INSTALLER_FILENAME}" 76 | 77 | ; The default installation directory 78 | InstallDir "$PROFILE\${APP_NAME}" 79 | 80 | ; Registry key to check for directory (so if you install again, it will 81 | ; overwrite the old one automatically) 82 | InstallDirRegKey HKCU "Software\Runner" "Install_Dir" 83 | 84 | ; Request application privileges for Windows Vista 85 | RequestExecutionLevel user 86 | 87 | 88 | VIProductVersion "${FULL_VERSION}" 89 | VIAddVersionKey /LANG=1033 "FileVersion" "${FULL_VERSION}" 90 | VIAddVersionKey /LANG=1033 "ProductVersion" "${FULL_VERSION}" 91 | VIAddVersionKey /LANG=1033 "ProductName" "${PRODUCT_NAME}" 92 | VIAddVersionKey /LANG=1033 "CompanyName" "${PRODUCT_PUBLISHER}" 93 | VIAddVersionKey /LANG=1033 "LegalCopyright" "${COPYRIGHT_TXT}" 94 | VIAddVersionKey /LANG=1033 "FileDescription" "${FILE_DESC}" 95 | 96 | 97 | 98 | !define MUI_HEADERIMAGE 99 | !define MUI_HEADERIMAGE_BITMAP_NOSTRETCH 100 | !define MUI_ICON "${ICON_FILE}" 101 | !define MUI_WELCOMEFINISHPAGE_BITMAP "${IMAGE_FINISHED}" 102 | !define MUI_HEADERIMAGE_BITMAP "${IMAGE_HEADER}" 103 | !define MUI_WELCOMEFINISHPAGE_BITMAP_NOSTRETCH 104 | 105 | 106 | ;-------------------------------- 107 | 108 | ; Pages 109 | !insertmacro MUI_PAGE_LICENSE "${LICENSE_NAME}" 110 | !insertmacro MUI_PAGE_COMPONENTS 111 | !insertmacro MUI_PAGE_DIRECTORY 112 | !insertmacro MUI_PAGE_INSTFILES 113 | # These indented statements modify settings for MUI_PAGE_FINISH 114 | !define MUI_FINISHPAGE_NOAUTOCLOSE 115 | !define MUI_FINISHPAGE_RUN_TEXT "Start ${PRODUCT_NAME}" 116 | !define MUI_FINISHPAGE_RUN "$INSTDIR\${PRODUCT_NAME}.exe" 117 | !insertmacro MUI_PAGE_FINISH 118 | 119 | Var DirectXSetupError 120 | 121 | UninstPage uninstConfirm 122 | UninstPage instfiles 123 | 124 | !insertmacro MUI_LANGUAGE "English" 125 | ;-------------------------------- 126 | 127 | ; The stuff to install 128 | Section `${APP_NAME}` 129 | SectionIn RO 130 | 131 | ; Set output path to the installation directory. 132 | SetOutPath $INSTDIR 133 | 134 | ; Put file there 135 | File "${LICENSE_NAME}" 136 | File /r "${SOURCE_DIR}\*.*" 137 | 138 | ; Write the uninstall keys for Windows 139 | WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${SHORT_NAME}" "DisplayName" "${APP_NAME}" 140 | WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${SHORT_NAME}" "UninstallString" '"$INSTDIR\uninstall.exe"' 141 | WriteRegDWORD SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${SHORT_NAME}" "NoModify" 1 142 | WriteRegDWORD SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${SHORT_NAME}" "NoRepair" 1 143 | WriteUninstaller "uninstall.exe" 144 | 145 | SectionEnd 146 | 147 | ; Optional section (can be disabled by the user) 148 | Section "Start Menu Shortcuts" 149 | 150 | CreateDirectory "$SMPROGRAMS\${APP_NAME}" 151 | CreateShortCut "$SMPROGRAMS\${APP_NAME}\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0 152 | CreateShortCut "$SMPROGRAMS\${APP_NAME}\${APP_NAME}.lnk" "$INSTDIR\${PRODUCT_NAME}.exe" "" "$INSTDIR\${PRODUCT_NAME}.exe" 153 | CreateShortCut "$SMPROGRAMS\${APP_NAME}\${APP_NAME} License.lnk" "notepad.exe" "$INSTDIR\License.txt" 154 | 155 | SectionEnd 156 | 157 | 158 | ; Optional section (can be enabled by the user) 159 | Section /o "Desktop shortcut" 160 | 161 | CreateShortCut "$DESKTOP\${APP_NAME}.lnk" "$INSTDIR\${PRODUCT_NAME}.exe" "" 162 | 163 | SectionEnd 164 | 165 | 166 | ;-------------------------------- 167 | 168 | ; Uninstaller 169 | 170 | Section "Uninstall" 171 | ; Remove registry keys 172 | DeleteRegKey SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${SHORT_NAME}" 173 | 174 | ; Remove files and uninstaller (everything) 175 | RMDir /r "$INSTDIR" 176 | 177 | ; Remove desktop icon 178 | Delete "$DESKTOP\${APP_NAME}.lnk" 179 | 180 | ; Remove shortcuts, if any 181 | Delete "$SMPROGRAMS\${APP_NAME}\*.*" 182 | 183 | ; Remove directories used 184 | RMDir "$SMPROGRAMS\${APP_NAME}" 185 | RMDir "$INSTDIR" 186 | 187 | SectionEnd 188 | 189 | 190 | ;-------------------------------- 191 | ; 192 | ; This should be the LAST section available.... 193 | ; 194 | Section "DirectX Install" SEC_DIRECTX 195 | 196 | SectionIn RO 197 | 198 | SetOutPath "$TEMP" 199 | File "${MAKENSIS}\dxwebsetup.exe" 200 | DetailPrint "Running DirectX Setup..." 201 | ExecWait '"$TEMP\dxwebsetup.exe" /Q' $DirectXSetupError 202 | DetailPrint "Finished DirectX Setup" 203 | 204 | Delete "$TEMP\dxwebsetup.exe" 205 | 206 | SetOutPath "$INSTDIR" 207 | 208 | SectionEnd 209 | -------------------------------------------------------------------------------- /src/gmtest/options/windows/options_windows.yy: -------------------------------------------------------------------------------- 1 | { 2 | "option_windows_display_name": "GameMaker: Studio", 3 | "option_windows_executable_name": "${project_name}", 4 | "option_windows_version": "1.0.0.0", 5 | "option_windows_company_info": "", 6 | "option_windows_product_info": "", 7 | "option_windows_copyright_info": "", 8 | "option_windows_description_info": "A GameMaker:Studio Game", 9 | "option_windows_display_cursor": true, 10 | "option_windows_icon": "${options_dir}\\windows\\runner_icon.ico", 11 | "option_windows_save_location": 0, 12 | "option_windows_splash_screen": "${options_dir}\\windows\\splash.png", 13 | "option_windows_use_splash": true, 14 | "option_windows_start_fullscreen": false, 15 | "option_windows_allow_fullscreen_switching": true, 16 | "option_windows_interpolate_pixels": true, 17 | "option_windows_vsync": false, 18 | "option_windows_resize_window": false, 19 | "option_windows_borderless": false, 20 | "option_windows_scale": 0, 21 | "option_windows_copy_exe_to_dest": false, 22 | "option_windows_sleep_margin": 1, 23 | "option_windows_texture_page": "2048x2048", 24 | "option_windows_installer_finished": "${options_dir}\\windows\\Runner_finish.bmp", 25 | "option_windows_installer_header": "${options_dir}\\windows\\Runner_header.bmp", 26 | "option_windows_license": "${options_dir}\\windows\\installer\\license.txt", 27 | "option_windows_nsis_file": "${options_dir}\\windows\\installer\\runnerinstaller.nsi", 28 | "option_windows_enable_steam": false, 29 | "option_windows_disable_sandbox": false, 30 | "option_windows_steam_use_alternative_launcher": false, 31 | "resourceVersion": "1.0", 32 | "name": "Windows", 33 | "tags": [], 34 | "resourceType": "GMWindowsOptions", 35 | } -------------------------------------------------------------------------------- /src/gmtest/options/windows/runner_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gm-core/GMTest/29027a96973476cd6486494d44ce2b9719d3304b/src/gmtest/options/windows/runner_icon.ico -------------------------------------------------------------------------------- /src/gmtest/options/windows/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gm-core/GMTest/29027a96973476cd6486494d44ce2b9719d3304b/src/gmtest/options/windows/splash.png -------------------------------------------------------------------------------- /src/gmtest/rooms/rm_test_asserts/RoomCreationCode.gml: -------------------------------------------------------------------------------- 1 | test_main(); -------------------------------------------------------------------------------- /src/gmtest/rooms/rm_test_asserts/rm_test_asserts.yy: -------------------------------------------------------------------------------- 1 | { 2 | "isDnd": false, 3 | "volume": 1.0, 4 | "parentRoom": null, 5 | "views": [ 6 | {"inherit":false,"visible":false,"xview":0,"yview":0,"wview":1024,"hview":768,"xport":0,"yport":0,"wport":1024,"hport":768,"hborder":32,"vborder":32,"hspeed":-1,"vspeed":-1,"objectId":null,}, 7 | {"inherit":false,"visible":false,"xview":0,"yview":0,"wview":1024,"hview":768,"xport":0,"yport":0,"wport":1024,"hport":768,"hborder":32,"vborder":32,"hspeed":-1,"vspeed":-1,"objectId":null,}, 8 | {"inherit":false,"visible":false,"xview":0,"yview":0,"wview":1024,"hview":768,"xport":0,"yport":0,"wport":1024,"hport":768,"hborder":32,"vborder":32,"hspeed":-1,"vspeed":-1,"objectId":null,}, 9 | {"inherit":false,"visible":false,"xview":0,"yview":0,"wview":1024,"hview":768,"xport":0,"yport":0,"wport":1024,"hport":768,"hborder":32,"vborder":32,"hspeed":-1,"vspeed":-1,"objectId":null,}, 10 | {"inherit":false,"visible":false,"xview":0,"yview":0,"wview":1024,"hview":768,"xport":0,"yport":0,"wport":1024,"hport":768,"hborder":32,"vborder":32,"hspeed":-1,"vspeed":-1,"objectId":null,}, 11 | {"inherit":false,"visible":false,"xview":0,"yview":0,"wview":1024,"hview":768,"xport":0,"yport":0,"wport":1024,"hport":768,"hborder":32,"vborder":32,"hspeed":-1,"vspeed":-1,"objectId":null,}, 12 | {"inherit":false,"visible":false,"xview":0,"yview":0,"wview":1024,"hview":768,"xport":0,"yport":0,"wport":1024,"hport":768,"hborder":32,"vborder":32,"hspeed":-1,"vspeed":-1,"objectId":null,}, 13 | {"inherit":false,"visible":false,"xview":0,"yview":0,"wview":1024,"hview":768,"xport":0,"yport":0,"wport":1024,"hport":768,"hborder":32,"vborder":32,"hspeed":-1,"vspeed":-1,"objectId":null,}, 14 | ], 15 | "layers": [ 16 | {"instances":[],"visible":true,"depth":0,"userdefinedDepth":true,"inheritLayerDepth":false,"inheritLayerSettings":false,"gridX":32,"gridY":32,"layers":[],"hierarchyFrozen":false,"resourceVersion":"1.0","name":"Compatibility_Instances_Depth_0","tags":[],"resourceType":"GMRInstanceLayer",}, 17 | {"spriteId":null,"colour":4290822336,"x":0,"y":0,"htiled":false,"vtiled":false,"hspeed":0.0,"vspeed":0.0,"stretch":false,"animationFPS":15.0,"animationSpeedType":0,"userdefinedAnimFPS":false,"visible":true,"depth":2147483600,"userdefinedDepth":true,"inheritLayerDepth":false,"inheritLayerSettings":false,"gridX":32,"gridY":32,"layers":[],"hierarchyFrozen":false,"resourceVersion":"1.0","name":"Compatibility_Colour","tags":[],"resourceType":"GMRBackgroundLayer",}, 18 | ], 19 | "inheritLayers": false, 20 | "creationCodeFile": "${project_dir}/rooms/rm_test_asserts/RoomCreationCode.gml", 21 | "inheritCode": false, 22 | "instanceCreationOrder": [], 23 | "inheritCreationOrder": false, 24 | "sequenceId": null, 25 | "roomSettings": { 26 | "inheritRoomSettings": false, 27 | "Width": 1024, 28 | "Height": 768, 29 | "persistent": false, 30 | }, 31 | "viewSettings": { 32 | "inheritViewSettings": false, 33 | "enableViews": false, 34 | "clearViewBackground": true, 35 | "clearDisplayBuffer": true, 36 | }, 37 | "physicsSettings": { 38 | "inheritPhysicsSettings": false, 39 | "PhysicsWorld": false, 40 | "PhysicsWorldGravityX": 0.0, 41 | "PhysicsWorldGravityY": 10.0, 42 | "PhysicsWorldPixToMetres": 0.1, 43 | }, 44 | "parent": { 45 | "name": "Rooms", 46 | "path": "folders/Rooms.yy", 47 | }, 48 | "resourceVersion": "1.0", 49 | "name": "rm_test_asserts", 50 | "tags": [], 51 | "resourceType": "GMRoom", 52 | } -------------------------------------------------------------------------------- /src/gmtest/scripts/assert/assert.gml: -------------------------------------------------------------------------------- 1 | function _test_create_assert_error(argument0) { 2 | /* 3 | * Helper method for asserts to create standardized error 4 | * messages. Not meant for external use. 5 | */ 6 | throw ("ASSERTION ERROR: " + string(argument0)); 7 | } 8 | 9 | 10 | /// @desc Convenience method for assert_is_true 11 | /// @param Value 12 | /// @param OptionalMessage 13 | function assert() { 14 | if (argument_count > 1) { 15 | assert_is_true(argument[0], argument[1]); 16 | } else { 17 | assert_is_true(argument[0]); 18 | } 19 | } 20 | 21 | /// @desc Ensures the passed in object/instance does not exist in this room 22 | /// @param Object 23 | function assert_does_not_exist() { 24 | if (instance_exists(argument0)) { 25 | if (argument_count > 1) { 26 | msg = argument[1]; 27 | } else { 28 | msg = _test_create_assert_error(string(argument[0]) + " should not exist"); 29 | } 30 | 31 | throw (msg); 32 | } 33 | } 34 | 35 | /// @desc Ensures the passed values are equal 36 | /// @param TestValue 37 | /// @param ExpectedValue 38 | /// @param OptionalMessage 39 | function assert_equal() { 40 | if (argument[0] != argument[1]) { 41 | 42 | var msg; 43 | if (argument_count > 2) { 44 | msg = argument[2]; 45 | } else { 46 | msg = _test_create_assert_error(string(argument[0]) + " is not " + string(argument[1])); 47 | } 48 | throw (msg); 49 | } 50 | } 51 | 52 | /// @desc Ensures the passed in object/instance exists 53 | /// @param Object 54 | function assert_exists() { 55 | if (!instance_exists(argument0)) { 56 | var msg; 57 | 58 | if (argument_count > 1) { 59 | msg = argument[1]; 60 | } else { 61 | msg = _test_create_assert_error(string(argument[0]) + " has no instances"); 62 | } 63 | throw (msg); 64 | } 65 | } 66 | 67 | /// @desc Asserts that the passed in argument is false 68 | /// @param Value 69 | /// @param OptionalMessage 70 | function assert_is_false() { 71 | if (argument_count > 1) { 72 | assert_equal(argument[0], false, argument[1]); 73 | } else { 74 | assert_equal(argument[0], false); 75 | } 76 | } 77 | 78 | /// @desc Asserts that the passed in argument is true 79 | /// @param Value 80 | /// @param OptionalMessage 81 | function assert_is_true() { 82 | if (argument_count > 1) { 83 | assert_equal(argument[0], true, argument[1]); 84 | } else { 85 | assert_equal(argument[0], true); 86 | } 87 | } 88 | 89 | /// @desc Ensures the passed in argument is undefined 90 | /// @param TestValue 91 | /// @param OptionalMessage 92 | function assert_is_undefined() { 93 | if (!is_undefined(argument[0])) { 94 | 95 | var msg; 96 | if (argument_count > 1) { 97 | msg = argument[1]; 98 | } else { 99 | msg = _test_create_assert_error(string(argument[0]) + " is not undefined."); 100 | } 101 | throw (msg); 102 | } 103 | } 104 | 105 | /// @desc Ensures the passed in values are not equal 106 | /// @param TestValue 107 | /// @param UnexpectedValue 108 | /// @param OptionalMessage 109 | function assert_not_equal() { 110 | if (argument[0] == argument[1]) { 111 | var msg = ""; 112 | 113 | if (argument_count > 2) { 114 | msg = argument[2]; 115 | } else { 116 | msg = _test_create_assert_error(string(argument[0]) + " shouldn\'t be " + string(argument[1])); 117 | } 118 | throw (msg); 119 | } 120 | } 121 | 122 | /// @desc Ensures the passed in method throws an exception 123 | /// @param testMethod 124 | /// @param optionalExpectedMessage 125 | function assert_throws() { 126 | var testMethod = argument[0]; 127 | var expectedMessage = argument_count > 1 ? argument[1] : ""; 128 | var thrownErrorMessage = ""; 129 | var didThrow = false; 130 | var didThrowCorrectMessage = argument_count == 1; 131 | 132 | try { 133 | testMethod(); 134 | } catch (error) { 135 | didThrow = true; 136 | thrownErrorMessage = typeof(error) == "string" ? error : error.message; 137 | 138 | if (argument_count > 1) { 139 | didThrowCorrectMessage = thrownErrorMessage == expectedMessage; 140 | } 141 | } 142 | 143 | if (!didThrow) { 144 | throw _test_create_assert_error("Supplied method did not throw an error"); 145 | } 146 | 147 | if (!didThrowCorrectMessage) { 148 | throw _test_create_assert_error("Supplied method threw unexpected error message: \"" + thrownErrorMessage + "\""); 149 | } 150 | } -------------------------------------------------------------------------------- /src/gmtest/scripts/assert/assert.yy: -------------------------------------------------------------------------------- 1 | { 2 | "isDnD": false, 3 | "isCompatibility": false, 4 | "parent": { 5 | "name": "gmtest", 6 | "path": "folders/Scripts/gmtest.yy", 7 | }, 8 | "resourceVersion": "1.0", 9 | "name": "assert", 10 | "tags": [], 11 | "resourceType": "GMScript", 12 | } -------------------------------------------------------------------------------- /src/gmtest/scripts/gmtest_methods/gmtest_methods.gml: -------------------------------------------------------------------------------- 1 | /// @desc Defines an individual test 2 | /// @param {string} description The description of the functionality being tested 3 | /// @param {method} testMethod A method containing the test 4 | function test_it(testName, testMethod) { 5 | var testCount = array_length(global.__gmtest_testsCollection); 6 | global.__gmtest_testsCollection[testCount] = { 7 | name: testName, 8 | test: testMethod, 9 | } 10 | } 11 | 12 | /// @desc Defines a setup function for a suite of tests 13 | /// @param {method} setupMethod A method containing the setup for a test suite 14 | function test_before(setupMethod) { 15 | global.__gmtest_before = setupMethod; 16 | } 17 | 18 | /// @desc Defines a cleanup function for a suite of tests 19 | /// @param {method} cleanupMethod A method containing the cleanup for a test suite 20 | function test_after(cleanupMethod) { 21 | global.__gmtest_after = cleanupMethod; 22 | } 23 | 24 | /// @desc Defines a setup function for each test in a suite of tests 25 | /// @param {method} setupMethod A method containing the setup for a test suite 26 | function test_before_each(setupMethod) { 27 | global.__gmtest_beforeEach = setupMethod; 28 | } 29 | 30 | /// @desc Defines a cleanup function for each test in a suite of tests 31 | /// @param {method} cleanupMethod A method containing the cleanup for a test suite 32 | function test_after_each(cleanupMethod) { 33 | global.__gmtest_afterEach = cleanupMethod; 34 | } 35 | 36 | /// @desc Wraps a suite of tests 37 | /// @param {string} testName The name of the test suite 38 | /// @param {method} testSuiteMethod A method containing the individual tests 39 | function test_describe(testName, testSuiteMethod){ 40 | if (!variable_global_exists("__gmtest_suites")) { 41 | global.__gmtest_suites = []; 42 | } 43 | 44 | global.__gmtest_testsCollection = []; 45 | global.__gmtest_before = function() {}; 46 | global.__gmtest_after = function() {}; 47 | global.__gmtest_beforeEach = function() {}; 48 | global.__gmtest_afterEach = function() {}; 49 | 50 | testSuiteMethod(); 51 | 52 | global.__gmtest_suites[array_length(global.__gmtest_suites)] = { 53 | name: testName, 54 | tests: global.__gmtest_testsCollection, 55 | before: global.__gmtest_before, 56 | after: global.__gmtest_after, 57 | beforeEach: global.__gmtest_beforeEach, 58 | afterEach: global.__gmtest_afterEach, 59 | }; 60 | } 61 | 62 | /// @desc Runs all registered tests 63 | /// @param autoEnd {boolean} If GM Test should close the game upon completion of the tests. Defaults to false. 64 | function test_run_all() { 65 | var autoEnd = argument_count > 0 ? argument[0] : false; 66 | var testCount = array_length(global.__gmtest_suites); 67 | var totalTests = 0; 68 | var passedTests = 0; 69 | var brokenTests = []; 70 | for (var i = 0; i < testCount; i++) { 71 | // Prepare for this suite 72 | global.__gmtest_before = -1; 73 | global.__gmtest_after = -1; 74 | 75 | // Print suite info 76 | var testSuite = global.__gmtest_suites[i]; 77 | show_debug_message(testSuite.name); 78 | 79 | var suiteTestCount = array_length(testSuite.tests); 80 | testSuite.before(); 81 | 82 | for (var testIdx = 0; testIdx < suiteTestCount; testIdx++) { 83 | 84 | totalTests++; 85 | var testPassed = true; 86 | var testExceptionMessage = ""; 87 | 88 | // Run the test 89 | testSuite.beforeEach(); 90 | 91 | try { 92 | testSuite.tests[testIdx].test(); 93 | } catch (error) { 94 | testPassed = false; 95 | testExceptionMessage = typeof(error) == "string" ? error : error.message; 96 | } finally { 97 | testSuite.afterEach(); 98 | } 99 | 100 | if (testPassed) { 101 | show_debug_message("|- ✓ It " + testSuite.tests[testIdx].name); 102 | passedTests++; 103 | } else { 104 | show_debug_message("|- × It " + testSuite.tests[testIdx].name); 105 | show_debug_message("|-- ERROR: " + testExceptionMessage); 106 | 107 | brokenTests[array_length(brokenTests)] = { 108 | suite: testSuite.name, 109 | test: testSuite.tests[testIdx].name, 110 | errorMessage: testExceptionMessage, 111 | }; 112 | } 113 | } 114 | testSuite.after(); 115 | show_debug_message(""); 116 | 117 | } 118 | 119 | show_debug_message("[" + string(passedTests) + "/" + string(totalTests) + "] Test exeuction end"); 120 | show_debug_message(""); 121 | show_debug_message("-----------"); 122 | 123 | if (array_length(brokenTests) > 0) { 124 | show_debug_message(""); 125 | show_debug_message("Failed tests:"); 126 | show_debug_message(""); 127 | 128 | for (var i = 0; i < array_length(brokenTests); i++) { 129 | show_debug_message("In " + brokenTests[i].suite); 130 | show_debug_message("|- × It " + brokenTests[i].test); 131 | show_debug_message("|-- ERROR: " + brokenTests[i].errorMessage); 132 | show_debug_message("-----------"); 133 | } 134 | } else { 135 | show_debug_message("All tests passing!"); 136 | } 137 | 138 | if (autoEnd) { 139 | game_end(); 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /src/gmtest/scripts/gmtest_methods/gmtest_methods.yy: -------------------------------------------------------------------------------- 1 | { 2 | "isDnD": false, 3 | "isCompatibility": false, 4 | "parent": { 5 | "name": "gmtest", 6 | "path": "folders/Scripts/gmtest.yy", 7 | }, 8 | "resourceVersion": "1.0", 9 | "name": "gmtest_methods", 10 | "tags": [], 11 | "resourceType": "GMScript", 12 | } -------------------------------------------------------------------------------- /src/gmtest/scripts/test_asserts/test_asserts.gml: -------------------------------------------------------------------------------- 1 | function test_assert_exists() { 2 | test_describe("assert_exists", function() { 3 | test_before(function() { 4 | instance_create_depth(0, 0, 0, obj_another_object); 5 | }); 6 | 7 | test_after(function() { 8 | instance_destroy(obj_another_object); 9 | }); 10 | 11 | test_it("asserts when an object is present", function() { 12 | assert_exists(obj_another_object); 13 | }); 14 | 15 | test_it("errors when an object is not present", function() { 16 | assert_throws(function() { 17 | assert_exists(obj_an_object); 18 | }, "ASSERTION ERROR: " + string(obj_an_object) + " has no instances"); 19 | 20 | }); 21 | }); 22 | } 23 | 24 | function test_assert_equal() { 25 | test_describe("assert_equal", function() { 26 | test_it("can tell when things are equal", function() { 27 | assert_equal(true, true); 28 | assert_equal(1, 1); 29 | }); 30 | 31 | test_it("errors when things are not equal", function() { 32 | assert_throws(function() { 33 | assert_equal(1, 2); 34 | }); 35 | 36 | assert_throws(function() { 37 | assert_equal(true, false); 38 | }); 39 | }); 40 | 41 | }); 42 | } 43 | 44 | function test_assert_not_equal() { 45 | test_describe("assert_not_equal", function() { 46 | test_it("can tell when things are not equal", function() { 47 | assert_not_equal(true, false); 48 | assert_not_equal(1, 2); 49 | }); 50 | 51 | test_it("errors when things are equal", function() { 52 | assert_throws(function() { 53 | assert_not_equal(1, 1); 54 | }); 55 | 56 | assert_throws(function() { 57 | assert_not_equal(true, true); 58 | }); 59 | }); 60 | }); 61 | } 62 | 63 | function test_assert_does_not_exist() { 64 | test_describe("assert_does_not_exist", function() { 65 | test_it("asserts when an object is not present", function() { 66 | assert_does_not_exist(obj_another_object); 67 | }); 68 | 69 | test_it("errors when an object is present", function() { 70 | assert_throws(function() { 71 | instance_create_depth(0, 0, 0, obj_an_object); 72 | assert_does_not_exist(obj_an_object); 73 | }, "ASSERTION ERROR: " + string(obj_an_object) + " should not exist"); 74 | 75 | }); 76 | }); 77 | } 78 | 79 | function test_assert() { 80 | test_describe("assert", function() { 81 | test_it("asserts when the content is true", function() { 82 | assert(true); 83 | assert(1 == 1); 84 | assert("hello" == "hello"); 85 | }); 86 | 87 | test_it("errors when the content is not true", function() { 88 | assert_throws(function() { 89 | assert(false); 90 | }); 91 | }); 92 | }); 93 | } 94 | 95 | function test_assert_is_true() { 96 | test_describe("assert_is_true", function() { 97 | test_it("asserts when the content is true", function() { 98 | assert_is_true(true); 99 | assert_is_true(1 == 1); 100 | assert_is_true("hello" == "hello"); 101 | }); 102 | 103 | test_it("errors when the content is not true", function() { 104 | assert_throws(function() { 105 | assert_is_true(false); 106 | }); 107 | }); 108 | }); 109 | } 110 | 111 | function test_assert_is_false() { 112 | test_describe("assert_is_false", function() { 113 | test_it("asserts when the content is false", function() { 114 | assert_is_false(false); 115 | assert_is_false(1 == 2); 116 | assert_is_false("hello" == "helloooo"); 117 | }); 118 | 119 | test_it("errors when the content is not false", function() { 120 | assert_throws(function() { 121 | assert_is_false(true); 122 | }); 123 | }); 124 | }); 125 | } 126 | 127 | function test_assert_is_undefined() { 128 | test_describe("assert_is_undefined", function() { 129 | test_it("asserts when the content is undefined", function() { 130 | assert_is_undefined(undefined); 131 | }); 132 | 133 | test_it("errors when the content is not undefined", function() { 134 | assert_throws(function() { 135 | assert_is_undefined(true); 136 | }); 137 | }); 138 | }); 139 | } 140 | 141 | function test_assert_throws() { 142 | test_describe("assert_throws", function() { 143 | test_it("asserts when the provided function throws", function() { 144 | assert_throws(function() { 145 | throw "test"; 146 | }); 147 | }); 148 | 149 | test_it("asserts when the provided function throws the right error message", function() { 150 | assert_throws(function() { 151 | throw "test"; 152 | }, "test"); 153 | }); 154 | 155 | test_it("errors when the provided function does not throw", function() { 156 | try { 157 | assert_throws(function() {}); 158 | } catch (error) { 159 | assert_is_true(string_pos("ASSERT", error) != 0); 160 | } 161 | }); 162 | 163 | test_it("errors when the provided function does not throw the right error message", function() { 164 | try { 165 | assert_throws(function() { 166 | throw "wrong"; 167 | }, "right"); 168 | } catch (error) { 169 | assert_is_true(string_pos("ASSERT", error) != 0); 170 | } 171 | }); 172 | }); 173 | } -------------------------------------------------------------------------------- /src/gmtest/scripts/test_asserts/test_asserts.yy: -------------------------------------------------------------------------------- 1 | { 2 | "isDnD": false, 3 | "isCompatibility": false, 4 | "parent": { 5 | "name": "tests", 6 | "path": "folders/Scripts/tests.yy", 7 | }, 8 | "resourceVersion": "1.0", 9 | "name": "test_asserts", 10 | "tags": [], 11 | "resourceType": "GMScript", 12 | } -------------------------------------------------------------------------------- /src/gmtest/scripts/test_main/test_main.gml: -------------------------------------------------------------------------------- 1 | function test_main() { 2 | test_assert_exists(); 3 | test_assert_does_not_exist(); 4 | test_assert_equal(); 5 | test_assert_not_equal(); 6 | test_assert(); 7 | test_assert_is_true(); 8 | test_assert_is_false(); 9 | test_assert_is_undefined(); 10 | test_assert_throws(); 11 | 12 | test_run_all(true); 13 | } -------------------------------------------------------------------------------- /src/gmtest/scripts/test_main/test_main.yy: -------------------------------------------------------------------------------- 1 | { 2 | "isDnD": false, 3 | "isCompatibility": false, 4 | "parent": { 5 | "name": "tests", 6 | "path": "folders/Scripts/tests.yy", 7 | }, 8 | "resourceVersion": "1.0", 9 | "name": "test_main", 10 | "tags": [], 11 | "resourceType": "GMScript", 12 | } -------------------------------------------------------------------------------- /src/gmtest/sprites/spr_box/61b3ae8b-3460-4fd2-aaad-be502a046c2e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gm-core/GMTest/29027a96973476cd6486494d44ce2b9719d3304b/src/gmtest/sprites/spr_box/61b3ae8b-3460-4fd2-aaad-be502a046c2e.png -------------------------------------------------------------------------------- /src/gmtest/sprites/spr_box/layers/61b3ae8b-3460-4fd2-aaad-be502a046c2e/8146f226-818c-4d31-a359-f372654c9847.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gm-core/GMTest/29027a96973476cd6486494d44ce2b9719d3304b/src/gmtest/sprites/spr_box/layers/61b3ae8b-3460-4fd2-aaad-be502a046c2e/8146f226-818c-4d31-a359-f372654c9847.png -------------------------------------------------------------------------------- /src/gmtest/sprites/spr_box/spr_box.yy: -------------------------------------------------------------------------------- 1 | { 2 | "bboxMode": 0, 3 | "collisionKind": 1, 4 | "type": 0, 5 | "origin": 0, 6 | "preMultiplyAlpha": false, 7 | "edgeFiltering": false, 8 | "collisionTolerance": 0, 9 | "swfPrecision": 0.0, 10 | "bbox_left": 0, 11 | "bbox_right": 31, 12 | "bbox_top": 0, 13 | "bbox_bottom": 31, 14 | "HTile": false, 15 | "VTile": false, 16 | "For3D": false, 17 | "width": 32, 18 | "height": 32, 19 | "textureGroupId": { 20 | "name": "Default", 21 | "path": "texturegroups/Default", 22 | }, 23 | "swatchColours": null, 24 | "gridX": 0, 25 | "gridY": 0, 26 | "frames": [ 27 | {"compositeImage":{"FrameId":{"name":"61b3ae8b-3460-4fd2-aaad-be502a046c2e","path":"sprites/spr_box/spr_box.yy",},"LayerId":null,"resourceVersion":"1.0","name":"composite","tags":[],"resourceType":"GMSpriteBitmap",},"images":[ 28 | {"FrameId":{"name":"61b3ae8b-3460-4fd2-aaad-be502a046c2e","path":"sprites/spr_box/spr_box.yy",},"LayerId":{"name":"8146f226-818c-4d31-a359-f372654c9847","path":"sprites/spr_box/spr_box.yy",},"resourceVersion":"1.0","name":"","tags":[],"resourceType":"GMSpriteBitmap",}, 29 | ],"parent":{"name":"spr_box","path":"sprites/spr_box/spr_box.yy",},"resourceVersion":"1.0","name":"61b3ae8b-3460-4fd2-aaad-be502a046c2e","tags":[],"resourceType":"GMSpriteFrame",}, 30 | ], 31 | "sequence": { 32 | "spriteId": {"name":"spr_box","path":"sprites/spr_box/spr_box.yy",}, 33 | "timeUnits": 1, 34 | "playback": 1, 35 | "playbackSpeed": 1.0, 36 | "playbackSpeedType": 1, 37 | "autoRecord": true, 38 | "volume": 1.0, 39 | "length": 1.0, 40 | "events": {"Keyframes":[],"resourceVersion":"1.0","resourceType":"KeyframeStore",}, 41 | "moments": {"Keyframes":[],"resourceVersion":"1.0","resourceType":"KeyframeStore",}, 42 | "tracks": [ 43 | {"name":"frames","spriteId":null,"keyframes":{"Keyframes":[ 44 | {"id":"84a50e15-437e-4077-89b8-1b6cc21b53c4","Key":0.0,"Length":1.0,"Stretch":false,"Disabled":false,"IsCreationKey":false,"Channels":{"0":{"Id":{"name":"61b3ae8b-3460-4fd2-aaad-be502a046c2e","path":"sprites/spr_box/spr_box.yy",},"resourceVersion":"1.0","resourceType":"SpriteFrameKeyframe",},},"resourceVersion":"1.0","resourceType":"Keyframe",}, 45 | ],"resourceVersion":"1.0","resourceType":"KeyframeStore",},"trackColour":0,"inheritsTrackColour":true,"builtinName":0,"traits":0,"interpolation":1,"tracks":[],"events":[],"modifiers":[],"isCreationTrack":false,"resourceVersion":"1.0","tags":[],"resourceType":"GMSpriteFramesTrack",}, 46 | ], 47 | "visibleRange": {"x":0.0,"y":0.0,}, 48 | "lockOrigin": false, 49 | "showBackdrop": true, 50 | "showBackdropImage": false, 51 | "backdropImagePath": "", 52 | "backdropImageOpacity": 0.5, 53 | "backdropWidth": 1920, 54 | "backdropHeight": 1080, 55 | "backdropXOffset": 0.0, 56 | "backdropYOffset": 0.0, 57 | "xorigin": 0, 58 | "yorigin": 0, 59 | "eventToFunction": {}, 60 | "eventStubScript": null, 61 | "parent": {"name":"spr_box","path":"sprites/spr_box/spr_box.yy",}, 62 | "resourceVersion": "1.3", 63 | "name": "", 64 | "tags": [], 65 | "resourceType": "GMSequence", 66 | }, 67 | "layers": [ 68 | {"visible":true,"isLocked":false,"blendMode":0,"opacity":100.0,"displayName":"default","resourceVersion":"1.0","name":"8146f226-818c-4d31-a359-f372654c9847","tags":[],"resourceType":"GMImageLayer",}, 69 | ], 70 | "parent": { 71 | "name": "Sprites", 72 | "path": "folders/Sprites.yy", 73 | }, 74 | "resourceVersion": "1.0", 75 | "name": "spr_box", 76 | "tags": [], 77 | "resourceType": "GMSprite", 78 | } --------------------------------------------------------------------------------