huulong [Lexaloffle Blog Feed]https://www.lexaloffle.com/bbs/?uid=27121 Headless script inconsistently saves file when overwriting existing file <p>Tested version: 0.2.5g</p> <p>When trying to save a new cart by running a cart that contains a <code>save</code> instruction in headless mode, and the target cart already exists, </p> <p>Repro:</p> <p>Create a demo cart demo.p8 with the following <strong>lua</strong> content:</p> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre>save(&quot;demo_inconsistent_save1.p8&quot;) save(&quot;demo_inconsistent_save2.p8&quot;) save(&quot;demo_inconsistent_save3.p8&quot;) save(&quot;demo_inconsistent_save4.p8&quot;) save(&quot;demo_inconsistent_save5.p8&quot;)</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>Then run it headlessly:</p> <p><code>pico8 -x run demo.p8</code></p> <p>The first time, all carts will be generated. On further runs, carts already exist, but only every other cart will be properly overwritten, starting from the second one, namely: demo_inconsistent_save2.p8 and demo_inconsistent_save4.p8</p> <p>Workaround: make sure to remove all existing target carts in your custom script before saving them again.</p> https://www.lexaloffle.com/bbs/?tid=140246 https://www.lexaloffle.com/bbs/?tid=140246 Mon, 19 Feb 2024 15:05:48 UTC Lexaloffle settings: cannot change Offsite Usernames due to Bad Data Format <p>Hey, I tried to add my YouTube channel in my user settings on this website, but each time I click on a field I get an error:</p> <p>Error // Bad Data Format: &lt;!DOCTYPE html&gt;<br /> ...</p> <img style="margin-bottom:16px" border=0 src="/media/27121/2024-02-05 Cannot change SNS names due to Bad Data Format.png" alt="" /> <p>then the field is replaced with [error]</p> <p>The same occurs when checking Cart Listings: Make Favourites Public / Make Likes Public</p> https://www.lexaloffle.com/bbs/?tid=140100 https://www.lexaloffle.com/bbs/?tid=140100 Mon, 05 Feb 2024 18:00:54 UTC Regression: &quot;failed to import spritesheet&quot; error message in terminal removed <p>I had a hard time debugging &quot;Cannot load&quot; error message when running a cartridge with <code>pico8_0.2.5g -run</code>, where the cart contained an <code>import missing_spritesheet.png</code> statement. I thought that &quot;Cannot load&quot; meant &quot;Cannot load cart&quot; but in fact the cart was loaded, only the spritesheet was not. This was due to the spritesheet missing from the carts folder, but I only understood this thanks to an older version of PICO-8, pico8_0.2.2c which would print an extra error message in the console:</p> <p>&gt; failed to import spritesheet; file: /path/to/missing_spritesheet.png</p> <p>Is there a particular reason why the terminal message was removed? To make the terminal cleaner? In this case, could we at least have the full error message in PICO-8 instead?</p> <p>Tested versions:</p> <ul> <li>0.2.2c: &quot;failed to import spritesheet; file: /path/to/missing_spritesheet.png&quot;</li> <li>0.2.5e: nothing is printed in terminal</li> <li>0.2.5g: nothing is printed in terminal</li> </ul> <p>To repro: create a cart with &quot;import dummy.png&quot; (where dummy.png is a file doesn't exist in carts/) and run it with <code>pico8 -run</code> from terminal.</p> https://www.lexaloffle.com/bbs/?tid=55205 https://www.lexaloffle.com/bbs/?tid=55205 Mon, 04 Dec 2023 11:43:54 UTC REORDERED <p> <table><tr><td> <a href="/bbs/?pid=111198#p"> <img src="/bbs/thumbs/pico8_komehara_reordered-0.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=111198#p"> komehara_reordered</a><br><br> by <a href="/bbs/?uid=27121"> huulong</a> <br><br><br> <a href="/bbs/?pid=111198#p"> [Click to Play]</a> </td></tr></table> </p> <p>This is a game I made for the Global Game Jam 2018 on theme &quot;Transmission&quot;, but I never posted it here. In fact, it's the first cartridge I'm posting on the BBS.</p> <p>I wanted to improve it before uploading it, esp. add keyboard-only controls, so that users can play it on a micro-console without mouse... But I never got the time, so I prefer posting the current version here, so at least you can try it on PC or mobile device (using touch for mouse + gamepad overlay).</p> <h2>Concept</h2> <p>REORDERED is a puzzle game inspired by the concept of <em>out-of-order delivery</em> in computer networking. The player must reorder the letters of a message sent from an antenna to another to form another word.</p> <p>To reorder letters, the player must mess up the travel time of some letters by interacting with the environment.</p> <h2>Controls</h2> <p>!! Mouse or touch is required to play !!</p> <ul> <li>Mouse click on Togglable element (green, small eye icon in the center) to toggle it</li> <li>Mouse click on Restart icon to restart level</li> <li>Keyboard press (X) (keyboard X/V/M) to start emitting letters</li> <li>(Debug) Press Arrow Left/Right to go to previous/next level</li> </ul> <h2>Mechanics</h2> <p>To reorder letters, the player must mess up the travel time of some letters by interacting with the environment.</p> <p>A given word is decomposed in letters that are sent at regular intervals from an emitting antenna. A letter travels in straight line until it reaches an element that affects its trajectory. The player can enable and disable those elements in order to guide the letters into a certain direction.</p> <p>Letters eventually arrive on a receiving antenna to compound a word again. Some trajectories being longer than others, letters are effectively reordered by the timely toggling of interactive elements, causing a new word to be created.</p> <h3>Special tiles</h3> <ul> <li>Arrow: changes the direction of a traveling letter. Has a togglable variant.</li> <li>Mirror: reflects direction of a traveling letter. Has a togglable variant.</li> <li>Emitter: shaped as an antenna, it sends the original word, letter by letter</li> <li>Receiver: shaped as a circle (parabola seen from above), it receives the final word, letter by letter.</li> </ul> <p>itch.io link: <a href="https://komehara.itch.io/reordered">https://komehara.itch.io/reordered</a><br /> Code repository link: <a href="https://github.com/hsandt/ggj2018-Transmission">https://github.com/hsandt/ggj2018-Transmission</a></p> https://www.lexaloffle.com/bbs/?tid=47639 https://www.lexaloffle.com/bbs/?tid=47639 Mon, 02 May 2022 16:00:21 UTC Draw tiled rectangle / textured rectangle / tiled sprites <p>Hey, is there a way to draw a rectangle of arbitrary dimension filled with tiled sprites, aka textured rectangle or tiled rectangle? I can of course manually iterate and draw the same sprites many times, but this had very bad performance so I quickly hit over 1 CPU (meaning I'm dropping from 60 to 30 FPS).</p> <p>In other engines, you'd set sprite rendering mode to Tiled and stretch the sprite, resulting in a repeating pattern preserving the sprite original size, instead of stretching the original sprite like sspr.</p> <p>Recently, we got textured lines (tline) and fill patterns (fillp) but there is no direct way to use them to draw tiled sprites.</p> <p>I see some ways to do that, but they are all workarounds, with no one-line solution:<br /> a. iterate on 2D coordinates and draw same sprite with spr() -&gt; bad performance<br /> b. prepare a tilemap of the same sprites and draw them, offset by some camera() with map() -&gt; need to either setup tilemap in data or generate them at runtime, and need to think with reverse offset to set camera properly. Kind of a waste of data if your rectangle is always using the same sprite. Only works if you have spare space in your tilemap (or you must overwrite some tilemap data and restore it later; note that with Big Maps in PICO-8 0.2.4, it's less of an issue)<br /> c. use fillp to set up a binary pattern and use it for rectfill -&gt; only works for binary (2-color) sprites</p> <p>I'm using a. for now, and only drawing sprites visible by at least 1px on screen to spare CPU, but even that costs too much (around 0.7 out of my budget of 0.1! and I need TWO layers of those because the foreground layer has some transparency, so I quickly get over CPU budget).</p> <p>I think I'll be switching to b. for now.</p> <p>Suggestion:</p> <p>sspr() could have an additional argument &quot;render_mode_option&quot;. 0 is default of stretching, 1 is for tiled rendering.</p> https://www.lexaloffle.com/bbs/?tid=47537 https://www.lexaloffle.com/bbs/?tid=47537 Mon, 25 Apr 2022 11:41:07 UTC Running PICO-8 headless script and checking error codes <p>Hi,</p> <p>I'm heavily using .p8 files as headless scripts to automate my export pipeline. It's great, as all commands are available and when running headlessly, you can even save/load which fail in normal GUI mode.</p> <p>However, I noticed that errors are completely silent (unlike GUI mode, which shows error messages). How can I catch PICO-8 errors from within the .p8 script or, as last resort, from the bash script I'm using to <code>pico8 -x</code> the .p8 script?</p> <p>The most commonly failing commands are save(&quot;game.p8.png&quot;) when the PNG is too big, and export(&quot;game.bin/html&quot;) where we're missing an icon or label. When that happens, I must re-run the commands in GUI mode and inspect every error one-by-one. Besides, the commands I manually type are generally slightly different from the script ones (which are very complete with all options) so I'm not exactly sure if I'm reproducing it right.</p> <p>My suggestions:<br /> a. access error code of last native PICO-8 command (like, save, load and export) with a simple function (e.g. err() which returns an int). We could go further by getting the error message too (e.g. errmsg())<br /> b. make all commands return a success bool. Currently, only load does this (undocumented). save and export return nil so I cannot verify success of the operation.<br /> c. Less convenient, but let a bash/shell script running <code>pico8 -x</code> check the final result of the operations (1 for error, 0 for success) and read error messages in some way. This is less convenient as it doesn't pinpoint where the error occurred in the script. Currently, pico-8 cartridge..p8 -export &quot;... game.bin&quot; does print error messages; but it doesn't return 1 on failure (e.g. missing label) so we cannot check that in a bash script.<br /> d. An option for <code>pico8 -x</code> that prints all native command errors as we would see them in the GUI (load -&gt; &quot;could not load&quot; or better &quot;could not load [filename]&quot;, export -&gt; &quot;no icon found, please capture a label or use -i&quot;)</p> https://www.lexaloffle.com/bbs/?tid=47487 https://www.lexaloffle.com/bbs/?tid=47487 Thu, 21 Apr 2022 14:22:39 UTC printh fails with &quot;bad log file name&quot; when filename contains hyphen `-` <p>As noted in one comment on <a href="https://pico-8.fandom.com/wiki/Printh">https://pico-8.fandom.com/wiki/Printh</a> and as I myself experienced during my project, printh seems not to support hyphen/minus character <code>-</code> in file names.</p> <p>Since the only known special filename is &quot;@clip&quot;, I don't see why.</p> <p>It bothers me in my project as my game title is hyphenated and I use it for the logs. Fortunately, the logs are placed in a local folder containing the .p8, so I can name it whatever I want and it won't be mixed up with logs from my other projects.</p> <p>Workaround: underscore <code>_</code> and even space <code> </code> work, so use them instead.</p> <p>Is there a rationale for preventing usage of this character? If not, could it be allowed in a future version of PICO-8?</p> <p>I understand that some characters like colon <code>:</code> are forbidden due to system limitations, but hyphen <code>-</code> is supported on all systems I know of.</p> <p>On the other side, slash <code>/</code> is a risky one but surprisingly, printh does not error directly when you use it. Instead, it will try to write the file, then fail with &quot;printh: could not write file&quot; as the system prevents the operation. Even Windows doesn't accept forward slashes, so I'm not sure why printh would wait for a low-level error on this one.</p> https://www.lexaloffle.com/bbs/?tid=47394 https://www.lexaloffle.com/bbs/?tid=47394 Fri, 15 Apr 2022 19:32:30 UTC reload needs .p8 unlike load, causing .p8.png multi-cartridges project to fail <p>I noticed that load() supports filenames without extensions and will pick filebasename.p8 if it exists, else filebasename.p8.png (I didn't exactly try the priority order, as there is only either a .p8 or .p8.png in my distributed game folder).</p> <p>However, reload() won't work with a file basename. It <em>needs</em> the .p8 or .p8.png extension. When distributing a game both for p8 and png though, you don't know in advance what you'll need, and would need to create two versions of the code, one reloading files in .p8, the other reloading files in .p8.png, for both versions to work. I actually wrote a string replacement script to support them both!</p> <p>It would be nice if reload() supported file basename like load() for this reason. I don't know if this is a bug report or a suggestion, but I would expect reload() to be consistent with load() so I opened this thread in the bug section nevertheless.</p> https://www.lexaloffle.com/bbs/?tid=44255 https://www.lexaloffle.com/bbs/?tid=44255 Sun, 15 Aug 2021 18:29:44 UTC Profiler overlay <p>Hey, I've just triggered with profiling overlay you see in the top-right of the attached screenshot, and I cannot find how I enabled it. It would be nice to use since I was using my own custom profiler (printing stats) so far but this one has a nice graph and shows clearly when I drop to 30 FPS.</p> <img style="margin-bottom:16px" border=0 src="/media/27121/6_2021-08-04 new profiler layout - not sure how I enabled it.png" alt="" /> <p>It really is an overlay, not part of the game. As a matter of fact, taking a screen capture with F1 with ignore the overlay!</p> <p>As a hint, I was reload my game with a script that sends keystrokes Ctrl+R to the PICO-8 window. Maybe I pressed something else, or the keystrokes were not correctly registered at that time, and it triggered another shortcut; which I cannot find at all in the documentation!</p> <p>Note: this happened in the editor, not the runtime binary version of PICO-8.</p> https://www.lexaloffle.com/bbs/?tid=44094 https://www.lexaloffle.com/bbs/?tid=44094 Wed, 04 Aug 2021 18:26:41 UTC mkdir(nil) crashes editor/game <p>Calling this in editor:</p> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre>mkdir(nil)</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>will crash the editor instantly.</p> <p>Opening pico8 in terminal, or running a script in headless mode containing this line (pico8 -x script.p8), allows us to see:</p> <p>Segmentation fault (core dumped)</p> <p>Interestingly, mkdir() (no argument at all) just shows the help, like mkdir without brackets at all.</p> https://www.lexaloffle.com/bbs/?tid=41115 https://www.lexaloffle.com/bbs/?tid=41115 Sat, 09 Jan 2021 17:58:01 UTC Integrated screenshot capture (F1) uses different black color #020408 <p>I noticed that the screenshot captures done with F1 from the editor contain a black color #020408, while a system screenshot will show that PICO-8 uses #000000 while running.</p> <p>This caused some issues as I was editing screen captures, Aseprite noticed that the color didn't match the black color from the PICO-8 palette, and operations like color replacement failed.</p> <p>This may have been the case from the start, and I have no idea how many times I used screenshots in my editing process, possibly mixing &quot;good&quot; and &quot;bad&quot; black together. As they are not distinguishable with bare eyes this may be a problem for later (e.g. I try to fill an area with color bucket but it only colors a small area).</p> <p>I could only find one occurrence of this color, on the PICO-8 Wikipedia talk: <a href="https://en.wikipedia.org/wiki/Talk:Pico-8">https://en.wikipedia.org/wiki/Talk:Pico-8</a></p> <p>Apparently the old page was mentioning #020408 for black. Either it was the old color, or the author checked the colors from an F1 screenshot (and I would have done the same!).</p> <p>I don't know if other colors are different during screenshot.<br /> I don't know if it's intentional for web export, human eye convenience or anything, or if it's just an old value that was not updated.</p> https://www.lexaloffle.com/bbs/?tid=41111 https://www.lexaloffle.com/bbs/?tid=41111 Sat, 09 Jan 2021 15:20:37 UTC Aggressive Lua code minification and debug code stripping <img style="margin-bottom:16px" border=0 src="/media/27121/Minification post image 157.png" alt="" /> <p>Sometimes your cartridge fits in the token count, but not the characters count / compressed size, so you can't export it until you reduce the number of characters in the cartridge. You'd also like to keep comments, meaningful variable names and even debug code where you can, in case you're gonna continue working on the code.</p> <p>One way to do this is to use a build pipeline:</p> <ul> <li>copy your source file(s) to an intermediate directory</li> <li>process file(s) to reduce code size</li> <li>output final cartridge</li> </ul> <p>If you use <a href="https:github.com/dansanderson/picotool">picotool</a> or work with compiled languages, you should be familiar with that process. It may sound a bit overkill for PICO-8, but is very useful if you're stuck in the case mentioned above.</p> <p>This is what I do when working with my custom framework <a href="https://github.com/hsandt/pico-boots">pico-boots</a>, but while I don't think many devs would be interested in using a complete framework for PICO-8 written by somebody else, they may be interested in the <strong>individual processing steps</strong> described below. You can always refer to pico-boots' repository for implementation details.</p> <p><em>Note that I use picotool to build my cartridge from multiple sources, but the techniques I use apply to single files too. For those also using picotool, I'll explain for which Step the processing should be applied: on individual sources (pre-processing) or on the output cartridge (post-processing).</em></p> <h1>Content</h1> <ul> <li>Comment stripping</li> <li>Minification</li> <li>Debug code stripping <ul> <li>Multi-line</li> <li>Single-line</li> </ul></li> <li>Going further</li> </ul> <h1>Comment stripping</h1> <p>Probably the most obvious, you'll want to remove single line (&quot;--&quot;) and block (&quot;--[[ ]]&quot;) comments.</p> <p>I used to do it manually; now the minification step does it for me, so I won't dwell on it. However, if you already use very short variable names but have lots of comments, it's worth trying comment stripping alone.</p> <p>Single line comment stripping is easy to implement in a file processing script, block comment may be a bit trickier.</p> <p><em>Step: pre-processing or post-processing</em></p> <h1>Minification</h1> <p>Code minification mainly consists in variable/key name shortening, space trimming and comment stripping. You can whatever does the job. However, note that minifiers are written for pure Lua and may not like PICO-8 shortcuts such as single-line</p> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre>if(cond) effect</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>and</p> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre>a += 5</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>So you may want to expand those into pure Lua statements, manually or inside your pipeline (don't worry though, minification will often more than make up for the loss of space).</p> <p><em>If you use picotool, note that it generates a single-line &quot;if(cond) effect&quot; during the build. So you'll need to expand that in your pipeline post-processing, just before minification.</em></p> <p>Personally, I use a <a href="https://github.com/hsandt/luamin/tree/feature/pico8">custom branch in my fork</a> of <a href="https://github.com/mathiasbynens/luamin">luamin</a>. It's basically Luamin plus a few features/fixes:</p> <ul> <li>option &quot;--minify-level&quot; for aggressive member minification: useful if you want to minify even attribute and method names (requires extra care!)</li> <li>option &quot;--newline-separator&quot; for partial newline preservation for easier debugging: otherwise the code is a veeery long line and error messages just tell you &quot;assert on line 1&quot; (note that there is only a newline where luamin would put a ';' without the option, so clauses ending with brackets, like function definitions, will still chain into longer lines)</li> <li>works outside the terminal (e.g. in Sublime Text)<br /> (more info on <a href="https://github.com/hsandt/pico-boots#minification">minification</a> and <a href="https://github.com/hsandt/pico-boots#npm">npm</a> in pico-boots README)</li> </ul> <p><em>I know that picotool has a --lua-minify option, but it was too aggressive for me (it minifies even &quot;__call&quot; which breaks metatable logic).</em></p> <p><em>Step: pre-processing or post-processing (but if using aggressive minification, post-processing only so member names are minified the same way across the cartridge)</em></p> <h2>Example</h2> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre>function demo_app.instantiate_gamestates() -- override return {main_menu(), debug_demo(), input_demo(), render_demo()} end function demo_app.on_pre_start() -- override end function demo_app.on_post_start() -- override -- enable mouse devkit input:toggle_mouse(true) ui:set_cursor_sprite_data(visual_data.sprites.cursor) end function demo_app.on_reset() -- override ui:set_cursor_sprite_data(nil) end</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>becomes</p> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre>function n.o()return{i(),j(),k(),l()}end function n.p()end function n.q()g:r(true)h:s(m.t.u)end function n.v()h:s(nil)end</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <h2>Implementation example</h2> <p>There is not much to do since it's already in the Luamin package, which you can get using &quot;npm install/update&quot; (see <a href="https://github.com/hsandt/pico-boots/blob/master/scripts/npm/package.json">package.json</a>).</p> <p>However, if you're working on an actual .p8 cartridge rather than pure Lua code, you may want to extract the lua section, minify it and reinject it back. <a href="https://github.com/hsandt/pico-boots/blob/master/scripts/minify.py">minify.py</a> does precisely that (and also expands single-line &quot;if(cond) effect&quot;).</p> <h2>Possible improvement on luamin for PICO-8</h2> <p>Only use lower characters to generate minified identifiers (see IDENTIFIER_PARTS in <a href="https://github.com/hsandt/luamin/blob/master/luamin.js">luamin.js</a>). Otherwise, since PICO-8 auto-lowers characters when opening code in the integrated editor, it may cause variable conflicts (&quot;Ab&quot; becomes &quot;ab&quot; which may be another variable in scope) or even prevent cartridge from running (&quot;Do&quot; becomes &quot;do&quot; which is a keyword).</p> <h1>Debug code stripping</h1> <h2>Multi-line</h2> <p>You can use whatever you want to flag debug code and remove it for the release build. However, you need some way to tell your pipeline that you are making a <em>debug</em> vs a <em>release</em> build.</p> <p>On my projects, I use generic symbol-based preprocessing similar to the one in C# (or C++), but very much simplified. You define a set of symbols for your current build config (e.g. <em>debug</em> config defines [&quot;assert&quot;, &quot;log&quot;], <em>release</em> config defines nothing). Then you surround parts you don't want in some build configs with special markers:</p> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre>-- will be stripped in release #if log printh(&quot;Player hit!&quot;) printh(&quot;Remaining HP: &quot;..player.hp) #endif</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>During build, any code surrounded by undefined symbols is stripped.</p> <p>Of course, if you don't need one symbol per debug feature like me, you can just define &quot;debug&quot; for the <em>debug</em> config and surround all your debug code with &quot;#if debug&quot; and &quot;#endif&quot;.</p> <p><em>Step: pre-processing or post-processing, but recommend pre-processing to make core build faster, as there would be less code to assemble</em></p> <h3>Example</h3> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre>#if assert assert(damage &gt; 0) #endif player.hp = player.hp - damage #if log printh(&quot;Player hit!&quot;) printh(&quot;Remaining HP: &quot;..player.hp) #endif</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>becomes in <em>release</em> config:</p> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre>player.hp = player.hp - damage</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <h2>Single-line</h2> <p>For single-line, you can write a simple parser that strips line calling certain functions.</p> <p>For instance, I strip all single-line &quot;assert(...)&quot; calls if the &quot;assert&quot; symbol is not defined. It means that in the example above, I don't even need the &quot;#if assert&quot; anymore. It's very convenient when you have many logs and assertions. But multi-line stripping is still useful for more complex behaviors.</p> <p><em>Step: same as multi-line</em></p> <h3>Example</h3> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre>assert(damage &gt; 0) player.hp = player.hp - damage log(&quot;Player hit!&quot;) log(&quot;Remaining HP: &quot;..player.hp)</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>becomes in <em>release</em> config:</p> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre>player.hp = player.hp - damage</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <h2>Implementation example</h2> <p>See both multi-line and single-line stripping in <a href="https://github.com/hsandt/pico-boots/blob/master/scripts/preprocess.py">preprocess.py</a></p> <p>It also contains a reversed stripping tag &quot;--[[#pico8&quot; and &quot;--#pico8]]&quot; that comments out the code until it is built into a cartridge; but that's only useful if you run unit tests in pure Lua.</p> <h1>Going further</h1> <p>If your game has a lot of text, <strong>string compression</strong> is your next step. You can make your own, or check out a tool like <a href="https://github.com/dansanderson/p8advent">p8advent</a> (also see <a href="https://www.lexaloffle.com/bbs/?tid=2776">post</a> which mentions alternative).</p> <p>Also, if you're interested in the full build pipeline I use, check out <a href="https://github.com/hsandt/pico-boots/blob/master/scripts/build_cartridge.sh">the generic build script</a> and <a href="https://github.com/hsandt/pico-boots-demo/blob/master/build_game.sh">the demo project script</a> using the former.</p> https://www.lexaloffle.com/bbs/?tid=36804 https://www.lexaloffle.com/bbs/?tid=36804 Mon, 10 Feb 2020 20:48:59 UTC 0.1.11g Multiline string gets clamped when priting with no coordinates at bottom <p>When printing with no coordinate arguments, text is printed on the next line after the last prompt position. In addition, when the bottom of the screen is reached, all previous graphics are moved upward.</p> <p>It is also possible to print multiple lines at once, and when printed at the bottom, it will also move all previous graphics from multiple lines.</p> <p>However, the lines after the 1st one won't be printed correctly. The 2nd line's bottom half will be hidden, and the lines after that will be invisible.</p> <p>Reproduction:</p> <ol> <li>Start PICO-8</li> <li>Enter <code>print(&quot;1\n2\n3&quot;)</code></li> <li>Repeat until prompt reaches the bottom of the screen</li> <li>Repeat. From then on, &quot;2&quot; will be cut and &quot;3&quot; will be invisible.</li> </ol> <p>Note:</p> <p>This also applies to Lua multiline strings using [[ ]], [==[ ]==], etc. instead of &quot;\n&quot;.</p> https://www.lexaloffle.com/bbs/?tid=32730 https://www.lexaloffle.com/bbs/?tid=32730 Fri, 28 Dec 2018 14:47:12 UTC