<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: BibleClinger</title>
    <description>The latest articles on DEV Community by BibleClinger (@bibleclinger).</description>
    <link>https://dev.to/bibleclinger</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1347627%2F35a3da4b-aee4-4ad9-aa6b-a1632a6e273d.jpg</url>
      <title>DEV Community: BibleClinger</title>
      <link>https://dev.to/bibleclinger</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bibleclinger"/>
    <language>en</language>
    <item>
      <title>Game Tank 65C02 RESET Pitfalls</title>
      <dc:creator>BibleClinger</dc:creator>
      <pubDate>Sat, 13 Jun 2026 00:00:23 +0000</pubDate>
      <link>https://dev.to/bibleclinger/game-tank-65c02-reset-pitfalls-3nhi</link>
      <guid>https://dev.to/bibleclinger/game-tank-65c02-reset-pitfalls-3nhi</guid>
      <description>&lt;p&gt;I love the 6500 family of processors. Unfortunately, there aren't many modern systems out there that are equipped with a 6502 or any of its descendants. Enter &lt;a href="https://gametank.zone/" rel="noopener noreferrer"&gt;the Game Tank&lt;/a&gt;. It's a new, 8-bit console (equipped with &lt;em&gt;two&lt;/em&gt; Western Digital 65C02's) that is, as of the date of this writing, supposed to be brought into production soon this year. "New" and "8-bit" aren't usually heard in the same sentence in the year 2026, but here we are, and I'm completely here for it.&lt;/p&gt;

&lt;p&gt;Writing 6502 assembly code can be incredibly difficult, even though the chip is a joy to write for -- at least as far as assembly languages go. The Game Tank does sport &lt;a href="https://github.com/clydeshaffer/gametank_sdk" rel="noopener noreferrer"&gt;a C SDK&lt;/a&gt;, &lt;a href="https://github.com/dwbrite/gametank-sdk" rel="noopener noreferrer"&gt;a Rust SDK&lt;/a&gt;, and even &lt;a href="https://github.com/fetchingcat/gametank_basic_sdk" rel="noopener noreferrer"&gt;a BASIC SDK&lt;/a&gt; if you're into any of those languages. While these can be useful, it is my opinion that any developer that works with 6500 processors should write at least one project in assembly in order to better appreciate what is really going on under the hood. It's also probably going to be mandatory to write at least some of your code in assembly if you want to squeeze out every optimization that you can.&lt;/p&gt;

&lt;p&gt;Thankfully, there's lot of information and documentation out there. For programming the 6502 you can visit &lt;a href="https://6502.org/tutorials/" rel="noopener noreferrer"&gt;the 6502.org web site&lt;/a&gt;. If you're looking for assemblers, there's the well-documented &lt;a href="https://cc65.github.io/doc/ca65.html" rel="noopener noreferrer"&gt;ca65 assembler&lt;/a&gt;. Regarding specifics to the Game Tank itself, there is the &lt;a href="https://wiki.gametank.zone/doku.php?id=start" rel="noopener noreferrer"&gt;Game Tank wiki&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Last year I made an attempt at writing a simple program that bounced a rectangle around on the screen of the Game Tank Emulator.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbmzs48i0nn6ogpt8288d.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbmzs48i0nn6ogpt8288d.gif" alt="Bouncing rectangle" width="504" height="505"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's not exactly the game of the century, but as a simple demo to see if I understood how the system worked, it was sufficient.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Pitfalls
&lt;/h2&gt;

&lt;p&gt;Between getting this demo working last year, and now trying slowly to make a Pong variant, I realized how many things can go wrong.&lt;/p&gt;

&lt;p&gt;I present you some common pitfalls in initialization routines for the Game Tank.&lt;/p&gt;

&lt;h3&gt;
  
  
  Initializing Stack RAM in a Routine
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nasm"&gt;&lt;code&gt;&lt;span class="nf"&gt;.proc&lt;/span&gt; &lt;span class="nv"&gt;RESET&lt;/span&gt;
  &lt;span class="nf"&gt;...&lt;/span&gt;
  &lt;span class="nf"&gt;ldx&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="kc"&gt;$&lt;/span&gt;&lt;span class="nv"&gt;ff&lt;/span&gt;        &lt;span class="c1"&gt;; We init the stack&lt;/span&gt;
  &lt;span class="nf"&gt;txs&lt;/span&gt;

  &lt;span class="nf"&gt;jsr&lt;/span&gt; &lt;span class="nv"&gt;ZeroAllRAM&lt;/span&gt;  &lt;span class="c1"&gt;; We init RAM to 0&lt;/span&gt;
  &lt;span class="nf"&gt;...&lt;/span&gt;
&lt;span class="nf"&gt;.endproc&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A classic 6502 error.&lt;/p&gt;

&lt;p&gt;You wrote a RAM initialization routine to set all RAM values in the range $00-$1FFF to 0 so as not to be surprised by random values. Your intentions are good, but the stack lies in the $0100-$01FF range, and &lt;code&gt;jsr&lt;/code&gt; and &lt;code&gt;rts&lt;/code&gt; both rely on this very stack. If you initialized this range to 0 in your routine, then you just clobbered your return address, and you're probably scratching your head wondering why you somehow &lt;code&gt;rts&lt;/code&gt;ed indirectly into your IRQ handler.&lt;/p&gt;

&lt;p&gt;You can fix this in a number of ways. The easiest might be to just zero RAM directly in the RESET handler without using a separate routine.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using RAM Before Initial RAM Banking
&lt;/h3&gt;

&lt;p&gt;The Game Tank can bank RAM, which is a bit novel to me. Which bank is used at startup should be considered random. It is recommended that you initialize this by writing to the Banking Register at $2005 early on in your RESET routine.&lt;/p&gt;

&lt;p&gt;Let's say you remember to bank, but you do it this way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nasm"&gt;&lt;code&gt;&lt;span class="nf"&gt;BANKING_REGISTER&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;2005&lt;/span&gt;
&lt;span class="nf"&gt;.proc&lt;/span&gt; &lt;span class="nv"&gt;RESET&lt;/span&gt;
   &lt;span class="nf"&gt;ldx&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="kc"&gt;$&lt;/span&gt;&lt;span class="nv"&gt;ff&lt;/span&gt;              &lt;span class="c1"&gt;; We initialize the stack&lt;/span&gt;
   &lt;span class="nf"&gt;txs&lt;/span&gt;                   
   &lt;span class="nf"&gt;jsr&lt;/span&gt; &lt;span class="nv"&gt;initValues&lt;/span&gt;        &lt;span class="c1"&gt;; We initialize our game variables&lt;/span&gt;
   &lt;span class="nf"&gt;stz&lt;/span&gt; &lt;span class="nv"&gt;BANKING_REGISTER&lt;/span&gt;  &lt;span class="c1"&gt;; We bank ram&lt;/span&gt;
   &lt;span class="nf"&gt;...&lt;/span&gt;
&lt;span class="nf"&gt;.endproc&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The bug is that you initialized the stack pointer and initialized your game variables before you banked RAM. Assuming that the Game Tank happens to boot with RAM Bank 0 active, you're fine; the other 3/4ths of the time, your RAM, including your stack, will appear uninitialized or even corrupted. This goes from absolute chaos to an easy fix if you can identify that you simply got the order wrong.&lt;/p&gt;

&lt;p&gt;The solution is to set up RAM banking almost immediately -- certainly before stack initialization and variable initialization.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using a Subroutine to Bank RAM
&lt;/h3&gt;

&lt;p&gt;Let's say you have some important game variables in RAM Bank 0, and some more important game variables in RAM Bank 1. You want to initialize all of them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nasm"&gt;&lt;code&gt;&lt;span class="nf"&gt;BANKING_REGISTER&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;2005&lt;/span&gt;
&lt;span class="nf"&gt;.proc&lt;/span&gt; &lt;span class="nv"&gt;RESET&lt;/span&gt;
   &lt;span class="nf"&gt;stz&lt;/span&gt; &lt;span class="nv"&gt;BANKING_REGISTER&lt;/span&gt;  &lt;span class="c1"&gt;; RAM Bank 0&lt;/span&gt;
   &lt;span class="nf"&gt;ldx&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="kc"&gt;$&lt;/span&gt;&lt;span class="nv"&gt;ff&lt;/span&gt;
   &lt;span class="nf"&gt;txs&lt;/span&gt;                   &lt;span class="c1"&gt;; We initialize the stack&lt;/span&gt;
   &lt;span class="nf"&gt;jsr&lt;/span&gt; &lt;span class="nv"&gt;initValuesBank0&lt;/span&gt;   &lt;span class="c1"&gt;; Initialize Bank 0 variables&lt;/span&gt;
   &lt;span class="nf"&gt;jsr&lt;/span&gt; &lt;span class="nb"&gt;Ch&lt;/span&gt;&lt;span class="nv"&gt;angeBank1&lt;/span&gt;       &lt;span class="c1"&gt;; We want to swap to bank 1&lt;/span&gt;
   &lt;span class="nf"&gt;jsr&lt;/span&gt; &lt;span class="nv"&gt;initValuesBank1&lt;/span&gt;   &lt;span class="c1"&gt;; Initialize Bank 1 variables&lt;/span&gt;
   &lt;span class="nf"&gt;...&lt;/span&gt;
&lt;span class="nf"&gt;.endproc&lt;/span&gt;

&lt;span class="nf"&gt;.proc&lt;/span&gt; &lt;span class="nb"&gt;Ch&lt;/span&gt;&lt;span class="nv"&gt;angeBank1&lt;/span&gt;
   &lt;span class="nf"&gt;lda&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="kc"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;01000000&lt;/span&gt;
   &lt;span class="nf"&gt;sta&lt;/span&gt; &lt;span class="nv"&gt;BANKING_REGISTER&lt;/span&gt;  &lt;span class="c1"&gt;; RAM Bank 1&lt;/span&gt;
   &lt;span class="nf"&gt;rts&lt;/span&gt;
&lt;span class="nf"&gt;.endproc&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The problem here is that by swapping to Bank 1, you have completely pulled the stack out from underneath you. Bank 1's stack almost certainly doesn't point to the correct return location, so we never return from &lt;code&gt;ChangeBank1&lt;/code&gt;. Code execution goes somewhere into the unknown.&lt;/p&gt;

&lt;p&gt;The solution might be to avoid RAM banking entirely if you don't really need it. (&lt;strong&gt;Note:&lt;/strong&gt; &lt;em&gt;you should still initialize the banking register!&lt;/em&gt;) It has a layer of complexity to it that really must be taken into account in order to make it useful.&lt;/p&gt;

&lt;p&gt;If you absolutely want to use RAM banking, then the solution might be to redefine &lt;code&gt;ChangeBank1&lt;/code&gt; as a macro, instead of a subroutine to which to &lt;code&gt;jsr&lt;/code&gt;. Don't forget to change back to your main RAM bank immediately afterwards!&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The 6500 family of processors can be fun to program, but being that you'll likely need to touch assembly, a lot can go wrong. It's worth coming up with a reusable, RESET routine that does all of the initial housekeeping.&lt;/p&gt;

&lt;p&gt;Perhaps the next article will be about the things that can go wrong with attempting to use the Game Tank's Blitter...&lt;/p&gt;

</description>
      <category>gametank</category>
      <category>6502</category>
      <category>bug</category>
      <category>pitfalls</category>
    </item>
    <item>
      <title>Star Voyager's Elusive Star Bomb</title>
      <dc:creator>BibleClinger</dc:creator>
      <pubDate>Thu, 04 Jun 2026 12:59:55 +0000</pubDate>
      <link>https://dev.to/bibleclinger/star-voyagers-elusive-star-bomb-5153</link>
      <guid>https://dev.to/bibleclinger/star-voyagers-elusive-star-bomb-5153</guid>
      <description>&lt;p&gt;I've written previously about Star Voyager for the Nintendo Entertainment System. I &lt;a href="https://dev.to/bibleclinger/discovering-a-secret-in-star-voyager-55f9"&gt;first wrote&lt;/a&gt; about the hidden method of triggering the win condition. I &lt;a href="https://dev.to/bibleclinger/star-voyager-damage-system-59af"&gt;then wrote&lt;/a&gt; about what I call the hidden Minor Damage system.&lt;/p&gt;

&lt;p&gt;There are still some interesting secrets buried within this 40 year old game. Today we're going to talk about Star Voyager's Star Bomb.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Upgrades
&lt;/h2&gt;

&lt;p&gt;You have 2 upgrades you can find among the 8 planets. One planet will give you the Hyperdrive Engine, and the other will give you the Super Laser Cannon. The rest of the planets have nothing for you to find.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The Hyperdrive Engine&lt;/strong&gt; gives you much more responsive controls, faster acceleration, and faster warp charging. It's very nice to have, particularly when warping long distances.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Super Laser Cannon&lt;/strong&gt;, in addition to changing your laser weapons fire to the cool blue of your Home Base Station, will majorly buff your damage.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzhy8ov15iv7rumdsjxbg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzhy8ov15iv7rumdsjxbg.png" alt="Docking to get the Star Bomb" width="800" height="752"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There's an additional mysterious upgrade called the Star Bomb. You find it by docking with a monolith in an unknown sector in the 10x10 grid of the galaxy that you're fighting in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Initial Searches for the Monolith
&lt;/h2&gt;

&lt;p&gt;Since the location of the Star Bomb is randomized, and it's not found on your map, players have had to hunt for it. Over the years, it's been realized that we could eliminate certain possibilities. &lt;a href="https://strategywiki.org/wiki/Star_Voyager_(NES)" rel="noopener noreferrer"&gt;StrategyWiki notes&lt;/a&gt;, "The StarBomb is a stationary object, furthermore it is never occupied by a planet or the enemy. While playing the game you can track which sectors are never occupied by the enemy or planets to help limit your search."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuipemwthl90sqh5wy8fq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuipemwthl90sqh5wy8fq.png" alt="The Grid" width="577" height="619"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can also eliminate sectors (B,0), (I,0), (J,0), and (A, 1) from the search. The game is hardcoded to eliminate spawns in those sectors for any stationary object, including the Star Bomb.&lt;/p&gt;

&lt;p&gt;This is all nifty, but even eliminating all objects, planetary orbits, and special zones that still leaves about 42 possible locations. How many more can you eliminate by noting which sectors the enemies have traveled in? And if you wait for the enemies to travel across the galaxy, do you have enough time to search for it? This is why people only seemed to find it at random:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=eRnVUpK9kRM" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=eRnVUpK9kRM&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Star Bomb Found
&lt;/h2&gt;

&lt;p&gt;As it turns out, the devs wanted you to find it all along. They ended up tucking away the secret location within another location -- the Asteroid Belt. They chose this location for good reason. It's one of those sectors you really don't want to visit normally. You are bombarded by asteroids over and over, and even with the Hyperdrive, you may have to take some &lt;a href="https://dev.to/bibleclinger/star-voyager-damage-system-59af"&gt;Minor Damage&lt;/a&gt; in order to escape.&lt;/p&gt;

&lt;p&gt;Nevertheless, lying within the Asteroid Belt is the secret of the Star Bomb. Before warping to the Asteroid Belt, I'd personally recommend that you have your shields up. You take damage fairly quickly once inside the belt. I also would recommend that you have the Hyperdrive Engine already equipped for fast warp charging and overall efficiency.&lt;/p&gt;

&lt;h2&gt;
  
  
  Triggering the Secret
&lt;/h2&gt;

&lt;p&gt;Once you have arrived in the belt, press A or B on Controller 2. Your ship's compass will suddenly snap-align to the location of the Star Bomb. If you can't read it, press Select and look at where your Ship's destination is pointed on the Map. Note this location.&lt;/p&gt;

&lt;p&gt;Now go back to the Cockpit view, and warp out of there. You probably want to perform the fastest warp which will give you a jump distance of 1. Right before your warp is engaged, you can swap to the Map location, select where you actually want to go (again, you'll only have a jump distance of 1), and then go back to the Cockpit view. This should hopefully help you avoid anything dangerous nearby.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Star Bomb Sector
&lt;/h2&gt;

&lt;p&gt;Warp over to the sector your compass had suddenly pointed for you. You'll receive a message, "FAINT SIGNAL RECEIVED." Find the monolith and attempt to dock with it as if it were a planet. It'll rotate, disappear from view, and you'll be informed that you use Controller 2 to fire the Star Bomb.&lt;/p&gt;

&lt;h2&gt;
  
  
  Firing the Star Bomb
&lt;/h2&gt;

&lt;p&gt;The Star Bomb will not fire in a sector that has a station, an asteroid belt, or a planet. It just won't.&lt;/p&gt;

&lt;p&gt;It will, however, fire in an empty sector or in a sector with an enemy. Just press A or B on controller 2, and watch the missile fly away.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0b4r8nlpbdv4a99n2wo9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0b4r8nlpbdv4a99n2wo9.png" alt="Battle with mothership" width="800" height="751"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this screenshot, the Star Bomb is the small blue square launched by the player at the mothership. Upon a successful launch, the message, "FIRE STARBOMB!" scrolls dramatically on the ship's computer screen.&lt;/p&gt;

&lt;p&gt;StrategyWiki, as of the publication date of this article, incorrectly says that "[...] you will get the one and only Star Bomb in the game." In actuality, you get one shot from the Star Bomb per warp. It's as if the Star Bomb is charged by the warp of the Engines. Perhaps this inaccuracy is an attestation to how rare finding the Star Bomb has been for all of these years.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The developers tucked away this secret, but provided a way for players to find it. It's amazing that I've never found how to use the Asteroid Belt to find the Star Bomb until today. How many more secrets are left to be found in this game?&lt;/p&gt;

</description>
      <category>starvoyager</category>
      <category>nes</category>
      <category>secrets</category>
    </item>
    <item>
      <title>Star Voyager Damage System</title>
      <dc:creator>BibleClinger</dc:creator>
      <pubDate>Thu, 04 Jun 2026 09:26:17 +0000</pubDate>
      <link>https://dev.to/bibleclinger/star-voyager-damage-system-59af</link>
      <guid>https://dev.to/bibleclinger/star-voyager-damage-system-59af</guid>
      <description>&lt;p&gt;&lt;a href="https://dev.to/bibleclinger/discovering-a-secret-in-star-voyager-55f9"&gt;Recently I wrote a post&lt;/a&gt; about discovering a secret way to achieve near-instant victory in the notoriously difficult game Star Voyager for the &lt;a href="https://en.wikipedia.org/wiki/Nintendo_Entertainment_System" rel="noopener noreferrer"&gt;Nintendo Entertainment System&lt;/a&gt;. I've been continuing my efforts at reverse engineering aspects of the game, and so far it's been rather enlightening in explaining quite a lot about why this game is so difficult. Today I'd like to talk about the damage system that the game uses.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your Ship's Systems
&lt;/h2&gt;

&lt;p&gt;Your ship has the following 5 systems:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Shields&lt;/li&gt;
&lt;li&gt;Radar&lt;/li&gt;
&lt;li&gt;Laser Cannons&lt;/li&gt;
&lt;li&gt;Engine&lt;/li&gt;
&lt;li&gt;Life Support System&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fak7rv2kdqpopf6vb576y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fak7rv2kdqpopf6vb576y.png" alt="Map Screen of Star Voyager" width="800" height="748"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each of these systems can be damaged during combat with the enemy aliens. You can also take damage to these systems if you end up in an asteroid belt. When a system is damaged, it'll show on the Map screen on the lower left (unless it's the Life Support System). You'll also see the damaged section flashing on the image of your ship on the right. In this screenshot, everything appears fine...&lt;/p&gt;

&lt;h3&gt;
  
  
  Shields
&lt;/h3&gt;

&lt;p&gt;Your &lt;strong&gt;Shields&lt;/strong&gt; are your only means of defense outside of your piloting skills. You should immediately leave combat if your Shields are damaged, since they will become disabled. Suffice it to say that working Shields are supposed to negate 50% of the incoming damage completely. That's a good enough reason to leave and live to fight another day when they aren't available. (We'll skip other details about shields for now.)&lt;/p&gt;

&lt;h3&gt;
  
  
  Radar
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Radar&lt;/strong&gt; uses the right display of the cockpit to show contacts behind you, and it draws a reticle on your HUD for forward contacts. You are well able to pick off motherships and fighters that aren't even rendering by using this forward marking system.&lt;/p&gt;

&lt;h3&gt;
  
  
  Laser Cannons
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Laser Cannons&lt;/strong&gt; are your main means of engaging in combat. Once your Laser Cannons are damaged, they cannot fire. It's time to go get repaired.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2hdjhiuty4imef6jjzci.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2hdjhiuty4imef6jjzci.png" alt="Shooting Lasers" width="800" height="748"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Engine
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Engine&lt;/strong&gt; will operate sluggishly once damaged. In my experience, you can maintain combat status with a damaged Engine. You'll probably want to do this if you're down to the last enemy fighters of an enemy unit with a dead mothership. Otherwise, the enemy you were fighting will regenerate to full health after you warp out, and that isn't fun.&lt;/p&gt;

&lt;h3&gt;
  
  
  Life Support System
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Life Support System&lt;/strong&gt; will deteriorate over time once damaged. You do NOT have a lot of time to do much of anything except find a station and repair. Otherwise, the Life Support System is a passive system that does nothing while operational other than helping you breathe.&lt;/p&gt;

&lt;h2&gt;
  
  
  Damage and Repairs
&lt;/h2&gt;

&lt;p&gt;Your &lt;strong&gt;Shields&lt;/strong&gt;, &lt;strong&gt;Radar&lt;/strong&gt;, and &lt;strong&gt;Laser Cannons&lt;/strong&gt; do not operate once they are considered damaged. As noted above, &lt;strong&gt;Engines&lt;/strong&gt; and &lt;strong&gt;Life Support&lt;/strong&gt; will continue to operate, although you have limited time to repair the Life Support Systems.&lt;/p&gt;

&lt;p&gt;You repair these systems by warping to a station and docking with it. All of the friendly stations can repair this damage completely, except for the Shields, Laser Cannons, and Life Support System. &lt;em&gt;These three systems must be repaired at your Home Base Station.&lt;/em&gt; Your Home Base is easily distinguished in 3D from the other friendly stations by its bright blue color. It's located at coordinate (A,0).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6p8fpe0o0s5n0b4971u5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6p8fpe0o0s5n0b4971u5.png" alt="Home Base" width="800" height="752"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Hidden Damage Mechanic
&lt;/h2&gt;

&lt;p&gt;Often it seemed to me that during a playthrough, the same systems would get damaged in the mid-to-late game. It felt like the enemies were targeting specific systems each playthrough, or perhaps my repair crews weren't doing such a good job fixing me up to get back into the fray.&lt;/p&gt;

&lt;p&gt;Much to my surprise, this was partly true.&lt;/p&gt;

&lt;p&gt;Incoming damage is processed a bit like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;If Shields are on, use the Random Number Generator to drop 50% of all incoming damage (theoretically, at least).&lt;/li&gt;
&lt;li&gt;For the damage that hasn't been dropped, use the Random Number Generator to obtain 1 number with 8 possible values.&lt;/li&gt;
&lt;li&gt;If this randomized value is anywhere from 1 to 5 inclusive, then the damage goes to the specific system in that slot. For values outside of this range, congratulations -- the damage was absorbed by plot armor.&lt;/li&gt;
&lt;li&gt;Invisible damage to systems is capped per system. Once the system meets its cap, the damage becomes visible. Your Shields will turn off, or your Engines will become sluggish, etc. etc.. This is the kind of damage your ship will report, and the kind that has immediate alerts and consequences.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;(The bright side is that after step #4 occurs, damage calculated in step #3 for this slot is now ignored; you have extra plot armor until you repair or die.)&lt;/p&gt;

&lt;p&gt;From here on, I'll refer to the invisible damage as &lt;strong&gt;Minor Damage&lt;/strong&gt; and the visible damage (the kind that the game warns you about) as &lt;strong&gt;Major Damage&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Minor Damage Table
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;RNG Value&lt;/th&gt;
&lt;th&gt;System Hit&lt;/th&gt;
&lt;th&gt;Minor Damage Cap&lt;/th&gt;
&lt;th&gt;Major Damage Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Shields&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Disabled&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Laser Cannons&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;Disabled&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Radar&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Disabled&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Life Support System&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;Disabled. Eventual death.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Engine&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Sluggish&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Repairing Minor Damage
&lt;/h2&gt;

&lt;p&gt;All stations, both Home and friendly, repair only &lt;em&gt;half&lt;/em&gt; of all your Minor Damage across every system per repair session. Interestingly enough, this means friendly stations &lt;em&gt;can&lt;/em&gt; repair Minor Damage even for systems whose Major Damage they can't.&lt;/p&gt;

&lt;h2&gt;
  
  
  An Example of Minor Damage
&lt;/h2&gt;

&lt;p&gt;Let's say that you got into a desperate combat and barely survived. You defeated an enemy, but he left you with Major Damage to both Shields and Engines. Your Minor Damage will be capped at 5 for both systems. Let's say you also, unknown to you, obtained 3 hits to your Radar, and 6 to your Laser Cannons, and 5 to your Life Support System.&lt;/p&gt;

&lt;p&gt;You know that you can't repair Shields at a friendly station, so you warp to your Home Base and dock with it. This repairs the Shields and Engines. Now you think you're fine, but your ship is still worse for the experience.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;System&lt;/th&gt;
&lt;th&gt;Minor Damage Before Repair&lt;/th&gt;
&lt;th&gt;... After Repair&lt;/th&gt;
&lt;th&gt;Hits Left&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Shields&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Radar&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Laser Cannons&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Engine&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Life Support System&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;You should be able to see the problem. You think you're fully repaired, but Your Shields and Engines are more susceptible to being damaged again, each requiring only 3 hits instead of the usual 5. Your Laser Cannons, one of the two strongest items in the game, are now just as weak as your Engines used to be when you started the game!&lt;/p&gt;

&lt;h2&gt;
  
  
  But It Seems Fine
&lt;/h2&gt;

&lt;p&gt;Since Minor Damage is a hidden mechanic, another danger is that you may be inclined to run into multiple battles when you shouldn't. Consider what it would mean if, instead of taking any Major Damage, you took 4 hits to the Shields, 4 to Radar, 7 to your Laser Cannons, 4 to Engines, and 7 to Life Support. Yes, it's improbable, but the point is that you wouldn't see any damage for the time being. The moment you get into the next battle, however, everything on your ship might very well be falling apart!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fak5an7yid37r48jfyoz3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fak5an7yid37r48jfyoz3.png" alt="Warping into battle!" width="800" height="749"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Strategy
&lt;/h2&gt;

&lt;p&gt;In terms of what Minor Damage means for strategy, you should seek to repair between battles, unless you know you didn't take any Minor Damage. To ballpark it, figure for every time the screen showed you getting hit, you took about half of that amount in Minor Damage spread out among your systems. If you know you got through combat without a scratch, great! If you have the fuel to spare as well, you can continue onward to fight another enemy.&lt;/p&gt;

&lt;p&gt;If you took a lot of hits in combat, get to a repair station immediately. If you're going into a tough battle and already have some battle damage, visit two different repair stations. Also, keep in mind, if your Life Support or Laser Cannons have received Major Damage, it'll take &lt;em&gt;four&lt;/em&gt; repair sessions to fully repair everything back to new. You may not have time for that.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmca27x3xu253b9p9t373.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmca27x3xu253b9p9t373.png" alt="The Enemy Approaches!" width="800" height="749"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Star Voyager only tells you about Major Damage, when a system either stops working or begins to work sluggishly. Hidden by the game implementation is what I call a Minor Damage bookkeeping system. Major Damage only occurs to a system once that system takes too much Minor Damage. Every time you dock and repair, only half of each system's Minor Damage is repaired, meaning your may be more likely to sustain Major Damage in subsequent battles unless you repair multiple times.&lt;/p&gt;

&lt;p&gt;In my opinion, having a more complicated damage system made the game more interesting. Hiding this mechanic, however, I think may have been the mistake that made this game feel unfair and too difficult. Knowing about the Minor Damage system allows players to better strategize between getting repairs and saving time.&lt;/p&gt;

</description>
      <category>starvoyager</category>
      <category>nes</category>
      <category>secret</category>
    </item>
    <item>
      <title>Discovering a Secret in Star Voyager</title>
      <dc:creator>BibleClinger</dc:creator>
      <pubDate>Sat, 30 May 2026 01:12:47 +0000</pubDate>
      <link>https://dev.to/bibleclinger/discovering-a-secret-in-star-voyager-55f9</link>
      <guid>https://dev.to/bibleclinger/discovering-a-secret-in-star-voyager-55f9</guid>
      <description>&lt;p&gt;Years ago, I used to play a game for the &lt;a href="https://en.wikipedia.org/wiki/Nintendo_Entertainment_System" rel="noopener noreferrer"&gt;Nintendo Entertainment System&lt;/a&gt; called Star Voyager. The basic premise is simple: you're a pilot of a space fighter, and you need to defeat an armada of aliens who are bent on destroying you and your space station, simply because they are mean.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6140wyimu4q3bhsxs1ta.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6140wyimu4q3bhsxs1ta.png" alt="Image of the game manual's cover" width="800" height="607"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I wasn't very good at it, but there was a lot to it that kept me coming back to play it again over the years. You could dock at space stations and repair and refuel your spaceship. You could land on the eight planets that actually orbit the center of the galaxy. One of these eight contains an upgraded engine, and one contains upgraded weapons -- both of which feel like necessities when fighting enemies that are very difficult. The euphoric feeling of destroying an alien mothership aside, there were other things to it: the exploration, unknown secrets, nagging questions such as, "How &lt;em&gt;do&lt;/em&gt; you escape from a black hole? Can you even do it?" made me keep coming back to try something new. (And yes, apparently you can -- but that isn't what we're discussing today!)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhplioz1x0jec2aemwbuo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhplioz1x0jec2aemwbuo.png" alt="Image of the game's map" width="800" height="752"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The game itself is notoriously difficult. Even with &lt;a href="https://en.wikipedia.org/wiki/Game_Genie" rel="noopener noreferrer"&gt;Game Genie&lt;/a&gt; cheats, and your shields up, your ship takes damage from the aliens fairly easily, especially if you have the tendency to fly in predictable patterns. Many people have given up on the game as a relic that was too difficult in the 90's without the manual and without something that gives you a significant edge.&lt;/p&gt;

&lt;h2&gt;
  
  
  RESET Subroutine
&lt;/h2&gt;

&lt;p&gt;Well, today I think I found the ultimate advantage. While digging into the game with a debugger running, I came across an interesting and noteworthy phenomenon in the code: the game was purposely leaving three bytes uninitialized during a reset -- $07FD-$07FF. Not only that, but two of these values were being read uninitialized and compared against "magic numbers."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxffusaju9bh6asd6jzf0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxffusaju9bh6asd6jzf0.png" alt="Image of code using uninitialized memory" width="333" height="650"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This made me think the game was purposely testing memory to distinguish between a "warm reset" where a player would press the Reset button, and a "cold reset" where a player would turn the console on fresh. As it turns out, not only was this going on, but the game was tracking the amount of resets and storing that number in $07FD.&lt;/p&gt;

&lt;p&gt;But why?&lt;/p&gt;

&lt;h2&gt;
  
  
  Conditions for the Dev Secret
&lt;/h2&gt;

&lt;p&gt;The game considers the first time you power on the system with the game as reset one. It was looking specifically for reset number six. If it was in fact the sixth reset, then it would perform an AND against two values in zero page. If the result of &lt;em&gt;that&lt;/em&gt; wasn't zero, then it would initialize &lt;em&gt;another&lt;/em&gt; value in zero page to zero.&lt;/p&gt;

&lt;p&gt;It actually sounds convoluted if you don't know what the values &lt;em&gt;are&lt;/em&gt; that are being compared. It took me a little bit of time to figure out what exactly the variables being AND'ed represented. Once I did, however, it became abundantly clear what the game was looking for.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ust0ug4etrle23unxgc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ust0ug4etrle23unxgc.png" alt="Image of code that triggers the secret" width="250" height="160"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One of these variables was the 2nd player's controller input. Interesting. Another was an entry within a table of possible input values corresponding to A, B, Select, Start, Up, Down, Left, and Right. Also interesting.&lt;/p&gt;

&lt;p&gt;The game was checking to see if the following conditions were met:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You had reset the console 5 times since the time you originally turned it on with the game loaded.&lt;/li&gt;
&lt;li&gt;You were holding Select on Player Two's controller when the game was loading you into the cockpit.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If these conditions were met, then address $9E, which I dubbed &lt;code&gt;MysteryValue&lt;/code&gt;, would be set to zero. If these conditions were not met, then &lt;code&gt;MysteryValue&lt;/code&gt; would have its previously-set value of nine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trying It Out
&lt;/h2&gt;

&lt;p&gt;Instead of hooking up a second controller, I instead used the debugger to make the above conditions true, right when they needed to be.&lt;/p&gt;

&lt;p&gt;And nothing seemed to happen.&lt;/p&gt;

&lt;p&gt;I checked the map, and I didn't notice anything different.&lt;/p&gt;

&lt;p&gt;I exited the map. A little bit of patience, and soon I got a transmission. The game began to inform me that I had, in fact, already won, despite all of the enemies still being visible on the map.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;MysteryValue&lt;/code&gt; seems to be how many enemies you have left to destroy before victory. By meeting these conditions, we short-circuited the need to destroy them. A better name for the variable might be &lt;code&gt;EnemiesRemaining&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is this here?
&lt;/h2&gt;

&lt;p&gt;In my humble opinion, I think this was a trick way for the devs to test the part of the game after you won. All they had to do was load the game, press reset 5 times, hold down Select on the 2nd controller, and then dock with the space station right next to them. Easy testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Duplicate with Game Genie Code
&lt;/h2&gt;

&lt;p&gt;We can &lt;a href="https://www.youtube.com/watch?v=nJ9zJ_PDatU" rel="noopener noreferrer"&gt;write our own Game Genie code&lt;/a&gt; to set this variable to 0. (If you want to try to write your own codes, &lt;a href="https://games.technoplaza.net/ggencoder/js/" rel="noopener noreferrer"&gt;there are web sites&lt;/a&gt; that can do the bitwise math for you.) Let's look at the relevant section of code where the game initializes $9E (&lt;code&gt;EnemiesRemaining&lt;/code&gt;) to nine during a normal run.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1xlobyerkh6mheohyzka.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1xlobyerkh6mheohyzka.png" alt="Code image where $9E is set to nine." width="270" height="73"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Through the Game Genie, we can change one byte per code. The value of nine is written at address $D546: &lt;code&gt;STX EnemiesRemaining&lt;/code&gt;. The problem is that the value of nine is achieved by first performing a &lt;code&gt;LDX #$0A&lt;/code&gt; at $D53F and then a &lt;code&gt;DEX&lt;/code&gt; at $D545.&lt;/p&gt;

&lt;p&gt;This means there's no easy way to load my own value into X. Decrementing X and storing the result is very efficiently performed in three bytes while a &lt;code&gt;LDX&lt;/code&gt; opcode would take two bytes just to load an immediate value, and the required &lt;code&gt;STX&lt;/code&gt; would take another two.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F317swpo61kp4a6zva7fa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F317swpo61kp4a6zva7fa.png" alt="Status of System Registers" width="494" height="285"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At the moment when X is being decremented, Y is 0. We &lt;em&gt;can&lt;/em&gt; swap &lt;code&gt;STX&lt;/code&gt; with &lt;code&gt;STY&lt;/code&gt; with a single byte change. Let's try it.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;STX&lt;/code&gt; with zero page addressing has a value of $86. &lt;code&gt;STY&lt;/code&gt; with the same addressing has a value of $84. The Game Genie code to swap out $86 and put $84 in its place at address $D546 is &lt;strong&gt;KAKITIVA&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Sure enough, success!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1r32ypsvhjdb8smtvlgy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1r32ypsvhjdb8smtvlgy.png" alt="Victory! Image shows us being called home." width="800" height="746"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just start the game, wait for the message congratulating you for winning, and then dock with the station. Enjoy the credits!&lt;/p&gt;

&lt;h2&gt;
  
  
  Too Easy Now!
&lt;/h2&gt;

&lt;p&gt;Well, yes, fighting no one &lt;em&gt;can&lt;/em&gt; be too easy. What shall we do? We can change the condition so that you must fight one enemy mothership and her fleet before victory is achieved.&lt;/p&gt;

&lt;p&gt;I attempted this by converting the extra &lt;code&gt;DEX&lt;/code&gt; to &lt;code&gt;INY&lt;/code&gt;. This, coupled with our previous Game Genie code, succeeded in increasing Y to 1, and then storing it into &lt;code&gt;EnemiesRemaining&lt;/code&gt;. Unfortunately, changing Y seemed to have other side effects. Despite killing all of the enemies entirely across the galaxy, the game wouldn't end.&lt;/p&gt;

&lt;p&gt;We need to change &lt;code&gt;EnemiesRemaining&lt;/code&gt; ($9E) within a span of 3 bytes, without altering registers. Instead, we can have Game Genie overwrite &lt;code&gt;STX EnemiesRemaining&lt;/code&gt; with &lt;code&gt;INC EnemiesRemaining&lt;/code&gt;, and leave the previous &lt;code&gt;DEX&lt;/code&gt; alone. Since &lt;code&gt;EnemiesRemaining&lt;/code&gt; is initialized to zero at the reset routine, an increment is guaranteed to bump it up to one.&lt;/p&gt;

&lt;p&gt;This approach worked for me, and I achieved victory after destroying one enemy. The Game Genie code is &lt;strong&gt;VTKITIVA&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Keep in mind, if you destroy a second enemy with this code activated, then &lt;code&gt;EnemiesRemaining&lt;/code&gt; will be decremented again, and that will result in you having to defeat $FF enemies. Since there are only nine to begin with, this is impossible to win.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;The developers of Star Voyager included a hidden way of accessing the winning screen.

&lt;ol&gt;
&lt;li&gt;Load the game normally.&lt;/li&gt;
&lt;li&gt;Reset the NES five times.&lt;/li&gt;
&lt;li&gt;On the last restart, you need to hold down Select on Controller Two until you're fully loaded in the cockpit.&lt;/li&gt;
&lt;li&gt;Wait for the victory message, and then dock with the space station.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;You can trigger the same win condition with Game Genie code &lt;strong&gt;KAKITIVA&lt;/strong&gt;. There is no need to reset the console nor to use any input on Controller Two.&lt;/li&gt;

&lt;li&gt;With Game Genie code &lt;strong&gt;VTKITIVA&lt;/strong&gt;, you can trigger the win condition after you defeat one enemy mothership and her fighters.&lt;/li&gt;

&lt;/ol&gt;

&lt;h2&gt;
  
  
  Edit to Provide Proper Credits
&lt;/h2&gt;

&lt;p&gt;It's come to my attention that, while I discovered this secret independently, Geoffrey Lovelace deserves credit for discovering it before me. I came across his video from April 6th, 2024 only after I published my results here. I'll link to his video here:&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/zMIQDXdQV0s"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>starvoyager</category>
      <category>nes</category>
      <category>secret</category>
    </item>
    <item>
      <title>Hunting for a Bug in a Prototype Project</title>
      <dc:creator>BibleClinger</dc:creator>
      <pubDate>Tue, 02 Sep 2025 18:52:05 +0000</pubDate>
      <link>https://dev.to/bibleclinger/hunting-for-a-bug-in-a-prototype-project-2gd2</link>
      <guid>https://dev.to/bibleclinger/hunting-for-a-bug-in-a-prototype-project-2gd2</guid>
      <description>&lt;p&gt;Every now and then, you have to really wonder how you ended up in a situation where you're hunting for a bug that seems impossible to be happening.&lt;/p&gt;

&lt;p&gt;I had decided to submit some pull requests to the &lt;a href="https://github.com/JoeStrout/MS2Prototypes" rel="noopener noreferrer"&gt;prototype project&lt;/a&gt; that Joe Strout is working on for MiniScript 2.0. Among the components of the prototype are an assembly language, an assembler, and a VM to run the assembled byte code. (The latest benchmarks are very promising, by the way, indicating that it is very much possible to get MiniScript into a new era of high speed scripting.)&lt;/p&gt;

&lt;p&gt;Now I already had added a sample factorial assembly program, as well as support in both the assembler and VM for MULT and DIV opcodes. I thought I was getting a quick sense for how the prototype was designed, and what I would need to do to add anything further. Redspark, from the MiniScript Discord, began adding support for more comparison opcodes to the VM. Today, I added support in the assembler for these same comparison opcodes, but in doing so, this is where I came across the unexpected bug.&lt;/p&gt;

&lt;p&gt;I wrote an assembly program to test the opcodes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# A program that tests the comparison operators.
#  0 -&amp;gt; Working
# -1 -&amp;gt; Not working

@main:
    LOAD r0, 0
    LOAD r1, 1

    IFLT r1, r0, error # Testing &amp;lt;
    IFEQ r0, r1, error # Testing ==
    IFNE r0, r0, error # Testing !=
    IFLE r1, r0, error # Testing &amp;lt;=
    RETURN
error:
    LOAD r0, -1
    RETURN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This program should return 0, but it was returning -1, and only due to the line with IFEQ. The new IFEQ opcode was supposed to test if two registers are equal, and if so, jump to the given label. In this case, it was jumping when the results were clearly NOT equal.&lt;/p&gt;

&lt;p&gt;Where to start?&lt;/p&gt;

&lt;p&gt;Well, the assembly program was very simple, and it was in fact correct.&lt;/p&gt;

&lt;p&gt;I checked the code changes I made to the assembler and couldn't find anything wrong. I checked RedSpark's changes to the VM, and I couldn't find anything wrong there either. I began adding some debug print statements -- quick-and-dirty bug fixing isn't pretty and certainly not proper, but it seemed overkill to start figuring things out with a debugger at this point.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxahzdbqiz6bzjzvfnth7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxahzdbqiz6bzjzvfnth7.png" alt="Output from VM 1" width="347" height="64"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well, this wasn't right.&lt;/p&gt;

&lt;p&gt;Why was it executing IFLT instead of IFEQ? I saw two main possibilities. Either:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;the assembler was translating the wrong opcode; or else&lt;/li&gt;
&lt;li&gt;the VM was executing the wrong opcode.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Again, I went over both my changes and RedSpark's changes, but I still couldn't find anything wrong. I needed more information.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frd0p10iyduebgmzrtf4t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frd0p10iyduebgmzrtf4t.png" alt="Output from VM 2" width="348" height="208"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well, this was even more puzzling: the opcodes being produced by my code in the assembler were correct, but they were not matching what the VM was executing. I added even more debug printing in the assembler, and turned on the existing &lt;code&gt;debug&lt;/code&gt; variable in the VM to get even more output:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fryo3fbgtyfyswhfmt8id.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fryo3fbgtyfyswhfmt8id.png" alt="Output from VM 3" width="356" height="304"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I commented out the offending line in the assembly code, and saw the above output. My code was emitting opcodes 7, 9, and 10 correctly, but they were somehow getting to the VM all as opcode 7! Opcode 7 was IFLT, the original comparison opcode. This meant all of the comparison opcodes were somehow being run by the VM as IFLT. Somewhere in between my output from the assembler and the VM's execution, something was going awfully wrong. It was as if something was rewriting my output...&lt;/p&gt;

&lt;p&gt;... and that's exactly what was happening. A little bit of background first, though. All of these comparison opcodes take 3 arguments: 2 registers for comparison, and then an offset to jump if the comparison is true. The offset can be either an immediate value (ie. &lt;code&gt;IFEQ r0, r1, 2&lt;/code&gt;), or it can take a label (ie. &lt;code&gt;IFEQ r0, r1, someLabel&lt;/code&gt;). In this case, I was using a label (ie. "error"). When you use a label, it has to be translated into the other format during assembly.&lt;/p&gt;

&lt;p&gt;The bug was actually occurring during the assembler's 2nd pass. When it was translating the label into a direct offset, it was also forcefully rewriting the opcode associated with the line. This part of the code ensured that IFLT was &lt;em&gt;the only&lt;/em&gt; comparison opcode that was being sent off in the final rewrite of the line. Since IFLT was the only comparison opcode around when this part of the project was written, there were no consequences until people decided to start adding more opcodes.&lt;/p&gt;

&lt;p&gt;Programmers often say that programming is about thinking outside of the box. Troubleshooting can be that way, too. I had started with the assumption that the error was most likely going to be in the new code, but it's worth considering that an error can be in existing code that held to assumptions that aren't true anymore.&lt;/p&gt;

&lt;p&gt;Hopefully we see MiniScript 2.0 soon!&lt;/p&gt;

</description>
      <category>miniscript</category>
      <category>miniscript2</category>
      <category>troubleshooting</category>
      <category>bug</category>
    </item>
    <item>
      <title>Timer for MiniScript</title>
      <dc:creator>BibleClinger</dc:creator>
      <pubDate>Tue, 29 Jul 2025 22:29:02 +0000</pubDate>
      <link>https://dev.to/bibleclinger/timer-for-miniscript-2io5</link>
      <guid>https://dev.to/bibleclinger/timer-for-miniscript-2io5</guid>
      <description>&lt;p&gt;If you try to write a game for &lt;a href="https://miniscript.org/MiniMicro/index.html#about" rel="noopener noreferrer"&gt;Mini Micro&lt;/a&gt;, you'll eventually find the need to write timer code. Perhaps you want the player to shoot projectiles of some sort, but you want to limit the rate of fire. Perhaps you want a bomb to explode after 60 seconds. No matter the case, a timer is going to be what you need if you're trying to do things after a set amount of time.&lt;/p&gt;

&lt;p&gt;The essence of a timer is simple. You can do it by storing the amount of time left in the timer, and then subtracting the amount of time passed with each frame from that. This requirement of getting the time passed with each frame means you require a game loop, &lt;a href="https://dev.to/bibleclinger/mini-micro-and-the-game-loop-4aog"&gt;which I wrote about already&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I wrote a Timer class in &lt;a href="https://github.com/BibleClinger/bclib" rel="noopener noreferrer"&gt;my MiniScript library bclib&lt;/a&gt;. This has proven to be very useful to me during my two recent game jams.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example Usage
&lt;/h2&gt;

&lt;p&gt;A simple use of it would be as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"bclib"&lt;/span&gt;

&lt;span class="n"&gt;onTimeout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timer&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt; &lt;span class="s"&gt;"Hello world!"&lt;/span&gt;
    &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quit&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="nf"&gt;

timer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bclib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Timer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="nd"&gt;@onTimeout&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;engine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bclib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Engine&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timer&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This program waits 5 seconds and then prints "Hello world!" to the screen. Simple!&lt;/p&gt;

&lt;p&gt;The arguments to &lt;code&gt;Timer.Create&lt;/code&gt; in this example are simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The amount of time in seconds before the callback function should be called.&lt;/li&gt;
&lt;li&gt;A reference to the callback function, or a map that contains a function called &lt;code&gt;onTimeout&lt;/code&gt;. This is what will be called when the timer goes off.&lt;/li&gt;
&lt;li&gt;Whether or not the timer is considered started. We want it active right away.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There are other options as well, but this is as simple as it gets.&lt;/p&gt;

&lt;p&gt;As for the last two lines, &lt;code&gt;Engine&lt;/code&gt; merely supplies the mechanism for the game loop, as I wrote in the article previously mentioned. Our callback function quits the program by calling &lt;code&gt;engine.quit&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;By the way, you don't need to use &lt;code&gt;Engine&lt;/code&gt; in order to use &lt;code&gt;Timer&lt;/code&gt;, but it does make your life easier in my opinion. Otherwise, you need to call &lt;code&gt;Timer.tick&lt;/code&gt; on every frame yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Another Example
&lt;/h2&gt;

&lt;p&gt;Let's say you have a class called Fighterjet that can fire missiles. You want to have a 5 second cooldown between missile shots for balancing. How might that look?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="n"&gt;Fighterjet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="x"&gt;{}&lt;/span&gt;

&lt;span class="n"&gt;Fighterjet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="nf"&gt;
    instance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;
    &lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;canFireMissile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;
    &lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timerCooldownMissile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bclib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Timer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="nd"&gt;@instance&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;instance&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="nf"&gt;

Fighterjet.fire&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;canFireMissile&lt;/span&gt; &lt;span class="n"&gt;then&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;canFireMissile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timerCooldownMissile&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;
        &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="n"&gt;Fire&lt;/span&gt; &lt;span class="n"&gt;missile&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="n"&gt;goes&lt;/span&gt; &lt;span class="n"&gt;here&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="nf"&gt;

Fighterjet.onTimeout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timer&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;canFireMissile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="nf"&gt;

Fighterjet.tick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="n"&gt;delta&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timerCooldownMissile&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tick&lt;/span&gt; &lt;span class="n"&gt;delta&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="nf"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's assume you have an external mechanic that calls &lt;code&gt;Fighterjet.fire&lt;/code&gt; on your Fighterjet instance when the player attempts to fire a missile. Let's further assume that you have an external source (such as &lt;code&gt;Engine&lt;/code&gt;) calling &lt;code&gt;Fighterjet.tick&lt;/code&gt; every frame.&lt;/p&gt;

&lt;p&gt;In this case, we have a variable, &lt;code&gt;canFireMissile&lt;/code&gt; that determines if the player can fire the missile. We originally have it set to true. When the player fires, the variable is set to false, and the timer is started. The player is unable to fire another missile until the timer goes off, and the &lt;code&gt;Fighterjet.onTimeout&lt;/code&gt; function is called.&lt;/p&gt;

&lt;p&gt;As long as &lt;code&gt;Fighterjet.tick&lt;/code&gt; is being called every frame, this design should be fairly solid.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Timers are essential for many games, if not most. You should definitely have a Timer class in your arsenal of coding tricks. The library I'm working on is still under development, but feel free to check out the &lt;a href="https://github.com/BibleClinger/bclib/wiki/Timer" rel="noopener noreferrer"&gt;Timer page on the Github wiki&lt;/a&gt; for the latest API documentation.&lt;/p&gt;

</description>
      <category>miniscript</category>
      <category>minimicro</category>
      <category>bclib</category>
      <category>timer</category>
    </item>
    <item>
      <title>Mini Micro and The Game Loop</title>
      <dc:creator>BibleClinger</dc:creator>
      <pubDate>Tue, 29 Jul 2025 16:22:10 +0000</pubDate>
      <link>https://dev.to/bibleclinger/mini-micro-and-the-game-loop-4aog</link>
      <guid>https://dev.to/bibleclinger/mini-micro-and-the-game-loop-4aog</guid>
      <description>&lt;p&gt;Sometimes the lack of threads in MiniScript makes programmers wonder how to do multiple things. The MiniScript wiki has &lt;a href="https://miniscript.org/wiki/How_to_do_many_things_at_once" rel="noopener noreferrer"&gt;a good example&lt;/a&gt; of how to do this very thing. I'd like to bring your attention to this particular block of code from that example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="n"&gt;lastTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pressed&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"escape"&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
    &lt;span class="n"&gt;dt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;lastTime&lt;/span&gt;
    &lt;span class="n"&gt;lastTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;
    &lt;span class="n"&gt;updateCounter&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt;   &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="n"&gt;Update&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt;
    &lt;span class="n"&gt;ball&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt;     &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="n"&gt;Update&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;ball&lt;/span&gt;
    &lt;span class="n"&gt;yield&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;while&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The way singlethreaded games work is to employ a single loop just like this one, often called "the main loop" or "the game loop." In the very simplest implementation, you're supposed to be doing all of your game calculations for one frame exactly within the body of the loop, and then sleep for the rest of the frame.&lt;/p&gt;

&lt;p&gt;In this example, we need to update both a counter &lt;em&gt;and&lt;/em&gt; the ball for each frame. This is handled in the loop by the two lines with comments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Engine class
&lt;/h2&gt;

&lt;p&gt;The above loop is easy enough code to write, but it can be tedious to write it over and over again as boilerplate in a lot of programs. Also, sometimes you might have more complicated scenarios where you would like a bit more control over what gets updated without having to write all of that out again.&lt;/p&gt;

&lt;p&gt;I wrote a class for this that I simply called Engine as part of &lt;a href="https://github.com/BibleClinger/bclib" rel="noopener noreferrer"&gt;my MiniScript library called bclib&lt;/a&gt;. It provides a mechanism to handle a game loop and provide updates to each object/function that it is given. It can also handle adding and removing from the update list during runtime.&lt;/p&gt;

&lt;p&gt;The above code block can be replaced with the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"bclib"&lt;/span&gt;

&lt;span class="n"&gt;checkEsc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pressed&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"escape"&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt; &lt;span class="n"&gt;then&lt;/span&gt; &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quit&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="nf"&gt;

engine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bclib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Engine&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="x"&gt;([&lt;/span&gt;&lt;span class="nd"&gt;@updateCounter&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ball&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="nd"&gt;@checkEsc&lt;/span&gt;&lt;span class="x"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Example Breakdown
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Engine.Create&lt;/code&gt; accepts a list. The elements of the list are simply either standalone functions, or else (perhaps preferably) maps that have a &lt;code&gt;tick&lt;/code&gt; or &lt;code&gt;update&lt;/code&gt; function (searched for in that order). You essentially hand it your code to deal with keyboard input, graphics changes, physics input -- whatever you want your game to do.&lt;/p&gt;

&lt;p&gt;In this case, we need two main updates to occur: the &lt;code&gt;updateCounter&lt;/code&gt; function and the &lt;code&gt;ball.update&lt;/code&gt; function. We pass a function reference directly to &lt;code&gt;updateCounter&lt;/code&gt;, but we pass &lt;code&gt;ball&lt;/code&gt; directly, since &lt;code&gt;Engine&lt;/code&gt; will look for and find its &lt;code&gt;update&lt;/code&gt; function. In order to also maintain the condition that the escape key will cause the program to exit, the function &lt;code&gt;checkEsc&lt;/code&gt; is written here, and a function reference to it is passed in to &lt;code&gt;Engine.Create&lt;/code&gt; as well.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;engine.run&lt;/code&gt; is where the main loop happens. It blocks while it is running. When &lt;code&gt;engine.quit&lt;/code&gt; is called, the engine ceases operations once that entire frame cycle has completed, and &lt;code&gt;engine.run&lt;/code&gt; returns.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other features
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Engine&lt;/code&gt; also looks for an &lt;code&gt;init&lt;/code&gt; function belonging to any update object. This allows for any object initialization that needs to be done. This function is entirely optional, and does not need to be provided. Similarly, it looks for an optional &lt;code&gt;deinit&lt;/code&gt; function on any objects that are removed -- or that are still present after &lt;code&gt;Engine.quit&lt;/code&gt; has been called.&lt;/p&gt;

&lt;p&gt;For more information, please see the &lt;a href="https://github.com/BibleClinger/bclib/wiki/Engine" rel="noopener noreferrer"&gt;Engine wiki page&lt;/a&gt; at the github. As the time of this writing, it is still a work in progress, as the library is still being worked on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In order to do multiple things at once in Mini Micro, programmers need a main loop. The &lt;code&gt;Engine&lt;/code&gt; class in the bclib library provides the mechanism to maintain a main loop.&lt;/p&gt;

</description>
      <category>miniscript</category>
      <category>minimicro</category>
      <category>bclib</category>
    </item>
    <item>
      <title>Reflections on Using bclib for Micro Jam #043</title>
      <dc:creator>BibleClinger</dc:creator>
      <pubDate>Wed, 16 Jul 2025 12:17:28 +0000</pubDate>
      <link>https://dev.to/bibleclinger/reflections-on-using-bclib-for-micro-jam-043-gfd</link>
      <guid>https://dev.to/bibleclinger/reflections-on-using-bclib-for-micro-jam-043-gfd</guid>
      <description>&lt;p&gt;This last weekend, I participated in &lt;a href="https://itch.io/jam/micro-jam-043" rel="noopener noreferrer"&gt;Micro Jam #043&lt;/a&gt; in which participants had 48 hours to make a video game. The theme for this particular session, open to interpretation, was Colors. The prerequisite was that the player must not stop moving. I wrote my entry in &lt;a href="https://miniscript.org/" rel="noopener noreferrer"&gt;MiniScript&lt;/a&gt; for &lt;a href="https://miniscript.org/MiniMicro/index.html#about" rel="noopener noreferrer"&gt;Mini Micro&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Having done two previous game jams last year, I figured this could be another case of stress and deadlines where I might spend more time on the engine than the actual game. In order to mitigate that, I decided to work on &lt;a href="https://github.com/BibleClinger/bclib" rel="noopener noreferrer"&gt;my MiniScript library bclib&lt;/a&gt; ahead of time. When that was done, I used it to implement Pong as a test, which was simple enough that I could make a basic implementation in an afternoon.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi1oeth2rjhs3r9rr6d1m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi1oeth2rjhs3r9rr6d1m.png" alt="A screenshot of Insanity Pong" width="800" height="535"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Despite some wonky physics in my Pong clone, I decided my library and I were both ready to venture into Micro Jam #043.&lt;/p&gt;

&lt;h2&gt;
  
  
  Color Smash Tank
&lt;/h2&gt;

&lt;p&gt;I settled on making a game inspired by an old, arcade classic -- &lt;a href="https://en.wikipedia.org/wiki/Smash_TV" rel="noopener noreferrer"&gt;Smash TV&lt;/a&gt;. My game is a top-down shooter, where you play as a runaway tank that can turn left or right. Different colored shapes would come out and attack the tank. The player would need to load the correct ammo (associated by color) to eliminate the enemies. I named it Color Smash Tank.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqpnrja57tj83jvlofk2q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqpnrja57tj83jvlofk2q.png" alt="Screenshot of Color Smash Tank" width="800" height="531"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Reflections
&lt;/h2&gt;

&lt;p&gt;I went into coding battle with an arsenal of classes that proved entirely useful to me. The main four I'll address are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Enum&lt;/li&gt;
&lt;li&gt;Timer&lt;/li&gt;
&lt;li&gt;TextLabel&lt;/li&gt;
&lt;li&gt;Machine&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Enum
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://dev.to/bibleclinger/a-miniscript-enum-class-4pei"&gt;I wrote about this one previously.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While using this class did help me easily keep track of enumerations, I learned that I needed to be careful about similarly named types. &lt;code&gt;eState.GAMEOVER&lt;/code&gt; could be confused for &lt;code&gt;eEvent.GAMEOVER&lt;/code&gt;, despite being entirely different enum types altogether. Thankfully, I caught this bug fairly early when &lt;em&gt;nothing&lt;/em&gt; happened instead of &lt;em&gt;something&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Timer
&lt;/h3&gt;

&lt;p&gt;If you are developing for Mini Micro, you should probably have a Timer class in your arsenal. I had been writing timer code manually in MiniScript previously. This library gave me the freedom to spin up a timer whenever it made sense.&lt;/p&gt;

&lt;p&gt;One interesting thing that I learned is that, in MiniScript, inner functions are very powerful as callbacks. I hadn't been sure when I had designed the Timer class if I wanted to use callback functions or callback objects -- so I decided to support both.&lt;/p&gt;

&lt;h3&gt;
  
  
  TextLabel
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://dev.to/bibleclinger/textlabel-for-mini-micro-a0n"&gt;I wrote about this one also previously.&lt;/a&gt; Its API has changed a bit, and more changes will probably be on the way in the near future. I took advantage of &lt;a href="https://dev.to/bibleclinger/does-miniscript-need-variadic-functions-53a0"&gt;maps as parameters&lt;/a&gt; for &lt;code&gt;TextLabel.Create&lt;/code&gt;'s parameters, which were growing in number as I was adding more features.&lt;/p&gt;

&lt;p&gt;What I learned during the game jam was that I desperately needed alignment options for these TextLabel instances to make the most of them. For example, if you want text centered in the middle of the screen, but you are writing messages of different lengths to the same row and column, then what was once centered in the screen may not be centered later on.&lt;/p&gt;

&lt;p&gt;Unfortunately this was something I couldn't address during development of my entry. My text was a bit misaligned, but the TextLabel class proved very handy to me. With alignment added, the next game jam should be even easier.&lt;/p&gt;

&lt;h3&gt;
  
  
  Machine
&lt;/h3&gt;

&lt;p&gt;Over a year ago, I wrote &lt;a href="https://bibleclinger.itch.io/axr-100-1" rel="noopener noreferrer"&gt;AXR-100: Operation First Wave&lt;/a&gt; which was my first game jam entry in MiniScript for Mini Micro. I ended up writing a lot of state code for it by hand, and it was very messy to me. Without timers, enums, or a state machine, this meant there was a lot of repeat code in order to do similar things all the time.&lt;/p&gt;

&lt;p&gt;With the implementation of this state machine class, I was able to model small state machines quite easily in MiniScript. It scaled well enough that I was able to model the basic lifecycle of the game itself as states, such as loading, displaying the title screen, actually playing the game, and displaying a game over message.&lt;/p&gt;

&lt;p&gt;What I learned during the game jam is that the code that I supply for my states can be rather complicated. States, transitions, and events should definitely be well thought out -- and indeed this library made it very easy for me to describe what I wanted -- but &lt;em&gt;after&lt;/em&gt; that I need also to do my best to keep my state code neat and tidy. Although this might be obvious in theory, in practice this requires the programmer to think very carefully about design choices, such as how certain game objects will interact with other game objects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;If you'd like to play the game, you can do so here: &lt;a href="https://bibleclinger.itch.io/color-smash-tank" rel="noopener noreferrer"&gt;https://bibleclinger.itch.io/color-smash-tank&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you're developing a game for Mini Micro, and feel that these libraries might help you, feel free to check out the library at: &lt;a href="https://github.com/BibleClinger/bclib" rel="noopener noreferrer"&gt;https://github.com/BibleClinger/bclib&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Just please be aware that this library is still under development and may change as time goes on.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>microjam</category>
      <category>miniscript</category>
      <category>minimicro</category>
      <category>bclib</category>
    </item>
    <item>
      <title>TextLabel for Mini Micro</title>
      <dc:creator>BibleClinger</dc:creator>
      <pubDate>Sun, 29 Jun 2025 08:55:43 +0000</pubDate>
      <link>https://dev.to/bibleclinger/textlabel-for-mini-micro-a0n</link>
      <guid>https://dev.to/bibleclinger/textlabel-for-mini-micro-a0n</guid>
      <description>&lt;p&gt;I tested &lt;a href="https://selfish-dev.itch.io/manduka" rel="noopener noreferrer"&gt;a Mini Micro video game currently being developed for a game jam&lt;/a&gt;. A TextDisplay was being used as a combination HUD and debug screen. The health being displayed started at 100%. This was intuitive and made sense. After taking some damage, however, I noticed the player's health became "97%%".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiuitjw8nhlufig76c014.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiuitjw8nhlufig76c014.png" alt="A screenshot of the game in question." width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Not only that, but other oddities are happening. "Ammo" is written as "%mmo", for example.&lt;/p&gt;

&lt;p&gt;What's going on?&lt;/p&gt;

&lt;h2&gt;
  
  
  Mini Micro's TextDisplay
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://miniscript.org/wiki/TextDisplay" rel="noopener noreferrer"&gt;Mini Micro's TextDisplay&lt;/a&gt; is a graphics layer specifically for text only. It is a two-dimensional grid of cells, with each cell accepting a single character. This grid has 68 columns and 26 rows. When you print to a TextDisplay, the TextDisplay prints the string character by character, starting at the row and column that it has stored internally. The starting row and column can be altered easily by the game, which is what is happening in order to print the HUD.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjpwhm61urs56tvkcnxnv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjpwhm61urs56tvkcnxnv.png" alt="TextDisplay visual example" width="800" height="513"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's consider the above screenshot, taken from the MiniScript wiki. If one were to set the TextDisplay's column and row to 30 and 20 respectively and print "Goodbye!" in this state, you would see "Goodbye!orld!" printed on the screen. Printing "Goodbye!" doesn't erase all of the text of "Hello World!" Printing only overwrites the cells that are in its way. In this case, we are only partially overwriting what is on the screen, leaving a mix of new text and old text.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;In the game, this same issue was happening. "100%" is 4 characters. "97%" is only 3 characters. The 4th character from "100%" (which is the '%' character) is never overwritten when "97%" is printed. This results in the extraneous percent character being left on the screen.&lt;/p&gt;

&lt;p&gt;"%mmo" is being written because originally it's written as "Ammo" -- but the string "ZomFrogs left: 100%" line is written chronologically &lt;em&gt;after&lt;/em&gt;. When there isn't enough room to write that final '%' character, it gets written to the next line, obliterating the 'A' in "Ammo".&lt;/p&gt;

&lt;h2&gt;
  
  
  A Worse Problem
&lt;/h2&gt;

&lt;p&gt;These are fairly easy for a player to spot as errors, but what happens when you are dealing with pure numbers? This is where things get much worse.&lt;/p&gt;

&lt;p&gt;Imagine if the player must manage the temperature of a critical piece of equipment in a game. Let's say that 150 degrees (in whatever unit) would be too hot, and the player must act quickly and cool the equipment whenever it is reaching this temperature. If it goes over 150 for too long, the facility is in danger, and the player must abandon the equipment and escape.&lt;/p&gt;

&lt;p&gt;Now let's further say the player sees "142" printed to the HUD. He recognizes that he must correct the issue by cooling the equipment. He does this successfully by bringing the temperature down to 98 degrees. When the HUD is updated, however, "98" is only 2 characters, whereas "142" is 3 characters. Printing "98" on the same row and column will result in a temperature being displayed of 982 degrees! The player might be convinced that he somehow failed and that he needs to escape immediately. Yet, internally, the game logic is treating the temperature as if it's 98 degrees, well within tolerance.&lt;/p&gt;

&lt;p&gt;This sort of mismatch between the internal state of the game vs the feedback given to the player will confuse players endlessly, since it won't always be so clear to them whether the feedback they are receiving is a visual bug or not. If they &lt;em&gt;are&lt;/em&gt; able to tell, then this could simply be a major source of frustration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solutions
&lt;/h2&gt;

&lt;p&gt;We have a number of potential solutions. We could clear the TextDisplay before we write our data, thereby erasing all text and starting fresh. This is a valid solution in many cases, but it can be a bit expensive in terms of performance to erase the TextDisplay every frame of a game when we really only want to erase parts of it.&lt;/p&gt;

&lt;p&gt;We could import the &lt;code&gt;textUtil&lt;/code&gt; module (already included in &lt;code&gt;/sys/lib&lt;/code&gt;) and use &lt;code&gt;clearRow&lt;/code&gt; or &lt;code&gt;clearRect&lt;/code&gt; to clear a limited amount of screen space. This is perhaps a better solution in that you're erasing less than the entire screen, but this requires you to keep track of each area that you need to clear.&lt;/p&gt;

&lt;p&gt;A third solution could be to write the same amount of characters each time no matter what. Health, for example, in the original game mentioned, would &lt;em&gt;always&lt;/em&gt; be written as 4 characters (assuming, of course, that 4 is truly the maximum length it could be). Ninety seven percent would then really be written as "97% " with an extra space appended. This is rather nifty, and relatively efficient if you're dealing with smaller strings whose max lengths you already know.&lt;/p&gt;

&lt;h2&gt;
  
  
  TextLabel
&lt;/h2&gt;

&lt;p&gt;TextLabel is a new class I've added to &lt;a href="https://github.com/BibleClinger/bclib" rel="noopener noreferrer"&gt;my Mini Micro library&lt;/a&gt; to address the underlying issue. As it is brand new, it is subject to change in the API, but the concept behind it should remain the same. It tracks where you want to print, and it knows how many characters you wrote the last time, thereby handling the erasure of previous text.&lt;/p&gt;

&lt;p&gt;The current implementation, as of July 29, 2025, could be used simply like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import "bclib"

health = bclib.TextLabel.Create(text, 55, 25)
health.print "100%"
health.print "97%"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv1e7xot5lmr7pztiosrj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv1e7xot5lmr7pztiosrj.png" alt="Screenshot of TextLabel being updated" width="800" height="537"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Line 1 is just importing the library.&lt;/p&gt;

&lt;p&gt;The next line creates the label. It binds to the TextDisplay pointed to by &lt;code&gt;text&lt;/code&gt;, which by default points to the default TextDisplay used by Mini Micro on startup. If you have a custom TextDisplay that you created, you can bind it to that.&lt;/p&gt;

&lt;p&gt;The next line prints the message at column 55, row 25 of the TextDisplay pointed to by &lt;code&gt;text&lt;/code&gt;, and the line after that updates the text to read "97%". Because it knows the last message was 4 characters long, and the current message being printed is only 3 characters long, it knows to pad the rest of the output with spaces to overwrite only one extra character's worth.&lt;/p&gt;

&lt;p&gt;Also, if you want to clear the label, &lt;code&gt;health.clear&lt;/code&gt; would do the job.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Need
&lt;/h2&gt;

&lt;p&gt;This class could be useful because it achieves the results of the other solutions presented while seriously limiting the amount of work the programmer must do. For each update to the value being printed, the programmer only needs to write one print statement, with little to no calculation.&lt;/p&gt;

&lt;p&gt;Hopefully this class will be updated and finalized in the near future.&lt;/p&gt;

</description>
      <category>textlabel</category>
      <category>minimicro</category>
      <category>miniscript</category>
      <category>bclib</category>
    </item>
    <item>
      <title>A MiniScript Enum Class</title>
      <dc:creator>BibleClinger</dc:creator>
      <pubDate>Mon, 02 Jun 2025 19:51:35 +0000</pubDate>
      <link>https://dev.to/bibleclinger/a-miniscript-enum-class-4pei</link>
      <guid>https://dev.to/bibleclinger/a-miniscript-enum-class-4pei</guid>
      <description>&lt;p&gt;Given that &lt;a href="https://www.miniscript.org/" rel="noopener noreferrer"&gt;MiniScript&lt;/a&gt; is a very minimalistic scripting language, it purposely lacks an Enum type. Its types are Number, String, List, Map, and funcRef (ie. a function reference) -- and that's it.&lt;/p&gt;

&lt;p&gt;That means that when you want to express an Enum type, you may find yourself using magic numbers. You can use Numbers after all -- in fact I would imagine most underlying Enum implementations do in fact use numerical types under the hood -- but if you find yourself writing code like &lt;code&gt;ship.firingMode = 2&lt;/code&gt;, you're probably going to be in for a world of hurt when you try to return to your space shooter game after a six month break. You may not be able to remember the significance, nuances, and intricacies of firing-mode 2 off a quick glance.&lt;/p&gt;

&lt;p&gt;Alternatively, you can use the String type. &lt;code&gt;ship.firingMode = "MISSILE_MODE"&lt;/code&gt; is valid MiniScript and is not a terrible alternative to Numbers, but it could lend itself to some interesting errors if you mistype the string somewhere, since &lt;code&gt;ship.firingMode = "MISSSILE_MODE"&lt;/code&gt; is also valid MiniScript.&lt;/p&gt;

&lt;h2&gt;
  
  
  An Enum class
&lt;/h2&gt;

&lt;p&gt;I decided to implement a simple Enum class in MiniScript. I have &lt;a href="https://github.com/BibleClinger/bclib" rel="noopener noreferrer"&gt;just published it to GitHub&lt;/a&gt; in a library called bclib[1]. I hope to add more items to this library in the near future.&lt;/p&gt;

&lt;p&gt;Let's set up a simple example of how we might use this Enum class in a space shooter. In this theoretical game, our ship can fire off all sorts of different objects, but it can only fire items of one type at a time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"bclib"&lt;/span&gt;

&lt;span class="n"&gt;eShipShootingMode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bclib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Safety Guns Missile Mines Probe"&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;eShipShootingMode&lt;/code&gt; represents your Enum type. We have chosen five firing modes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Safety (ie. Weapons off)&lt;/li&gt;
&lt;li&gt;Guns&lt;/li&gt;
&lt;li&gt;Missile&lt;/li&gt;
&lt;li&gt;Mines&lt;/li&gt;
&lt;li&gt;Probe&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note: we could have passed a list of strings, but in this example, we used a single string as our argument. Either will work. In the case of a single string, the &lt;code&gt;create&lt;/code&gt; function will split the string along spaces.&lt;/p&gt;

&lt;p&gt;Now the ship will need to store its firing mode in a variable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="n"&gt;ship&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="x"&gt;{}&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="n"&gt;Define&lt;/span&gt; &lt;span class="n"&gt;your&lt;/span&gt; &lt;span class="n"&gt;ship&lt;/span&gt; &lt;span class="n"&gt;properties&lt;/span&gt; &lt;span class="n"&gt;here&lt;/span&gt;
&lt;span class="n"&gt;ship&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;firingMode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;eShipShootingMode&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Safety&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="n"&gt;Weapons&lt;/span&gt; &lt;span class="n"&gt;off&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What if the user presses the key for guns? We can switch firing modes easily:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="n"&gt;ship&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;firingMode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;eShipShootingMode&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Guns&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above line should easily convey to any reader of your code what your intention is: you want the ship to have its firing mode set to fire guns.&lt;/p&gt;

&lt;p&gt;Also, trying to set your firing mode to &lt;code&gt;eShipShootingMode.Misssile&lt;/code&gt; (ie. a typo with one too many &lt;code&gt;s&lt;/code&gt; characters) will crash the program straight up when that line is executed. With a String, that won't happen unless you're doing extra error checking.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other Functions
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;bclib.Enum.count&lt;/code&gt;: A function that returns how many members the particular enum type has.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;bclib.Enum.getName&lt;/code&gt;: A function that returns the name instead of the numerical identifier. In our example, &lt;code&gt;eShipShootingMode.getName(eShipShootingMode.Guns)&lt;/code&gt; will return "Guns". This can be useful for logging purposes, for example, as you'd want the string instead of the numerical value when logging, or else you'd need to look up what firing mode 2 is all over again.&lt;/li&gt;
&lt;/ul&gt;







&lt;p&gt;[1] Short for "BibleClinger Library". Not too original, but straightforward.&lt;/p&gt;

</description>
      <category>miniscript</category>
      <category>minimicro</category>
      <category>bclib</category>
    </item>
    <item>
      <title>Adding Basic Animation to a Mini Micro Game</title>
      <dc:creator>BibleClinger</dc:creator>
      <pubDate>Mon, 26 May 2025 05:12:55 +0000</pubDate>
      <link>https://dev.to/bibleclinger/adding-basic-animation-to-a-mini-micro-game-hhk</link>
      <guid>https://dev.to/bibleclinger/adding-basic-animation-to-a-mini-micro-game-hhk</guid>
      <description>&lt;p&gt;Recently on the MiniScript &lt;a href="https://discord.gg/7s6zajx" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;, Dat_One_Dev posted code he was using for &lt;a href="https://youtu.be/FEJEeNP3PsY" rel="noopener noreferrer"&gt;a YouTube video tutorial&lt;/a&gt; on making video games for &lt;a href="https://miniscript.org/MiniMicro/index.html" rel="noopener noreferrer"&gt;Mini Micro&lt;/a&gt;. It was a game where you simply chase a balloon, clicking on it each time it appears. When you click on it, it moves to a new location, waiting for you to repeat the process.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnmnxbcwrkqigjhuymnh7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnmnxbcwrkqigjhuymnh7.png" alt="The Balloon Game" width="800" height="627"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now this got me thinking. As nice of a simple demo as this was (the code wasn't very long -- about 37 lines in the initial version posted on Discord), something about the balloon seemed off. It wasn't moving at all when it was on the screen. Why not make the balloon move a bit and demonstrate a basic animation technique?&lt;/p&gt;

&lt;p&gt;The idea that came to mind first was that we could make the balloon "breathe" -- that is, it would oscillate between shrinking and expanding. Sprites in Mini Micro have a property called &lt;code&gt;scale&lt;/code&gt;. We could subtract and add small amounts to this property on the balloon's sprite to achieve each effect respectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  Variables Required
&lt;/h2&gt;

&lt;p&gt;First we need some variables. Due to how the original script was written[1], I decided to add these as global variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;breatheTime = 1
currentTime = breatheTime
breatheIncrement = 0.01
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;breatheTime&lt;/code&gt; is the amount of time in seconds for the balloon to perform either a shrink or an expansion.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;currentTime&lt;/code&gt; is our current timer. It's how much time is left before we swap between shrinking or expanding.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;breatheIncrement&lt;/code&gt; is how much we want to adjust the scale of the balloon's sprite per tick. In this case, we want to change it by a very small amount, since ticks happen quite frequently -- about 60 times per second.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Breathing Function
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;breathe = function(dt)
    globals.currentTime -= dt
    if currentTime &amp;lt;= 0 then
        globals.breatheIncrement *= -1
        globals.currentTime = breatheTime
    else
        Balloon.scale += breatheIncrement
    end if
end function
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's walk through the code. First, our &lt;code&gt;breathe&lt;/code&gt; function has one parameter -- the delta time. This is the amount of time that has passed since the last tick or last cycle of the game loop.&lt;/p&gt;

&lt;p&gt;We immediately subtract &lt;code&gt;dt&lt;/code&gt; -- or delta time -- from &lt;code&gt;currentTime&lt;/code&gt;, which is the global timer we just created. We then check to see if our timer is less than or equal to 0. If it is, the timer has been triggered. We have gone far enough in shrinking or expanding. It's time to reverse course!&lt;/p&gt;

&lt;p&gt;We reverse course by inverting the sign of &lt;code&gt;breatheIncrement&lt;/code&gt;. This is achieved by simple multiplication of -1. We then reset the timer by setting &lt;code&gt;currentTime&lt;/code&gt; to &lt;code&gt;breatheTime&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;On the other hand, if the timer &lt;em&gt;didn't&lt;/em&gt; reach 0, then we continue our current operation by simply adding &lt;code&gt;breatheIncrement&lt;/code&gt; to &lt;code&gt;Balloon.scale&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Calculating Time
&lt;/h2&gt;

&lt;p&gt;We have our &lt;code&gt;breathe&lt;/code&gt; function, but how do we call it, and how do we pass delta time to it?&lt;/p&gt;

&lt;p&gt;First, almost any game in Mini Micro should do something like this for its main game loop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="n"&gt;lastTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;
    &lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
    &lt;span class="n"&gt;dt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;lastTime&lt;/span&gt;

    &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="n"&gt;Game&lt;/span&gt; &lt;span class="n"&gt;logic&lt;/span&gt; &lt;span class="n"&gt;goes&lt;/span&gt; &lt;span class="n"&gt;here&lt;/span&gt;

    &lt;span class="n"&gt;lastTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
    &lt;span class="n"&gt;yield&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;while&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Within the block where game logic is marked to go, that is where we put code that requires updates per tick -- like &lt;code&gt;breathe&lt;/code&gt;. Our new game loop should look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="n"&gt;lastTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;
    &lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
    &lt;span class="n"&gt;dt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;lastTime&lt;/span&gt;

    &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="n"&gt;Game&lt;/span&gt; &lt;span class="n"&gt;logic&lt;/span&gt; &lt;span class="n"&gt;goes&lt;/span&gt; &lt;span class="n"&gt;here&lt;/span&gt;
    &lt;span class="n"&gt;breathe&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt;

    &lt;span class="n"&gt;lastTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
    &lt;span class="n"&gt;yield&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;while&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The final animation looks like this. Spiffy:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0izzh98eg2410xvddzpn.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0izzh98eg2410xvddzpn.gif" alt="Balloon " width="232" height="198"&gt;&lt;/a&gt;&lt;/p&gt;







&lt;p&gt;[1] Note: Since we're editing someone else's code, the goal is to accomplish what we want by changing as little as possible. We want to work with what exists, not rewrite it, for our purposes.&lt;/p&gt;

</description>
      <category>minimicro</category>
      <category>miniscript</category>
      <category>animation</category>
    </item>
    <item>
      <title>MiniScript's locals, outer, and globals</title>
      <dc:creator>BibleClinger</dc:creator>
      <pubDate>Sun, 06 Apr 2025 21:09:51 +0000</pubDate>
      <link>https://dev.to/bibleclinger/miniscripts-locals-outer-and-globals-1pcn</link>
      <guid>https://dev.to/bibleclinger/miniscripts-locals-outer-and-globals-1pcn</guid>
      <description>&lt;p&gt;Just recently on the &lt;a href="https://discord.gg/7s6zajx" rel="noopener noreferrer"&gt;MiniScript Discord&lt;/a&gt;, someone was asking for support with a function of his that was supposed to modify a variable external to his function -- except it wasn't working. Given how this could be a gotcha, I figured it would be a topic worth exploring here in greater detail.&lt;/p&gt;

&lt;p&gt;Let's say we have a game where the player has an inventory that can only hold one item. We want to have a function that sets the inventory item, which we'll store in a global.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="n"&gt;inventory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"empty"&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;

&lt;span class="n"&gt;setInventory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;inventory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="nf"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's test the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="n"&gt;print&lt;/span&gt; &lt;span class="n"&gt;inventory&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="s"&gt;"empty"&lt;/span&gt;
&lt;span class="n"&gt;setInventory&lt;/span&gt; &lt;span class="s"&gt;"key"&lt;/span&gt;
&lt;span class="n"&gt;print&lt;/span&gt; &lt;span class="n"&gt;inventory&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="s"&gt;"empty"&lt;/span&gt; &lt;span class="o"&gt;????&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What is going wrong? Why is the inventory still empty?&lt;/p&gt;

&lt;p&gt;With code this simple, it should be pretty clear that our function is not setting the global &lt;code&gt;inventory&lt;/code&gt; variable. We might ask for some help, and someone will tell us to change &lt;code&gt;inventory = item&lt;/code&gt; to &lt;code&gt;globals.inventory = item&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Perfect! It works.&lt;/p&gt;

&lt;p&gt;But why?&lt;/p&gt;

&lt;h2&gt;
  
  
  The locals and globals maps
&lt;/h2&gt;

&lt;p&gt;MiniScript has two particular maps worth knowing about right away:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;locals&lt;/li&gt;
&lt;li&gt;globals&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you set a variable by doing, let's say, &lt;code&gt;x = 5&lt;/code&gt;, it's the equivalent of doing &lt;code&gt;locals.x = 5&lt;/code&gt;. This &lt;code&gt;locals&lt;/code&gt; map is built into MiniScript's inner workings.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;globals&lt;/code&gt; is the map that contains all of the variables that are set at global scope. When your script begins to run, if you begin executing code without putting it inside any function, and if it's not an imported module, then the &lt;code&gt;globals&lt;/code&gt; reference points to the same map as the &lt;code&gt;locals&lt;/code&gt; reference.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="n"&gt;locals&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="n"&gt;globals&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;

&lt;span class="n"&gt;print&lt;/span&gt; &lt;span class="n"&gt;locals&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="n"&gt;prints&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If this script is run on its own and outside of any function, then &lt;code&gt;locals.x&lt;/code&gt; and &lt;code&gt;globals.x&lt;/code&gt; are indeed the same variable, because &lt;code&gt;locals&lt;/code&gt; and &lt;code&gt;globals&lt;/code&gt; are the same map. This is &lt;a href="https://dev.to/joestrout/if-locals-globals-38bh"&gt;why you can explicitly test&lt;/a&gt; &lt;code&gt;if locals == globals&lt;/code&gt; in order to run different code, allowing for unit tests in your modules, tests that can be executed on their own but ignored when imported.&lt;/p&gt;

&lt;h2&gt;
  
  
  Outer
&lt;/h2&gt;

&lt;p&gt;There is a third map available called &lt;code&gt;outer&lt;/code&gt;. This one is a bit more niche. It is used for inner functions to access variables local to its outer function.&lt;/p&gt;

&lt;p&gt;When your script first starts (again assuming it's being executed on its own and outside of any function) &lt;code&gt;locals == globals&lt;/code&gt; and &lt;code&gt;locals == outer&lt;/code&gt; and &lt;code&gt;outer == globals&lt;/code&gt; will all resolve to true. Easy enough. This is why you don't usually need to be concerned with &lt;code&gt;outer&lt;/code&gt;, because often enough, even from within a function, &lt;code&gt;outer == globals&lt;/code&gt; will resolve to true.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reading vs Writing
&lt;/h2&gt;

&lt;p&gt;Let's say you are trying to print a variable named &lt;code&gt;total&lt;/code&gt;. How does MiniScript look up the variable?&lt;/p&gt;

&lt;p&gt;MiniScript first searches inside the &lt;code&gt;locals&lt;/code&gt; map. If it doesn't find it, it tries to find it inside the &lt;code&gt;outer&lt;/code&gt; map. If it doesn't find it there, then it tries &lt;code&gt;globals&lt;/code&gt;. Finally, it raises a runtime error if it hasn't been found.&lt;/p&gt;

&lt;p&gt;This is different from writing, in which case, MiniScript always assumes &lt;code&gt;locals&lt;/code&gt; is where you want to write your variables unless you explicitly specify a different map. This is why we can print the value of &lt;code&gt;globals.inventory&lt;/code&gt; without explicitly mentioning &lt;code&gt;globals&lt;/code&gt;, but we can't write to it without the explicit reference.&lt;/p&gt;

&lt;p&gt;Therefore, for reading, you do NOT need to use explicit references to &lt;code&gt;locals&lt;/code&gt;, &lt;code&gt;outer&lt;/code&gt;, or &lt;code&gt;globals&lt;/code&gt; -- &lt;em&gt;unless you are purposely trying to bypass shadowing&lt;/em&gt;. (Although if you are trying to do that, perhaps consider if shadowing is really a good idea for you in the first place.) For writing, you &lt;em&gt;must&lt;/em&gt; explicitly use a reference to the correct map, &lt;em&gt;if&lt;/em&gt; you do NOT wish to use &lt;code&gt;locals&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The order of variable lookup for reading is &lt;code&gt;locals&lt;/code&gt;, then &lt;code&gt;outer&lt;/code&gt;, and then &lt;code&gt;globals&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Variables are written to &lt;code&gt;locals&lt;/code&gt; by default.&lt;/li&gt;
&lt;li&gt;If you want to write to a variable outside of &lt;code&gt;locals&lt;/code&gt;, you must specify the map explicitly, whether &lt;code&gt;outer&lt;/code&gt; or &lt;code&gt;globals&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>miniscript</category>
      <category>globals</category>
      <category>scope</category>
      <category>locals</category>
    </item>
  </channel>
</rss>
