{"version":"https://jsonfeed.org/version/1.1","title":"TabularElf Blog","home_page_url":"https://www.tabularelf.com/","feed_url":"https://www.tabularelf.com/feed.json","description":"Vtuber and programmer from down under!","language":"en","items":[{"id":"https://www.tabularelf.com/posts/proper-frame-counter/","url":"https://www.tabularelf.com/posts/proper-frame-counter/","title":"[GameMaker] Making a proper frame counter.","language":"en","content_html":"<p><strong>Note</strong>: This is specifically for versions <strong>GameMaker 2022.5.0.8</strong> and above, due to the following code relying on Time Sources.</p>\n<p>I’ll admit, I have personally never needed a frame counter in my projects, especially given that I mostly focus on library-related work. That said, the thought does cross my mind from time to time. In the past, frame counters I’ve made only check for the current frames that have already been processed within the game. However I was at one point asked for a method to compare frames against the current step. While that particular use case was to make a simple alarm, it did spark my interest. So today, I want to introduce to you current_step. The rest of the blog post covers the whole process and how I handled it specifically. If you just want the full snippet, you may scroll down to the bottom of the post. Otherwise…</p>\n<!--More-->\n<h2 id=\"why-do-we-need-a-frame-counter%3F\" tabindex=\"-1\"><a href=\"https://www.tabularelf.com/posts/proper-frame-counter/#why-do-we-need-a-frame-counter%3F\" class=\"header-anchor\">Why do we need a frame counter?</a></h2>\n<p>Typically the main reason you’d want to use a frame counter is to</p>\n<ul>\n<li>Check how many frames your game has processed so far. (Yes, this is a literal use case.)</li>\n<li>Execute a particular set of code once every X frames. (Aka a simplified alarm.)</li>\n</ul>\n<p>The first one helps us see how many steps our game has passed so far. The second one is really handy for only executing a small chunk of code every step, without having to rely on an alarm or a timer that we have to keep track of ourselves. Typically current_time and get_timer() are the two most popular options for tracking this, but they have some drawbacks that I will go over later in this post.</p>\n<h2 id=\"how-were-frame-counters-usually-done-in-gamemaker%3F\" tabindex=\"-1\"><a href=\"https://www.tabularelf.com/posts/proper-frame-counter/#how-were-frame-counters-usually-done-in-gamemaker%3F\" class=\"header-anchor\">How were frame counters usually done in GameMaker?</a></h2>\n<p>If you’re familiar with GameMaker, you will know about objects and their many different events. They are used for a wide variety of things, but some in particular are used for managing specific systems. The main focus comes to mind is the begin step, step and end step events. With the exclusion of <code>draw events</code> and <code>alarm events</code>, these are the only events that process once per instance, per frame. In the order of:</p>\n<ul>\n<li>Begin Step Event</li>\n<li>Step Event</li>\n<li>End Step Event</li>\n</ul>\n<p>You can read more in detail about the step events and the other events (besides alarms) by clicking here. But for this part of the post, we’re going to be solely focusing on these three events for now.</p>\n<p>Traditionally, if you wanted to make a frame counter work with an object, you needed to design your game with a specific setup in mind. The first room within the game (In GameMaker 2.3.0+, this is managed by the Room Order section. In older versions, the first room that’s on top of all of the other rooms within the Room folder) had to contain a preferably persistent object (i.e. obj_game_controller), stored within a room that sets up most of your game before moving into another room (such as the main menu or game intro). Much of the code for a frame counter was setup like this.</p>\n<pre><code class=\"language-gml\">// Game Start Event\nglobal.frame_counter = 0;\n\n// Begin Step Event\n++global.frame_counter;\n</code></pre>\n<p>The reason we call it in the begin step event is because now any time an object wishes to get the current frame counter, they can just fetch global.frame_counter. Here’s two reasons why I don’t like this approach.</p>\n<ol>\n<li>It solely relies on an object to manage it.</li>\n<li>While not likely, it is possible to modify global.frame_counter either by accident, or via an external scripting API (think modding API), which could cause other unintended issues.</li>\n</ol>\n<p>The second one is more of a specific rare case, but the first is more problematic. This is because the counter itself is managed by a single instance of that object. If you know anything about objects and instances… It’s possible to accidentally destroy said instance, thus rendering your frame counter completely and utterly useless! Of course, with good standard practices and proper management, both of these are mostly avoidable.</p>\n<p>But what if you didn’t want to rely on an object?</p>\n<h2 id=\"solution-1%3A-use-current_time!\" tabindex=\"-1\"><a href=\"https://www.tabularelf.com/posts/proper-frame-counter/#solution-1%3A-use-current_time!\" class=\"header-anchor\">Solution 1: Use current_time!</a></h2>\n<p>Now when I came across the question, one of my first thoughts was “Why not just use current_time?” Since it doesn’t use an object, and the value itself can’t be changed alone. We need to keep in mind however, current_time increments in milliseconds, whereas get_timer() increments in microseconds. The reason I’m using current_time here is more of simplicity sake. The code I came up with for this was shoved into a macro for easy use. If you’re unfamiliar with what a macro is, it’s essentially a keyword that gets replaced during code compiling with the specificied value or code in place. Some examples of macros in use:</p>\n<pre><code class=\"language-gml\">#macro FPS_SPEED (&quot;Current FPS: &quot; + string(fps) + &quot;\\nFPS Target: &quot; + string((game_get_speed(gamespeed_fps))))\n\n// In the draw event\n\n// Print FPS stats\ndraw_text(8, 8, FPS_SPEED);\n</code></pre>\n<p>During compiling, this gets expanded to</p>\n<pre><code class=\"language-gml\">#macro current_step (current_time div game_get_speed(gamespeed_fps))\n</code></pre>\n<p>This is good, but it has one flaw with this kind of thinking. It’s quite hard to tell from a glance, but did you know that both current_time and get_timer() tick upwards separately from the rest of your game code? “Obviously it shouldn’t cause some kind of issue, right?” you ask. Well unless your intention is to have your frame counter count up once every real world second, any moments where your game freezes up is enough to cause a desync while it’s still executing. Especially anywhere within the current step, alarms or draw events! Let’s also not forget that we’re relying on game_get_speed(), which is a function that can be altered by game_set_speed() (or room_speed for those who still use it), and can influence the current frame counter. It also may at times start above 0, which we don’t want that kind of inconsistency. Ultimately, current_time, and by extension, get_timer() make for a pretty bad frame counter overall. There’s got to be something better, right?</p>\n<h2 id=\"solution-2%3A-use-time-sources!\" tabindex=\"-1\"><a href=\"https://www.tabularelf.com/posts/proper-frame-counter/#solution-2%3A-use-time-sources!\" class=\"header-anchor\">Solution 2: Use Time Sources!</a></h2>\n<p>Up until Game Maker 2022.5.0.8, objects were the one and only true way you could process logic every frame. However, since version 2022.5.0.8, GameMaker has introduced time sources! “So what is this time source you speak of?” Think about it like an object’s alarm event, except it’s not an object. It works solely independently from any and all objects. Aha, now we’re getting fancy here! “But how do we use a time source?”</p>\n<p>Time sources are a bit more involved, and I’d recommend checking the documentation on all of their arguments on time source create <a href=\"https://manual.yoyogames.com/GameMaker_Language/GML_Reference/Time_Sources/time_source_create.htm\">here</a>. But for our specific case, we’ll be actually just using this.</p>\n<pre><code class=\"language-gml\">ts = time_source_create(time_source_global, 1, time_source_units_frames, callback, [], -1);\n</code></pre>\n<p>Time sources have two parent-based timers. time_source_global and time_source_game. We’re using time_source_global since it cannot be paused with time_source_pause() by accident (which can happen if you do time_source_pause(time_source_game)). The rest of the arguments determine that:</p>\n<ul>\n<li>Waits 1 frame before running our callback function</li>\n<li>Sets an array of paramaters to pass into the callback function (In our case, it’s an empty array)</li>\n<li>Sets the repetitions, aka repeats, the time source should execute. (-1 makes it repeat forever.)</li>\n</ul>\n<p>What we’ll be doing is taking one step further however, and creating a unique struct that contains our relative information. We’ll also be using said struct to store our frame counter value as well.</p>\n<pre><code class=\"language-gml\">function __get_current_step() {\n    // Initialize our static variable\n    static _inst = undefined;\n\n    // Check that our static variable is undefined.\n    if (_inst == undefined) {\n        _inst = {};\n        _inst.ts = time_source_create(time_source_global, 1, time_source_units_frames, method(_inst, function() {\n            ++currentStep;\n        }), [], -1);\n        time_source_start(_inst.ts);\n         _inst.currentStep = 0;\n\t}\n\t\n\treturn _inst.currentStep;\n}\n__get_current_step(); // We call this once at the start\n</code></pre>\n<p>So what’s going on here? What is static?\nStatic is basically a value that gets declared once and binded to the function. You can perform any future code with it to change or alter said value, or its contents. But ultimately, you can use it to keep a permanent reference to a value. In our case, we’re using it to store a struct. The other benefit we gain here is that unless we expose that struct by returning it, this is effectively untouchable by any outside force (Well, besides static_get()). As for method(), Game Maker allows functions to be called from any instance, object, or struct by binding the function to it. This means that whenever that method is called, it’s executing as said instance. This current code works just as fine, so we can assign this to a macro in it’s current state.</p>\n<pre><code class=\"language-gml\">#macro current_step (__get_current_step())\n</code></pre>\n<p>“But, wait, when do time sources tick?” This may come as a shocker to some of you, they tick after the begin step event but before the step event! The goal of this is to also account for the begin step event, so does that mean time sources are also a dud?</p>\n<p><img src=\"https://www.tabularelf.com/images/uploads/wellyesbutactuallyno-768x432.jpg\" alt=\"Image\"></p>\n<p>We can make this work with the begin step event, it just requires a bit more logic on our end.</p>\n<h3 id=\"extending-solution-2-to-work-in-the-begin-step-event.\" tabindex=\"-1\"><a href=\"https://www.tabularelf.com/posts/proper-frame-counter/#extending-solution-2-to-work-in-the-begin-step-event.\" class=\"header-anchor\">Extending Solution 2 to work in the Begin Step Event.</a></h3>\n<p>To begin, we’ll add a new variable to our struct</p>\n<pre><code class=\"language-gml\">_inst.currentStep = 0;\n_inst.executedInBeginStep = false;\n</code></pre>\n<p>Now just before we return currentStep, we also need this bit of code to be added.</p>\n<pre><code class=\"language-gml\">    // Check if we're in the begin step event\n    if ((event_type == ev_step) &amp;&amp; (event_number == ev_step_begin) &amp;&amp; \n\t(!_inst.executedInBeginStep)) {\n        _inst.executedInBeginStep = true;    \n        ++_inst.currentStep;\n    }\n    \n    return _inst.currentStep;\n}\n</code></pre>\n<p>Basically, since our time source doesn’t tick until after begin step event, this small snippet of code ensures that we’ve already incremented ahead of time. Now, you’ll already notice that our time source code will also still increment it, causing a double increment. To fix this, we just add in a check to our callback function.</p>\n<pre><code class=\"language-gml\">  _inst.ts = time_source_create(time_source_global, 1, time_source_units_frames, method(_inst, function() {\n            if (executedInBeginStep) {\n                --currentStep;\n                executedInBeginStep = false;\n            }\n            ++currentStep;\n        }), [], -1);\n</code></pre>\n<p>Everything is good, right? If you were to call current_step in the create event and begin step event, while having it run in the very first room of the game, you’ll quickly realize that it has incremented an entire step despite the fact the game only just started (shows 1 instead of 0)! This isn’t technically a bug, although I do like to make my frame counters a bit more consistent. By ensuring that between the very start of the game, to the next begin step, stays consistently as “frame 0”. So I came up with another solution.</p>\n<p>Firstly we’ll change currentStep during our struct setup to -1.</p>\n<pre><code class=\"language-gml\">     _inst.currentStep = -1;\n     _inst.executedInBeginStep = false;\n</code></pre>\n<p>And then add this snippet of code just below our check for the begin step event.</p>\n<pre><code class=\"language-gml\">    // Check if this is our frame counter is below 0, aka the very first frame.\n    if (_inst.currentStep &lt; 0) {\n        return 0;   \n    }\n</code></pre>\n<p>We check to see if currentStep is less than 0 and return 0, since we are technically on the very first frame. Which corrects all of the remaining oddities, and makes calling it anywhere more in sync.\nOur code now is finally coming all together. What we end up with is a frame counter that not only updates every step event, but also actually starts from 0!</p>\n<h2 id=\"conclusion\" tabindex=\"-1\"><a href=\"https://www.tabularelf.com/posts/proper-frame-counter/#conclusion\" class=\"header-anchor\">Conclusion</a></h2>\n<p>This concludes the blog post on how we went from a basic frame counter, to a proper frame counter!\nI like to thank Homs from r/GameMaker’s Discord Server, for giving me a reason to spend some of my time thinking about the best possible solution to a frame counter! I also would like to give special thanks to Gizmo199 for helping me proof read all of this. (Staying up all night and writing does not mix very well.)</p>\n<p>I’m always looking for more things to cover in regards to GameMaker, so if you ever want to see me tackle something else involving GameMaker, leave a comment below or join my Discord Server to talk to me directly! Also consider following me on my socials!</p>\n<p>You can get the full code from here, with some slight changes\n<a href=\"https://gist.github.com/tabularelf/a54f338b1cc82f99e7a35cf0ad6f18cb\">here</a>!</p>\n","tags":["frame counter","gamemaker","time source"],"date_published":"2023-03-01T00:00:00.000Z"},{"id":"https://www.tabularelf.com/posts/basic-saving-and-loading/","url":"https://www.tabularelf.com/posts/basic-saving-and-loading/","title":"[GameMaker] Basic Saving and Loading with JSON & Buffers","language":"en","content_html":"<p>I’m writing this guide as I’ve noticed that there’s not a lot of up-to-date reading material that covers a good way of saving/loading important data. You can find videos of it online, but I prefer to scroll through webpages myself and study the material. The main topic we’re covering of course is saving/loading data from JSON. But, there’s a few things that we need to cover before we can get to that.</p>\n<!--More-->\n<h2 id=\"preparations\" tabindex=\"-1\"><a href=\"https://www.tabularelf.com/posts/basic-saving-and-loading/#preparations\" class=\"header-anchor\">Preparations</a></h2>\n<p>Before we actually begin to learn how to save and load our data, we first need to understand how we can store our data as JSON. GameMaker fortunately does provide us some easy-to-use functionality, which are json_stringify and json_parse. These two will allow us to turn data into JSON and vice versa. Data specifically being structs.</p>\n<h3 id=\"what-are-structs%2C-anyway%3F\" tabindex=\"-1\"><a href=\"https://www.tabularelf.com/posts/basic-saving-and-loading/#what-are-structs%2C-anyway%3F\" class=\"header-anchor\">What are structs, anyway?</a></h3>\n<p>If you’re familiar with instances/objects in GameMaker, they’re a form of that, but without events or built-in variables. Put simply, they only contain data that you, the developer, specify. They’re by far the easiest to deal with, since they are garbaged collected. Which means that you don’t even need to delete them, like with arrays. You can just set and forget them.</p>\n<h3 id=\"how-do-we-make-a-struct%3F\" tabindex=\"-1\"><a href=\"https://www.tabularelf.com/posts/basic-saving-and-loading/#how-do-we-make-a-struct%3F\" class=\"header-anchor\">How do we make a struct?</a></h3>\n<p>Defining a struct is relatively straight forward.</p>\n<pre><code class=\"language-gml\">var _struct = {\n\tfoo: &quot;bar&quot;,\n\tkey: &quot;value&quot;,\n\tbool: false,\n\tnumber: 26\n};\n</code></pre>\n<p>A struct can have as many keys as you desire, and they can hold whatever value you choose. In this example, foo is our key, and &quot;bar&quot; is the value. At this point of time, we can easily reference them. Just by either using the dot operator (<code>_struct.key</code>) or using the function <code>variable_struct_get(_struct, “key”)</code> (or the accessor <code>_struct[$ &quot;key&quot;]</code>)</p>\n<pre><code class=\"language-gml\">show_debug_message(_struct.foo);\nshow_debug_message(_struct[$ &quot;foo&quot;]);\nshow_debug_message(variable_struct_get(_struct, &quot;foo&quot;));\n</code></pre>\n<p>Do take care in mind, that both the accessor and the function do the same thing, and are different from the dot operator.</p>\n<p>The major difference being that:</p>\n<ul>\n<li>Dot Operators are several times faster, as they precalculate the pointer in memory. However, doing _struct.foo on something that doesn’t have the variable foo, will cause the game to crash. We can get around this by checking with variable_struct_exists(_struct, &quot;foo&quot;) prior to actually attempting to retrieving the value from the variable.</li>\n<li>Accessor/function only calcuate the pointer when called by the string value, and either returns the value being held in the variable, or undefined if nothing exists. This won’t crash the game, but will be slower than using the Dot Operators, due to having to calculate the pointer each time it is called.</li>\n</ul>\n<h2 id=\"setting-up-our-example-player\" tabindex=\"-1\"><a href=\"https://www.tabularelf.com/posts/basic-saving-and-loading/#setting-up-our-example-player\" class=\"header-anchor\">Setting up our example player</a></h2>\n<p>Let’s assume that we have an obj_player object. And in it’s main Create/Step event, we have the following code:</p>\n<pre><code class=\"language-gml\">// Create Event\nx = random(room_width);\ny = random(room_height);\n\n// Step Event\nif (keyboard_check_pressed(vk_space)) {\n\n\tx = random(room_width);\n\ty = random(room_height);\n\n}\n</code></pre>\n<p>Great! We’ve got our code. Now every time we press spacebar, our player will place itself in a random position in the room.</p>\n<h2 id=\"saving-our-data\" tabindex=\"-1\"><a href=\"https://www.tabularelf.com/posts/basic-saving-and-loading/#saving-our-data\" class=\"header-anchor\">Saving our data</a></h2>\n<p>The fun part! We’ll use the obj_player x and y to save from our lil example. But to start off, we’ll take the knowledge from making a struct and applying it to our example case.</p>\n<pre><code class=\"language-gml\">var _struct = {\n\tx: obj_player.x,\n\ty: obj_player.y\n}\n\nvar _json = json_stringify(_struct);\n</code></pre>\n<p>Now that we have our struct stringified, we just need to store into a buffer. Now I did sorta gloss over buffers entirely, but I’ll go down in some basic details shortly.</p>\n<pre><code class=\"language-gml\">var _buff = buffer_create(string_byte_length(_json), buffer_fixed, 1);\nbuffer_write(_buff, buffer_text, _json);\nbuffer_save(_buff, &quot;player.json&quot;);\nbuffer_delete(_buff);\n</code></pre>\n<p>Breaking it down what we’ve just done here.</p>\n<ul>\n<li>With buffer_create, we created a buffer with a set size given by string_byte_length, followed by determing the type of buffer it is. Since we already know how big our buffer is, we’ve gone with buffer_fixed, and the 1 is the alignment, or how many bytes it will attempt to “fill” for blank spaces. Leaving it as 1 is fine for our case here. And stored the new buffer in _buff.</li>\n<li>Since our JSON is a string, we used string_byte_length to get the raw size total of all of the bytes from our string.</li>\n<li>With buffer_write, we supplied our previously created buffer, and given it the type buffer_text, and then passed our JSON results.</li>\n<li>With buffer_save, we then save our buffer results to a file called player.json. The contents themselves will be shown as a singleline JSON string.</li>\n<li>Since buffers aren’t garbage collected, we then delete the buffer with buffer_delete.</li>\n</ul>\n<p>You might’ve noticed that in the manual for buffer_write, we have some additional types. We’re going with buffer_text since it’s by the most straight forward, and we’re not storing anything else. To complete our functionality, we’ll add them together and add a separate block of code of our obj_player‘s step event.</p>\n<p><strong>Note</strong>: Saving buffers ontop of files that already do exist, will overwrite them.</p>\n<pre><code class=\"language-gml\">if (keyboard_check_released(ord(&quot;S&quot;))) {\n\n\tvar _struct = {\n\t\tx: obj_player.x,\n\t\ty: obj_player.y\n\t}\n\n\tvar _json = json_stringify(_struct);\n\n\tvar _buff = buffer_create(string_byte_length(_json), buffer_fixed, 1);\n\tbuffer_write(_buff, buffer_text, _json);\n\tbuffer_save(_buff, &quot;player.json&quot;);\n\tbuffer_delete(_buff);\n}\n</code></pre>\n<h2 id=\"loading-our-data-back-in\" tabindex=\"-1\"><a href=\"https://www.tabularelf.com/posts/basic-saving-and-loading/#loading-our-data-back-in\" class=\"header-anchor\">Loading our data back in</a></h2>\n<p>Loading in our data is just as easy as saving our data. We’ll start by loading in the buffer and converting it back into a struct.</p>\n<pre><code class=\"language-gml\">if (keyboard_check_released(ord(&quot;L&quot;))) {\n\tvar _buff = buffer_load(&quot;player.json&quot;);\n\tvar _json = buffer_read(_buff, buffer_text);\n\tbuffer_delete(_buff);\n\tvar _struct = json_parse(_json);\n</code></pre>\n<p>We’ve now loaded in a buffer, extracted the JSON and then converted it back into a struct. Retrieving the x and y is as simple as what we’ve done above with our structs example.</p>\n<pre><code class=\"language-gml\">\tobj_player.x = _struct.x;\n\tobj_player.y = _struct.y;\n}\n</code></pre>\n<p>That’s all we really need to do for that. Though, you might ask some good questions. What if the JSON doesn’t have an x and or y value, the JSON is invalid, or if the file doesn’t exist, then what?</p>\n<h2 id=\"avoiding-errors-upon-loading\" tabindex=\"-1\"><a href=\"https://www.tabularelf.com/posts/basic-saving-and-loading/#avoiding-errors-upon-loading\" class=\"header-anchor\">Avoiding errors upon loading</a></h2>\n<p>In most cases, as long as we know that the file does exist, then we don’t have to worry too much. We can easily adapt what we have above by checking first to ensure that said file exists.</p>\n<pre><code class=\"language-gml\">if (keyboard_check_released(ord(&quot;L&quot;))) &amp;&amp; (file_exists(&quot;player.json&quot;)) { \n\tvar _buff = buffer_load(&quot;player.json&quot;);\n\tvar _json = buffer_read(_buff, buffer_text);\n\tbuffer_delete(_buff);\n\tvar _struct = json_parse(_json);\n</code></pre>\n<p>Very little of the code needs changing to check that player.json already exists before attempting to load in. But, what if someone were to modify the save file to pass in an invalid JSON string? Well, in this case GameMaker will throw an exception. Frankly I find that to be an annoyance. But, we can get over that by simply adding in try/catch, which results our code looking like this so far.</p>\n<pre><code class=\"language-gml\">if (keyboard_check_released(ord(&quot;L&quot;))) &amp;&amp; (file_exists(&quot;player.json&quot;)) { \n\tvar _buff = buffer_load(&quot;player.json&quot;);\n\tvar _json = buffer_read(_buff, buffer_text);\n\tvar _struct = undefined;\n\tbuffer_delete(_buff);\n\ttry {\n\t\t_struct = json_parse(_json);\n\t} catch(_ex) {\n\t\tshow_debug_message(_ex.message);\n\t}\n\n\tif (is_struct(_struct)) {\n\t\tobj_player.x = _struct.x;\n\t\tobj_player.y = _struct.y;\n\t}\n}\n</code></pre>\n<p>This will do for the most part, and will load our data in just fine. Though, we still run into the issue that if any of the values aren’t available (either by the developers end, or by players modifying the save file), while our try/catch will prevent the game from crashing, it will also skip the rest of the loading. That’s not good! Some of our values might be beneficial! How we can overcome this is by using a tenary operator. (It’s basically a one line version of an if/else block), represented as\n<code>statement ? value_if_true : value_else;</code></p>\n<pre><code class=\"language-gml\">obj_player.x = !is_undefined(_struct[$ &quot;x&quot;]) ? _struct[$ &quot;x&quot;] : obj_player.x;\nobj_player.y = !is_undefined(_struct[$ &quot;y&quot;]) ? _struct[$ &quot;y&quot;] : obj_player.y;\n</code></pre>\n<p>Which makes up the rest of our loading system. Now we’re left with this.</p>\n<pre><code class=\"language-gml\">if (keyboard_check_released(ord(&quot;L&quot;))) &amp;&amp; (file_exists(&quot;player.json&quot;)) { \n\tvar _buff = buffer_load(&quot;player.json&quot;);\n\tvar _json = buffer_read(_buff, buffer_text);\n\tbuffer_delete(_buff);\n\ttry {\n\t\tvar _struct = json_parse(_json);\n\t} catch(_ex) {\n\t\tshow_debug_message(_ex.message);\n\t}\n\n\n\tif (is_struct(_struct)) {\n\t\tobj_player.x = !is_undefined(_struct[$ &quot;x&quot;]) ? _struct[$ &quot;x&quot;] : obj_player.x;\n\t\tobj_player.y = !is_undefined(_struct[$ &quot;y&quot;]) ? _struct[$ &quot;y&quot;] : obj_player.y;\t\n\t}\n}\n</code></pre>\n<p>Now not only do we check to ensure that the player file exists, but we also check to ensure that json_parse doesn’t throw an error, and that each and every variable from the struct is there, skipping over what’s not there. This makes our system step over many of the errors without completely halting the game. You might also be tempted to try out the idea of looping all of the structs variables (via variable_struct_get_names()) and then applying it to obj_player, but this would also mean that each and every entry that wasn’t intended at all, will be added. So I wouldn’t ever recommend doing that, unless you want to cause unintentional behaviour down the road.</p>\n<h2 id=\"conclusion\" tabindex=\"-1\"><a href=\"https://www.tabularelf.com/posts/basic-saving-and-loading/#conclusion\" class=\"header-anchor\">Conclusion</a></h2>\n<p>While this concludes the basics, I will be looking to make further tutorials on the matter. Including saving multiple instances, asynchronous saving/loading and much more. As always, I’m happy to take in any suggestions and feedback between tutorials.</p>\n<p>And while I won’t cover it today, there is a library with parsers for CSV, XML, YAML, Messagepack, Binary, Ini, JSON and more! I highly recommend checking it out if you’re interested in other formats as well as JSON. They work just as well with the code above. Just swap out json_stringify and json_parse for the equivilants.\nLink here: <a href=\"https://github.com/JujuAdams/SNAP\">(https://github.com/JujuAdams/SNAP)</a></p>\n<p>In our next blog post on this topic, I’ll cover asynchronous saving/loading.\nRepo link (for the demo code above): <a href=\"https://github.com/tabularelf/BasicSaveLoadJSON\">https://github.com/tabularelf/BasicSaveLoadJSON</a></p>\n","tags":["gamemaker","buffer","json","loading","saving"],"date_published":"2022-01-16T00:00:00.000Z"},{"id":"https://www.tabularelf.com/posts/custom-game-restart/","url":"https://www.tabularelf.com/posts/custom-game-restart/","title":"[GameMaker] Why shouldn't you use game_restart","language":"en","content_html":"<p>GameMaker offers a lot of powerful functions and flexibility for many of our needs. However, some of these functions are done in a sort of black box state. While many of GameMakers own functions/systems are genuinely fine, the problem becomes very apparent in the long run. More so when you start to build a very complex game, and let GameMaker handle more of the work than you. game_restart, being one of them.</p>\n<!--More-->\n<h2 id=\"what%E2%80%99s-wrong-with-game_restart%3F\" tabindex=\"-1\"><a href=\"https://www.tabularelf.com/posts/custom-game-restart/#what%E2%80%99s-wrong-with-game_restart%3F\" class=\"header-anchor\">What’s wrong with game_restart?</a></h2>\n<p>To understand what’s wrong exactly with using game_restart, we first need to know how it works.\nHere I’ve written some pseudo code that you can more or less replicate within GameMaker.</p>\n<pre><code class=\"language-gml\">function pseudo_game_restart() {\n\t// This will destroy all instances. \n\t// Yes, this will run their cleanup events as well as well as their destroy event.\n\twith(all) {\n\t\t// Executes the instance game end event, if any\n\t\tevent_perform(ev_other, ev_game_end);\n\t\tinstance_destroy();\t\n\t}\n\n\taudio_stop_all();\n\n\t// Go to the very first room, as per room order\n\troom_goto(room_first);\n  \n\t// Some internal system that tells instances to run game start event, \n\t// upon going to the very first room.\n\t// call_later, which was later introduced in 2022.8, will suffice.\n\tcall_later(1, time_source_units_frames, function() {\n\t\twith(all) {\n\t\t\tevent_perform(ev_other, ev_game_start);\t \n\t\t}\n\t});\n}\n</code></pre>\n<p>As you can see here, not a whole lot is going on. But this also lies in some of the many problems that happen with game_restart.</p>\n<p>I’ll summarize the issues into dot points.</p>\n<ul>\n<li>Doesn’t cleanup any dynamic resources (such as data structures, assets that were created outside of the IDE and buffers).</li>\n<li>Doesn’t reset any global variables/states that were changed (states such as the GPU state, functions/constructors with static variables and game speed).</li>\n<li>Doesn’t reset resources that were defined in the IDE and modified in game.</li>\n<li>Does not stop any time sources.</li>\n<li>Kills all persistent instances.</li>\n<li>In some reports by users, can cause rare oddities/bugs on some specific platforms.</li>\n<li>In some more extreme reports, can even produce memory leaks - in a blank project.</li>\n<li>It is not “production ready”.</li>\n</ul>\n<p>The first three points aren’t only true, but it’s stated <a href=\"https://manual.yoyogames.com/index.htm#t=GameMaker_Language%2FGML_Reference%2FGeneral_Game_Control%2Fgame_restart.htm\">within the manual</a>.\n4th and 5th points refer to less from my experience, but more from others experience amongst the GameMaker community. Take that as you will. The last point, as summarized above and with the pseudo code, more or less demonstrates why you shouldn’t use it in a big project. game_restart is meant for prototyping and debugging purposes only. It’s not meant to be used in an actual game project. Additionally, some libraries do not support game_restart for these points above. It’s not predictable enough for developers to consistently rely on for their actual projects.</p>\n<p>But then, what do we use if we do want to restart the game? It’s simple. We make our own game_restart function. Now the code I’ve posted above can be more or less used as is (I would advice removing the event_perform from it as you may not want to execute game end events). You can add/change how it works. And it works well enough for a basic start. But I do prefer this.</p>\n<pre><code class=\"language-gml\">function __game_restart() {\n  // This will destroy all instances. \n  // Yes, this will run their cleanup events as well as their destroy event.\n  with(all) {\n\tinstance_destroy();\t\n  }\n\n  audio_stop_all();\n  draw_texture_flush();\n\n\n  // Go to the very first room, as per room order\n  room_goto(room_first);\n}\n</code></pre>\n<p>We can now use __game_restart to call our custom function. Game Start and Game End will never execute beyond their intended purposes. Allowing us to set and forget things we don’t want changing at all in the Game Start event. And everything else can be defined in the other events as per normal.</p>\n<p>We can extend __game_restart to do just about anything that we like. For example, handling some or all of those edge cases that game_restart doesn’t do. I won’t cover it here, as that would go in much further detail. But with some minor tweaks to the code, you can pull it off with ease.</p>\n<h2 id=\"conclusion\" tabindex=\"-1\"><a href=\"https://www.tabularelf.com/posts/custom-game-restart/#conclusion\" class=\"header-anchor\">Conclusion</a></h2>\n<p>I hope this not only brings out the issues with game_restart, but encourages you to look beyond what you expect from how your project should handle things when it restarts the game.</p>\n","tags":["game_restart","gamemaker"],"date_published":"2021-08-08T00:00:00.000Z"}]}