Skip to content

Commit

Permalink
Merge pull request #77 from YoYoGames/develop.gurpreet
Browse files Browse the repository at this point in the history
Manual Content: Document the 2023.11 change that file can be saved in "program_directory" when the file sandbox is disabled
  • Loading branch information
gurpreetsinghmatharoo authored Dec 13, 2023
2 parents 9f42774 + bdb0caf commit 78ca8c5
Show file tree
Hide file tree
Showing 12 changed files with 78 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Additional Information</title>
<meta name="generator" content="Adobe RoboHelp 2020" />
<meta name="generator" content="Adobe RoboHelp 2022" />
<link rel="stylesheet" href="../assets/css/default.css" type="text/css" />
<script src="../assets/scripts/main_script.js" type="module"></script>
<meta name="rh-authors" content="Mark Alexander" />
Expand All @@ -18,7 +18,6 @@ <h1><span data-field="title" data-format="default">Additional Information</span>
<p>This section of the manual contain a collection of miscellaneous articles related to programming and the way the GameMaker Language works. The following articles are designed as companion articles to further expand your understanding of how GameMaker works and how to get the most from the different language features available:</p>
<ul class="colour">
<li><a href="Best_Practices_When_Programming.htm">Best Practices When Programming</a></li>
<li><a href="The_File_System.htm">The File System</a></li>
<li><a href="Bitwise_Operators.htm">Bitwise Operators</a></li>
<li><a href="Type_Tables.htm">Type Tables</a></li>
<li><a data-xref="{title}" href="Whitespace_Characters.htm">White-space Characters</a></li>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ <h1>Best Practices When Programming</h1>
<div class="buttons">
<div class="clear">
<div style="float:left">Back: <a href="Additional_Information.htm">Additional Information</a></div>
<div style="float:right">Next: <a href="The_File_System.htm">The File System</a></div>
<div style="float:right">Next: <a href="Bitwise_Operators.htm">Bitwise Operators</a></div>
</div>
</div>
<h5><span data-keyref="Copyright Notice">© Copyright YoYo Games Ltd. 2023 All Rights Reserved</span></h5>
Expand Down
39 changes: 23 additions & 16 deletions Manual/contents/Additional_Information/The_File_System.htm
Original file line number Diff line number Diff line change
Expand Up @@ -15,34 +15,41 @@
<body>
<!--<div class="body-scroll" style="top: 150px;">-->
<h1><span data-field="title" data-format="default">The File System</span></h1>
<p>When using the <a href="../GameMaker_Language/GML_Reference/File_Handling/File_Handling.htm">file system functions</a> or <a href="../Settings/Included_Files.htm">included files</a> with <span data-keyref="GameMaker Name">GameMaker</span> it is vitally important to know exactly how the file system works and what things are going on behind the scenes. To that end, this section is designed to explain and clarify exactly <em>how</em> things are stored, <em>where</em> they are stored and what possible limits or workarounds there may be to this system.</p>
<p>The first and most important thing to note about the file functions is that they are limited - in general and by default - to the <strong>sandbox</strong>. What this means is that <span data-keyref="GameMaker Name">GameMaker</span> <strong>cannot save or load files from anywhere that is not part of the game bundle or the local storage for the device</strong> without <em>explicit </em>input from the user, and even then this input is limited to only Windows, macOS and Ubuntu (Linux) target platforms.</p>
<p>When using the <a href="../GameMaker_Language/GML_Reference/File_Handling/File_Handling.htm">file system functions</a> or <a href="../Settings/Included_Files.htm">included files</a> with <span data-keyref="GameMaker Name">GameMaker</span>, it&#39;s important to know how the file system works and what things are going on behind the scenes. This section is designed to explain and clarify exactly <em>how</em> things are stored, <em>where</em> they are stored and what possible limits or workarounds there may be to this system.</p>
<p>The first thing to note about the file functions is that they are limited - in general and by default - to the <strong>sandbox</strong>. What this means is that <span data-keyref="GameMaker Name">GameMaker</span> <strong>cannot save or load files from anywhere that is not part of the game bundle or the local storage for the device</strong> without <em>explicit </em>input from the user, and even then this input is limited to only Windows, macOS and Ubuntu (Linux) target platforms.</p>
<p class="note"><span data-conref="../assets/snippets/Tag_important.hts"> </span> It is possible to turn off sandboxing on the Desktop targets (Windows, macOS, and Ubuntu) by checking the <strong>Disable file system sandbox</strong> option in the <a data-xref="{title}" href="../Settings/Game_Options.htm">Game Options</a> for the target platform. You do this at your own risk, and while this will open up file saving and loading and permit you to access files anywhere on the given system, it may still be limited by the OS permissions.</p>
<h2>File Areas</h2>
<p>To understand the sandbox first of all you need to understand that there are two distinct areas for files:</p>
<ul class="colour">
<li><strong>The File Bundle</strong> - this is where all the files that are packaged with the executable game are stored, including the files that you have added to the <strong>Included Files</strong> asset list from the <span data-keyref="GameMaker Name">GameMaker</span> IDE (which are the external files that you want packaged with the game).</li>
<li><strong>The Save Area</strong> - this is an area of device storage that can be safely written to by the game and the game is guaranteed that this is a writable area.</li>
<li><strong>The File Bundle</strong> - This is where all the files that are packaged with the executable are stored, including the files that you have added to the <strong>Included Files</strong> asset list from the <span data-keyref="GameMaker Name">GameMaker</span> IDE (which are the external files that you want packaged with the game). This area can be accessed through the <span class="inline2"><a data-xref="{title}" href="../GameMaker_Language/GML_Reference/File_Handling/File_Directories/working_directory.htm">working_directory</a></span> variable, however, files will be read from this location automatically when reading, without explicitly needing a path - this is explained more in the next section.</li>
<li><strong>The Save Area</strong> - This is an area of device storage that can be safely written to by the game and the game is guaranteed that this is a writable area. This can be accessed through the <span class="inline2"><a data-xref="{title}" href="../GameMaker_Language/GML_Reference/General_Game_Control/game_save_id.htm">game_save_id</a></span> variable, however files will be read from this location too automatically when reading, and any saves are done here by default.</li>
</ul>
<p>The following diagram may help you to visualise this better:</p>
<p><img alt="File System Save Areas" class="center" src="../assets/Images/Scripting_Reference/Additional_Information/Files_SaveAreas.png" /></p>
<p>When your game is sandboxed, the two target areas - the bundle directory and the local storage area - are available on each target platform, but on each one they will work slightly differently. However <span data-keyref="GameMaker Name">GameMaker</span> has abstracted out the main essence of what can and can&#39;t be done, making it easier to re-target games to multiple environments.</p>
<p>To start with, you should understand what is meant when we talk of the <a href="../GameMaker_Language/GML_Reference/File_Handling/File_Directories/working_directory.htm"><span class="inline2">working_directory</span></a>. This is a synonym for the two possible save locations (as illustrated by the diagram above) and when you use that directory it will do one of two things depending on whether you are reading or writing, and whether the file you are reading from has been changed or not:</p>
<h2 id="h1">Accessing File Areas</h2>
<p>When your game is sandboxed, only the two target areas - <strong>the file bundle</strong> and <strong>the save area</strong> - are available on each target platform, but on each one they will work slightly differently. However <span data-keyref="GameMaker Name">GameMaker</span> has abstracted out the main essence of what can and can&#39;t be done, making it easier to re-target games to multiple environments.</p>
<p>To start with, let&#39;s look at how files are looked up in <span data-keyref="GameMaker Name">GameMaker</span>, say if you do a read:</p>
<p class="code">buf = buffer_load(&quot;my_file.dat&quot;);</p>
<p>or a write:</p>
<p class="code">buffer_save(buf, &quot;my_file.dat&quot;);</p>
<p>This will do one of two things depending on whether you are reading or writing:</p>
<ul class="colour">
<li><strong>Reading Operations</strong> - <span class="inline2">working_directory</span> will first check the save area to see if the file being accessed is there, and if it is uses that. However if the file does not exist in the save area, it then checks the file bundle area and uses that (if the file being looked for is an included file with your game).</li>
<li><strong>Writing Operations</strong> - This can only happen in the save area.</li>
<li><strong>Reading Operations</strong> - This will first check the <a href="../GameMaker_Language/GML_Reference/General_Game_Control/game_save_id.htm">save area</a> to see if the file being accessed is there, and if it is, it uses that. However if the file does not exist in the save area, it then checks the <a href="../GameMaker_Language/GML_Reference/File_Handling/File_Directories/working_directory.htm">file bundle area</a> and uses that (if the file being looked for is an <a href="../Settings/Included_Files.htm">Included File</a> with your game).</li>
<li><strong>Writing Operations</strong> - This can only happen in the save area, unless the sandbox is disabled and a path outside the save area is explicitly specified.</li>
</ul>
<p class="note"><span data-conref="../assets/snippets/Tag_note.hts"> </span> In general <span data-keyref="GameMaker Name">GameMaker</span> will handle all this for you and you <strong>rarely </strong>need to use the <span class="inline2"><a data-xref="{title}" href="../GameMaker_Language/GML_Reference/File_Handling/File_Directories/working_directory.htm">working_directory</a></span> built-in variable.</p>
<p>Using these two simple rules we can now see how the following functions work (these are examples to help you to visualise the process for the different functions available):</p>
<ul class="colour">
<li><span class="inline3_func"><a data-xref="{title}" href="../GameMaker_Language/GML_Reference/File_Handling/File_Directories/directory_create.htm">directory_create</a></span> (and the other directory functions) will only work in the <strong>save </strong>area.</li>
<li>the <a href="../GameMaker_Language/GML_Reference/File_Handling/File_System/File_System.htm">file system functions</a> will return information on files from <em>both </em>the <strong>bundle </strong>and the <strong>save </strong>area, but will only <em>write </em>to the <strong>save </strong>area.</li>
<li>the functions for writing text, binary or INI files will create a new file in the save area if one does not already exist, copying over any information from the original files included with the game bundle should they exist. Note that the original files will still remain in the read-only part of the save directory, but they won&#39;t be referenced as long as a version exists in the read/write section of the save area.</li>
<li>The <a href="../GameMaker_Language/GML_Reference/File_Handling/File_System/File_System.htm">file system functions</a> will return information on files from <em>both </em>the <strong>bundle </strong>and the <strong>save </strong>area, but will only <em>write </em>to the <strong>save </strong>area.</li>
<li>The functions for writing text, binary or INI files will create a new file in the save area if one does not already exist, copying over any information from the original files included with the game bundle should they exist. Note that the original files will still remain in the read-only part of the save directory, but they won&#39;t be referenced as long as a version exists in the read/write section of the save area.</li>
</ul>
<p>On the <strong>Windows</strong>, <strong>macOS </strong>and <strong>Ubuntu</strong> (Linux) platforms there are two ways to save and load files from outside of the sandbox and that is either using the functions <span class="inline3_func"><a data-xref="{title}" href="../GameMaker_Language/GML_Reference/File_Handling/File_System/get_open_filename.htm">get_open_filename</a></span> and <span class="inline3_func"><a data-xref="{title}" href="../GameMaker_Language/GML_Reference/File_Handling/File_System/get_save_filename.htm">get_save_filename</a></span> (both of these functions will require that the user select an area for loading and saving and the return string can then be used in the rest of the file functions to bypass the sandbox - see the function descriptions for more details). The other way is to disable the sandbox altogether from the <a data-xref="{title}" href="../Settings/Game_Options.htm">Game Options</a> for the target platform (only available for Desktop targets, as discussed further up this page).</p>
<h2>Outside The Sandbox</h2>
<p>On the <strong>Windows</strong>, <strong>macOS </strong>and <strong>Ubuntu</strong> (Linux) platforms there are two ways to save and load files from outside of the sandbox and that is either using the functions <span class="inline3_func"><a data-xref="{title}" href="../GameMaker_Language/GML_Reference/File_Handling/File_System/get_open_filename.htm">get_open_filename</a></span> and <span class="inline3_func"><a data-xref="{title}" href="../GameMaker_Language/GML_Reference/File_Handling/File_System/get_save_filename.htm">get_save_filename</a></span> (both of these functions will require that the user select an area for loading and saving, and the returned string can then be used in the rest of the file functions to bypass the sandbox - see the function descriptions for more details). The other way is to disable the sandbox altogether from the <a data-xref="{title}" href="../Settings/Game_Options.htm">Game Options</a> for the target platform (only available for Desktop targets, as discussed further up this page).</p>
<p>On <strong>HTML5</strong> it is also possible to load files from outside the sandbox from a server, however this should only be done using the function <span class="inline3_func"><a data-xref="{title}" href="../GameMaker_Language/GML_Reference/Buffers/buffer_load_async.htm">buffer_load_async</a></span> as loading synchronously has been deprecated on most browsers and will eventually be obsoleted. This means that files being loaded in this way should be saved as binary files - for example, you can save an <span class="inline">*.ini</span> as a string (see <span class="inline3_func"><a data-xref="{title}" href="../GameMaker_Language/GML_Reference/File_Handling/Ini_Files/ini_close.htm">ini_close</a></span> for details) and then write that into a buffer which can then be saved and loaded using the async functions. Note that if you are loading images using <span class="inline3_func"><a data-xref="{title}" href="../GameMaker_Language/GML_Reference/Asset_Management/Sprites/Sprite_Manipulation/sprite_add.htm">sprite_add</a></span> then these are already dealt with asynchronously.</p>
<p>You should also know that each target platform has its own save area where files and directories can be written to and read from. Below is a list of those areas for each target when sandboxed:</p>
<h2 id="h">Save Area Locations</h2>
<p>Each target platform has its own save area where files and directories can be written to and read from. Below is a list of those areas for each target when sandboxed:</p>
<ul class="colour">
<li><strong>Windows</strong>: Windows has all files in the <span class="inline">%localappdata%\&lt;Game Name&gt;</span> directory (on Windows 7 this is the <span class="inline">/Users/&lt;User Name&gt;/AppData/Local/&lt;Game Name&gt;</span> directory).</li>
<li><strong>Windows</strong>: Windows has all files in the <span class="inline">%localappdata%\&lt;Game Name&gt;</span> directory (on Windows this is the <span class="inline">/Users/&lt;User Name&gt;/AppData/Local/&lt;Game Name&gt;</span> directory).</li>
<li><strong>HTML5</strong>,<strong> GX.games</strong>: Everything is done through the local storage.</li>
<li><strong>macOS</strong>: Storage will depend on whether the application is sandboxed or not (following Apple&#39;s rules, with the path usually being <span class="inline">~/Library/Application Support/&lt;Game Name&gt;</span>).</li>
<li><strong>Ubuntu (Linux)</strong>: Files are stored in the <span class="inline">Home/.config/gamename</span> where &quot;Home&quot; is the users home directory - <span class="inline">/home/&lt;username&gt;</span></li>
Expand All @@ -55,8 +62,8 @@ <h1><span data-field="title" data-format="default">The File System</span></h1>
<div class="footer">
<div class="buttons">
<div class="clear">
<div style="float:left">Back: <a href="Additional_Information.htm">Additional Information</a></div>
<div style="float:right">Next: <a href="Bitwise_Operators.htm">Bitwise Operators And Binary</a></div>
<div style="float:left">Back: <a href="../Settings/Game_Settings.htm">GameMaker Runner</a></div>
<div style="float:right">Next: <a href="../Settings/Audio_Groups.htm">Audio Groups</a></div>
</div>
</div>
<h5><span data-keyref="Copyright Notice">© Copyright YoYo Games Ltd. 2023 All Rights Reserved</span></h5>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@
<body>
<!--<div class="body-scroll" style="top: 150px;">-->
<h1><span data-field="title" data-format="default">program_directory</span></h1>
<p>This function returns the directory where the game executable is stored. However, this may not always be useful, particularly as some devices run the exe from a *.zip file, so this would return the same no matter where the game is actually running from.</p>
<p class="note"><b><span data-conref="../../../../assets/snippets/Tag_warning.hts"> </span> </b>This function may not work as you expect due to <span data-keyref="GameMaker Name">GameMaker</span> being sandboxed! Please see the section on <a data-xref="{title}" href="../../../../Additional_Information/The_File_System.htm">The File System</a> for more information.</p>
<p class="note"><span data-conref="../../../../assets/snippets/Tag_warning.hts"> </span> <span data-keyref="GameMaker Name">GameMaker</span> doesn&#39;t limit writing to this directory so whether this is possible depends on OS permissions. It is however discouraged that you write to <span class="inline2"><span data-field="title" data-format="default">program_directory</span></span>, as it is possible to damage the game installation this way.</p>
<p>This function returns the directory where the game&#39;s runner (executable) is stored. However, this may not always be useful, particularly as some devices run the executable from a *.zip file, so this would return that location no matter where the extracted executable is actually running from.</p>
<p>This is different from <span class="inline2"><a data-xref="{title}" href="working_directory.htm">working_directory</a></span>, which stores where the game&#39;s files are stored, however by default they are in the same location.</p>
<div data-conref="../../../../assets/snippets/Note_Warning_GM_FileSystem_Sandboxed.hts"> </div>
<div data-conref="../../../../assets/snippets/Warning_directory_os_permissions.hts"> </div>
<div data-conref="../../../../assets/snippets/Note_Variable_Contains_Path_Including_Final_Slash.hts"> </div>
<p> </p>
<h4>Syntax:</h4>
Expand Down
Loading

0 comments on commit 78ca8c5

Please sign in to comment.