๐Ÿ”ฅ Firefly Zero documentation on Firefly Zero docs https://docs.fireflyzero.com/ Recent content in ๐Ÿ”ฅ Firefly Zero documentation on Firefly Zero docs Hugo en-us File formats https://docs.fireflyzero.com/internal/formats/ Mon, 01 Jan 0001 00:00:00 +0000 https://docs.fireflyzero.com/internal/formats/ <h2 id="-rom">๐Ÿ’พ ROM<a class="anchor" href="#-rom">#</a></h2> <p>Running <code>firefly_cli export</code> creates a single-file distribution for an app&rsquo;s ROM. This ROM can be imported back using <code>firefly_cli import</code>.</p> <p>This file is a regular <a href="https://en.wikipedia.org/wiki/ZIP_%28file_format%29" target="_blank" rel="noopener">zip archive</a> with <a href="https://en.wikipedia.org/wiki/Zstd" target="_blank" rel="noopener">zstd</a> compression. Because zstd compression support is added into the zip specification only in 2020, your archive viewer program might not be able to open it.</p> <h2 id="-metadata">๐Ÿท๏ธ Metadata<a class="anchor" href="#-metadata">#</a></h2> <p>The app metadata is stored in <code>_meta</code> and encoded using <a href="https://postcard.jamesmunns.com/wire-format" target="_blank" rel="noopener">Postcard Wire Format</a>. The schema is defined in <a href="https://github.com/firefly-zero/firefly-types/blob/main/src/meta.rs" target="_blank" rel="noopener">firefly-types</a>.</p> File system https://docs.fireflyzero.com/internal/fs/ Mon, 01 Jan 0001 00:00:00 +0000 https://docs.fireflyzero.com/internal/fs/ <ul> <li><code>roms/</code> <ul> <li><code>&lt;AUTHOR_ID&gt;/</code> <ul> <li><code>&lt;APP_ID&gt;/</code> <ul> <li><code>_bin</code>: the main executable WASM binary of the app.</li> <li><code>_meta</code>: the app metadata.</li> <li><code>_key</code>: the app author&rsquo;s public key.</li> <li><code>_hash</code>: the <a href="https://en.wikipedia.org/wiki/SHA-2" target="_blank" rel="noopener">SHA256</a> hash of all files in the directory (both their content and their names) except <code>_sig</code> and <code>_hash</code> itself.</li> <li><code>_sig</code>: the <a href="https://datatracker.ietf.org/doc/html/rfc2313" target="_blank" rel="noopener">PKCS 1 v1.5</a> signature signing the <code>_hash</code> with the author&rsquo;s private key. Can be verified using <code>_key</code>.</li> <li>May also contain any other files (game assets) that the app needs to run.</li> </ul> </li> </ul> </li> </ul> </li> <li><code>data/</code> <ul> <li><code>&lt;AUTHOR_ID&gt;/</code> <ul> <li><code>&lt;APP_ID&gt;/</code> <ul> <li><code>etc/</code>: directory writable by the app. More precisely, the only directory in the whole FS where a non-sudo app can create, modify, list, or delete files. Empty by default. Usually, used to store game saves or assets produced using the app.</li> <li><code>shots/</code>: directory with app screenshots in PNG format.</li> <li><code>stats</code></li> </ul> </li> </ul> </li> </ul> </li> <li><code>sys/</code> <ul> <li><code>priv/</code>: directory with private keys. <ul> <li><code>&lt;AUTHOR_ID&gt;</code>: the author&rsquo;s private key. Used to sign apps when building with <code>firefly_cli build</code>. Private keys are only present on the emulator&rsquo;s virtual file system but never on the device. Use <code>firefly_cli key</code> to manage keys.</li> </ul> </li> <li><code>pub/</code>: directory with public keys. <ul> <li><code>&lt;AUTHOR_ID&gt;</code>: the author&rsquo;s public key. Used to verify signatures of installed ROMs.</li> </ul> </li> <li><code>launcher</code>: short metadata of the launcher. This is the first app that is launched when device/emulator starts.</li> <li><code>new-app</code>: short metadata of the latest installed app. If there is no launcher installed in the system, this is the app that will be launched first when device/emulator starts.</li> <li><code>name</code>: the device name. By default, generated to be unique but users may change the device name. For multiplayer, we require all connected devices to have a unique name to avoid confusion. The name has the same validation rules as author and app IDs and can be at most 16 characters long.</li> </ul> </li> </ul> Getting started https://docs.fireflyzero.com/dev/getting-started/ Mon, 01 Jan 0001 00:00:00 +0000 https://docs.fireflyzero.com/dev/getting-started/ <h2 id="-pick-the-language">๐Ÿ‘‰ Pick the language<a class="anchor" href="#-pick-the-language">#</a></h2> <p>Firefly Zero supports lots of programming languages:</p> <ul> <li>๐Ÿฆ€ Rust</li> <li>๐Ÿƒ Go</li> <li>๐Ÿ€ C and C++</li> <li>โšก๏ธ Zig</li> <li>๐Ÿฐ MoonBit</li> <li>๐ŸŸฆ AssemblyScript (a subset of TypeScript)</li> </ul> <p>Experimental:</p> <ul> <li>๐ŸŒ™ Lua</li> <li>๐Ÿงช Elixir</li> <li>โŒ› Coming soon: more languages (Python, JS, Kotlin).</li> </ul> <p>For simple apps and games, it&rsquo;s a good idea to stick to what you already know. But if you&rsquo;re ready to learn something new for better results, we recommend using Go. It&rsquo;s easy to learn, sufficiently fast, and memory-safe.</p> Installation https://docs.fireflyzero.com/user/installation/ Mon, 01 Jan 0001 00:00:00 +0000 https://docs.fireflyzero.com/user/installation/ <h2 id="-cli">๐Ÿš CLI<a class="anchor" href="#-cli">#</a></h2> <div class="book-tabs"><input type="radio" class="toggle tab" name="tabs-0" id="tabs-0-0" data-name="Linux" checked="checked" /> <label for="tabs-0-0"> ๐Ÿง Linux</label> <div class="book-tabs-content markdown-inner"><p>Choose one of the following:</p> <details open="true true"><summary>Installation script (recommended)</summary><div class="markdown-inner"> <p>Run the following command in the terminal and watch the magic happen:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>bash -c <span style="color:#e6db74">&#34;</span><span style="color:#66d9ef">$(</span>curl https://fireflyzero.com/install.sh<span style="color:#66d9ef">)</span><span style="color:#e6db74">&#34;</span></span></span></code></pre></div></div></details> <details ><summary>Cargo (Rust package manager)</summary><div class="markdown-inner"> <p>If you have <a href="https://doc.rust-lang.org/cargo/" target="_blank" rel="noopener">cargo</a> (the <a href="https://www.rust-lang.org/" target="_blank" rel="noopener">Rust</a> package manager) installed, you can use it to install firefly-cli:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>cargo install firefly_cli</span></span></code></pre></div><p>After that, open <code>~/.bashrc</code> (or <code>~/.zshrc</code> if you use zsh) and add at the end the following:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>alias ff<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;firefly_cli&#34;</span></span></span></code></pre></div></div></details> <details ><summary>Manual</summary><div class="markdown-inner"> <ol> <li> <p><a href="https://github.com/firefly-zero/firefly-cli/releases/latest" target="_blank" rel="noopener">Download the latest release</a>. You need the one containing <code>-linux-</code> in the name. If you don&rsquo;t know which one you need, it&rsquo;s probably the one ending with <code>-x86_64-unknown-linux-gnu.tar.gz</code>.</p> firefly.toml https://docs.fireflyzero.com/dev/config/ Mon, 01 Jan 0001 00:00:00 +0000 https://docs.fireflyzero.com/dev/config/ <p>The <code>firefly.toml</code> configuration file tells firefly-cli how to build a ROM for the project. It should be placed at the root of the project (though you can explicitly specify the path using <code>--config</code>) and must be in the <a href="https://toml.io/en/" target="_blank" rel="noopener">TOML</a> format.</p> <p>Required:</p> <ul> <li><code>author_id</code> (string): your username. It should be unique, otherwise users may get a warning about invalid signature when launching your app. The best way to ensure that your author_id is unique is to add it into <a href="https://catalog.fireflyzero.com/" target="_blank" rel="noopener">catalog.fireflyzero.com</a>. There are also limitations on the length of the ID and used characters. If your ID (or any of the options below) is invalid, the <code>build</code> command will tell you.</li> <li><code>app_id</code> (string): the app ID. Must be unique for the given author. The combination <code>author_id.app_id</code> is the full ID of the app, and that must be globally unique.</li> <li><code>author_name</code> (string): your name. It will be shown in the launcher next to the app name. It must use ASCII Latin alphabet. Non-latin names have to be transliterated.</li> <li><code>app_name</code> (string): the human-readable name of the game. Shown in the launcher. It must use ASCII Latin alphabet. It should use Title Case. For example, &ldquo;The Plant vs the Zombie&rdquo;.</li> </ul> <p>Optional:</p> Callbacks https://docs.fireflyzero.com/dev/callbacks/ Mon, 01 Jan 0001 00:00:00 +0000 https://docs.fireflyzero.com/dev/callbacks/ <p>Callback is a function with a specific name that you define in your code and then the runtime calls it in the right time. None of the callbacks are required but you&rsquo;ll need to define at least one of them for your app to actually do something.</p> <h2 id="-supported-callbacks">๐Ÿ“š Supported callbacks<a class="anchor" href="#-supported-callbacks">#</a></h2> <p>Firefly Zero supports the following callbacks:</p> <ol> <li><code>boot</code> is called only once, after all the memory is initialized and all runtime functions are available but before any other callback is called. This is the best place to load fonts, sprites, and other assets, initialize the default state, read configurations, etc.</li> <li><code>update</code> is called ~60 times per second. It is guaranteed to be never called more often, and it won&rsquo;t be called less often if the game doesn&rsquo;t consume too much resources. This is the best place to update the state of objects, position of NPCs, read and handle user input, etc.</li> <li><code>render</code> is called before updating the image on the screen. It might be called less often than <code>update</code> if the device sees that the game is slow and needs more resources. This is the best place to call all drawing functions.</li> <li><code>before_exit</code> is called before the app is closed.</li> <li><code>cheat</code> handles cheat codes (see <a href="https://docs.fireflyzero.com/dev/debugging/#-cheat-codes">Cheat codes</a>).</li> <li><code>handle_menu</code> is called when a custom menu item is selected.</li> </ol> <img src="https://docs.fireflyzero.com/warn.png" class="hint-icon warning" /> <blockquote class="book-hint warning"> <p><strong>Use the right callback!</strong></p> Emulator https://docs.fireflyzero.com/user/emulator/ Mon, 01 Jan 0001 00:00:00 +0000 https://docs.fireflyzero.com/user/emulator/ <p>The emulator allows you to run any Firefly Zero apps on your computer. To install it, follow the <a href="https://docs.fireflyzero.com/user/installation/">Installation</a> guide.</p> <h2 id="-input">๐Ÿ•น Input<a class="anchor" href="#-input">#</a></h2> <p>The emulator supports the following input methods, from best to worst.</p> <ol> <li>Firefly Zero device</li> <li>Steam controller</li> <li>Gamepad</li> <li>(โŒ› Coming soon) UI buttons</li> <li>Keyboard</li> </ol> <h3 id="-firefly-zero-device">๐Ÿ“ฑ Firefly Zero device<a class="anchor" href="#-firefly-zero-device">#</a></h3> <p>The device can be used as a gamepad (not only for the emulator). See <a href="https://github.com/firefly-zero/firefly-gamepad" target="_blank" rel="noopener">firefly-gamepad</a>.</p> <h3 id="-steam-controller">๐Ÿ’จ Steam controller<a class="anchor" href="#-steam-controller">#</a></h3> <p>It is discontinued but you may find a used one. It has a touchpad just like Firefly Zero, and that makes it a better fit, compared to Xbox controllers, for apps requiring a precise input.</p> Settings https://docs.fireflyzero.com/user/settings/ Mon, 01 Jan 0001 00:00:00 +0000 https://docs.fireflyzero.com/user/settings/ <p>You can change device settings in the &ldquo;System Settings&rdquo; app.</p> <p><strong>Navigation:</strong></p> <ul> <li>Press up or down on the touchpad to move the cursor between available options.</li> <li>Press left or right when the cursor is on the header to switch between tabs.</li> <li>Press <code>E</code> (<code>Enter</code> on emulator) to activate or change the selected option.</li> </ul> <h2 id="-language">๐Ÿ’ฌ Language<a class="anchor" href="#-language">#</a></h2> <p>Select the preferred interface language. This affects all system apps and some games. Translations are a community effort. If your languages is not on the list or some translations are incorrect, you can help us by translating the relevant app.</p> Graphics https://docs.fireflyzero.com/dev/graphics/ Mon, 01 Jan 0001 00:00:00 +0000 https://docs.fireflyzero.com/dev/graphics/ <h2 id="-pixels">๐Ÿ”ฌ Pixels<a class="anchor" href="#-pixels">#</a></h2> <p>The screen size 240x160 pixels, just like GameBoy Advance. Pixels are quite big, so it&rsquo;s safe to draw one pixel wide lines and letters, they will be visible.</p> <p>Coordinates: x=0 is left, x=240 is right, y=0 is top, and y=160 is bottom.</p> <h2 id="-frames">๐Ÿ–ผ Frames<a class="anchor" href="#-frames">#</a></h2> <blockquote class='book-hint '> <p>All those moments will be lost in time.</p> </blockquote><p>Each update of the image on the screen is called &ldquo;frame&rdquo;. Before each frame is rendered, the <code>render</code> callback function is called. This is where you should call all drawing functions you need.</p> Multiplayer https://docs.fireflyzero.com/user/net/ Mon, 01 Jan 0001 00:00:00 +0000 https://docs.fireflyzero.com/user/net/ <p>To establish a multiplayer connection, take 2 or more devices (or launch 2 or more copies of the emulator) and on each device:</p> <ol> <li>Open the launcher.</li> <li>Launch &ldquo;Start multiplayer&rdquo; (the first app on the list) by pressing <code>E</code> (<code>Enter</code> on the emulator).</li> <li>Wait for all other devices to appear on the list.</li> <li>Press <code>E</code> on both devices (in any order) to stop scanning.</li> <li>Select &ldquo;confirm&rdquo; and press <code>E</code> on both devices (in any order) to confirm that the list of devices is complete.</li> </ol> <p>Then on any of the devices select and launch the app you want to play together. That&rsquo;s it! The app should start on all devices and you all should have control.</p> Designing SDKs https://docs.fireflyzero.com/internal/sdk-design/ Mon, 01 Jan 0001 00:00:00 +0000 https://docs.fireflyzero.com/internal/sdk-design/ <p>When designing a new SDK for Firefly Zero, we follow these principles:</p> <ol> <li><strong>Reduce type conversions</strong>. Try to use the same integer type everywhere. WebAssembly is a 32-bit system, so in Rust it will be <code>i32</code>. In Go, <code>len</code> and slice indexing use <code>int</code>, so that&rsquo;s the best &ldquo;default&rdquo; type. If the language supports generic constructors, consider using it to automatically cast 8-bit and 16-bit integers to the default integer type. Using an 8-bit or 16-bit integer in some types, like <code>Pad</code>, would potentially reduce the size of heap allocations, but most of the time these definitions never leave the stack, and in WebAssembly on the stack everything takes at least 32 bits.</li> <li><strong>Provide type casts</strong>. If the language provides custom type casting, define it for converting <code>Pad</code> to <code>Point</code> (and back), <code>Pad</code> to <code>DPad</code>, <code>Canvas</code> to <code>Image</code>, <code>Style</code> to <code>LineStyle</code> (and back), etc.</li> <li><strong>Provide custom types</strong>. While <code>load_file</code> can return a raw byte array and <code>draw_image</code> can accept any byte array, it&rsquo;s good to provide custom <code>File</code> and <code>Image</code> types (and other custom types too whenever possible). Even if the language doesn&rsquo;t provide nominal type safety, a definition like <code>enemy: Image</code> is much more descriptive than <code>Enemy: []byte</code>.</li> <li><strong>Host calls are functions</strong>. You can optionally provide <code>Line</code> type with <code>draw</code> method for the user&rsquo;s convenience. However, there must be always a <code>draw_line</code> function, like for any other WebAssembly host call. The idea is that host calls are side-effects and that&rsquo;s how we make it explicit.</li> <li><strong>Keep the host functions names</strong>. If the host function is called <code>draw_line</code>, the SDK function wrapping it must be called <code>draw_line</code> (or <code>drawLine</code>, or <code>DrawLine</code>) too. Don&rsquo;t call it <code>render_line</code> or anything else. The called host function names are visible in the runtime error messages and in <code>firefly_cli inspect</code>, so it should be easy for the user to map it to the SDK function calls in their code.</li> <li><strong>Keep consistent type names</strong>. Use the following type names: <ol> <li>Graphics: <code>Angle</code>, <code>Canvas</code>, <code>Color</code>, <code>Font</code>, <code>Image</code>, <code>LineStyle</code>, <code>Point</code>, <code>RGB</code>, <code>Size</code>, <code>Style</code>, <code>SubImage</code>.</li> <li>FS: <code>File</code>.</li> <li>Input: <code>Pad</code>, <code>DPad</code>, <code>Buttons</code>.</li> <li>Net: <code>Peer</code>, <code>Peers</code>, <code>Stash</code>.</li> <li>Stats: <code>Badge</code>, <code>Board</code>, <code>Progress</code>.</li> <li>Shapes: <code>Shape</code>, <code>Line</code>, <code>Rect</code>, <code>RoundedRect</code>, <code>Circle</code>, <code>Ellipse</code>, <code>Triangle</code>, <code>Arc</code>, <code>Sector</code>.</li> </ol> </li> <li><strong>Follow the language style guides</strong>. Follow the naming convention and all the best practices. If there are several competing standards, pick the most commonly used one. Use all possible linters and code formatters.</li> <li><strong>Keep modules flat</strong>. There should be only 2 public modules: <code>firefly.audio</code> with everything related to audio and <code>firefly</code> with everything else (and <code>sudo</code> if your SDK provides sudo functions). Even though the host runtime defines modules like <code>graphics</code>, <code>misc</code>, and more, the SDKs&rsquo; public API shouldn&rsquo;t reflect that structure. Make it fast and easy for users to find and import all they need.</li> <li><strong>Avoid allocations</strong>. It should be possible to use the SDK to write allocation-free apps. For example, in Go, <code>ReadPad</code> returns <code>(Pad, bool)</code> instead of <code>*Pad</code> so it doesn&rsquo;t escape on the heap. In case of reading a file, most users will want the file be automatically allocated with the correct size, so you should make both possible. For example, the Go version of <code>LoadFile</code> accepts an optional buffer and if it is <code>nil</code>, a new one is automatically allocated. Or in the Rust version, there are two implementations: <code>load_file</code> and <code>load_file_buf</code>.</li> <li><strong>Optimize (for size)</strong>. You should provide a simple-to-use API but it must never sacrifice binary size or performance. If someone wants to push the limits of what Firefly Zero can do, they should be able to do that without bypassing the official SDK. However, in many cases, the compiler is smart enough to optimize out unused code branches, so always validate your assumptions.</li> <li><strong>Keep the argument order</strong>. The host functions follow strict rules for arguments order. In particular, drawing functions always accept <code>Point</code> first and <code>Style</code> last. Your wrappers should follow the same order.</li> <li><strong>Use 32-bit float</strong>. 32-bit float arithmetic is much faster on the device than 64-bit arithmetic.</li> <li><strong>Provide helpers</strong>. Don&rsquo;t stop just at the host function wrappers. Provide everything that a typical game might need. For example, arithmetic operations for <code>Point</code>, radial coordinates for <code>Pad</code>, or optional integration with a popular 2D math library.</li> </ol> Input https://docs.fireflyzero.com/dev/input/ Mon, 01 Jan 0001 00:00:00 +0000 https://docs.fireflyzero.com/dev/input/ <h2 id="buttons">Buttons<a class="anchor" href="#buttons">#</a></h2> <blockquote class='book-hint '> <p>Just feel that you&rsquo;re the hardest little button to button.</p> </blockquote><p>Firefly Zero has 4 primary buttons:</p> <ul> <li><code>N</code> (North) on the top.</li> <li><code>S</code> (South) on the bottom.</li> <li><code>W</code> (West) on the left.</li> <li><code>E</code> (East) on the right.</li> </ul> <p>There are also Menu and Power buttons but regular apps don&rsquo;t have access to these.</p> <p>The <code>read_buttons</code> function returns which buttons are currently pressed. The SDKs also provide convenience methods to compare two states to get which buttons were just pressed or just released.</p> Repair https://docs.fireflyzero.com/user/repair/ Mon, 01 Jan 0001 00:00:00 +0000 https://docs.fireflyzero.com/user/repair/ <p>Firefly Zero is a sustainable device and we believe in your <a href="https://en.wikipedia.org/wiki/Right_to_repair" target="_blank" rel="noopener">right to repair</a>. We want everyone to truly own the things they buy and understand how these things work.</p> <p>Opening and disassembling Firefly Zero <strong>does not</strong> void the warranty. However, breaking the device while disassembling (just like other intentional damage) <strong>voids the warranty</strong>. So, before you get started, make sure you know what you&rsquo;re doing. And this page is here to guide you.</p> Multiplayer https://docs.fireflyzero.com/dev/net/ Mon, 01 Jan 0001 00:00:00 +0000 https://docs.fireflyzero.com/dev/net/ <p>Firefly Zero has a very unique approach to multiplayer: every game (or app) can be played together! The only question is how the app handles multiple inputs. And this section covers how you can do that. And don&rsquo;t worry, it&rsquo;s very simple.</p> <h2 id="-how-it-works">โš™๏ธ How it works<a class="anchor" href="#-how-it-works">#</a></h2> <p>If you take two or more calculators and punch into all of them the same expression, you&rsquo;ll get the same result. However if you make a typo in any of them, the result might be very different.</p> Audio https://docs.fireflyzero.com/dev/audio/ Mon, 01 Jan 0001 00:00:00 +0000 https://docs.fireflyzero.com/dev/audio/ <h2 id="-basics">๐Ÿงฑ Basics<a class="anchor" href="#-basics">#</a></h2> <p>Sound in Firefly Zero is constructed as a tree of nodes. There is already one node present, called <code>OUT</code>. Everything connected to it will play on the speakers (or headphones) of the device. Some nodes, called <em>sources</em>, can produce a sound by generating it using math or by reading it from memory or file system. For example, to play note A in 4th octave (440 Hz) using a sine wave:</p> Releases https://docs.fireflyzero.com/internal/releases/ Mon, 01 Jan 0001 00:00:00 +0000 https://docs.fireflyzero.com/internal/releases/ <h2 id="making-a-release">Making a release<a class="anchor" href="#making-a-release">#</a></h2> <p>We use <a href="https://taskfile.dev/" target="_blank" rel="noopener">task</a> everywhere and most of the projects provide <code>release</code> task for making a release which accepts the release number without any prefixes. For example, <code>task release -- 0.1.0</code>. The task will gracefully fail if the release number must be set in the source code first.</p> <p>Firefly consists of multiple projects scattered accross separate repositories. When releasing a project depending on other internal projects, don&rsquo;t forget to update the dependency version.</p> Projects https://docs.fireflyzero.com/internal/projects/ Mon, 01 Jan 0001 00:00:00 +0000 https://docs.fireflyzero.com/internal/projects/ <p>Some of the repositories on this list are private. It includes failed experiments and unfinished projects.</p> <p>Core (firmware and hardware):</p> <ul> <li><a href="https://github.com/firefly-zero/firefly-io" target="_blank" rel="noopener">๐Ÿ›œ firefly-io</a></li> <li><a href="https://github.com/firefly-zero/firefly-hardware" target="_blank" rel="noopener">firefly-hardware</a></li> <li><a href="https://github.com/firefly-zero/firefly-runtime" target="_blank" rel="noopener">โ™ฅ๏ธ firefly-runtime</a></li> <li><a href="https://github.com/firefly-zero/firefly-emulator" target="_blank" rel="noopener">๐Ÿ–ฅ firefly-emulator</a></li> <li><a href="https://github.com/firefly-zero/firefly-hal" target="_blank" rel="noopener">โŒš๏ธ firefly-hal</a></li> <li><a href="https://github.com/firefly-zero/firefly-main" target="_blank" rel="noopener">๐Ÿšช firefly-main</a></li> <li><a href="https://github.com/firefly-zero/firefly-model" target="_blank" rel="noopener">๐Ÿ“ฆ firefly-model</a></li> <li><a href="https://github.com/firefly-zero/firefly-gamepad" target="_blank" rel="noopener">๐ŸŽฎ firefly-gamepad</a></li> <li><a href="https://github.com/firefly-zero/firefly-types" target="_blank" rel="noopener">โš™๏ธ firefly-types</a></li> <li><a href="https://github.com/firefly-zero/firefly-audio" target="_blank" rel="noopener">๐Ÿ”Š firefly-audio</a></li> </ul> <p>Developer tools:</p> <ul> <li><a href="https://github.com/firefly-zero/firefly-cli" target="_blank" rel="noopener">๐Ÿš firefly-cli</a></li> <li><a href="https://github.com/firefly-zero/firefly-test" target="_blank" rel="noopener">โ˜‘๏ธ firefly-test</a></li> </ul> <p>SDKs:</p> <ul> <li><a href="https://github.com/firefly-zero/firefly-as" target="_blank" rel="noopener">๐ŸŸฆ firefly-as</a></li> <li><a href="https://github.com/firefly-zero/firefly-bitsy" target="_blank" rel="noopener">๐Ÿˆโ€โฌ› firefly-bitsy</a></li> <li><a href="https://github.com/firefly-zero/firefly-bulb" target="_blank" rel="noopener">๐Ÿ’ก firefly-bulb</a> and <a href="https://github.com/firefly-zero/bulb-parser" target="_blank" rel="noopener">bulb-parser</a></li> <li><a href="https://github.com/firefly-zero/firefly-c" target="_blank" rel="noopener">๐Ÿ€ firefly-c</a></li> <li><a href="https://github.com/firefly-zero/firefly-elixir" target="_blank" rel="noopener">๐Ÿงช firefly-elixir</a></li> <li><a href="https://github.com/firefly-zero/firefly-go" target="_blank" rel="noopener">๐Ÿƒ firefly-go</a></li> <li><a href="https://github.com/firefly-zero/firefly-lua" target="_blank" rel="noopener">๐ŸŒ™ firefly-lua</a></li> <li><a href="https://github.com/firefly-zero/firefly-moon" target="_blank" rel="noopener">๐Ÿฐ firefly-moon</a></li> <li><a href="https://github.com/firefly-zero/firefly-python" target="_blank" rel="noopener">firefly-python</a></li> <li><a href="https://github.com/firefly-zero/firefly-rust" target="_blank" rel="noopener">๐Ÿฆ€ firefly-rust</a></li> <li><a href="https://github.com/firefly-zero/firefly-starlark" target="_blank" rel="noopener">firefly-starlark</a></li> <li><a href="https://github.com/firefly-zero/firefly-zig" target="_blank" rel="noopener">โšก๏ธ firefly-zig</a></li> </ul> <p>Websites:</p> UI https://docs.fireflyzero.com/internal/ui/ Mon, 01 Jan 0001 00:00:00 +0000 https://docs.fireflyzero.com/internal/ui/ <p>This is the design guide for designing user interfaces for the system apps.</p> <ul> <li>We follow <a href="https://www.neobrutalism.dev/" target="_blank" rel="noopener">Neobrutalism</a> design adjusted for low-res pixelated screens.</li> <li>Font: <code>eg_6x9</code>.</li> <li>Respect user language</li> <li>Respect user color scheme</li> <li>Colors: <ul> <li>Primary: text, box borders</li> <li>Secondary: disabled elements, inactive elements</li> <li>Accent: active elements, headers</li> <li>BG: background.</li> </ul> </li> <li>Margins: 1, 2, 4N (N&gt;0) px.</li> <li>Rounded corners: 4px.</li> <li>Box border width: 1px.</li> <li>Use lowercase text except where the grammar requires it (abbreviations, names, country names in English, etc) and paragraphs of text.</li> <li>Cursor has 1px shadow on bottom-right.</li> <li>Pairs of yes/no buttons are aligned on the same line, with no/back/previous/cancel on the left and yes/forward/next/accept on the right.</li> </ul> Badges and scores https://docs.fireflyzero.com/dev/stats/ Mon, 01 Jan 0001 00:00:00 +0000 https://docs.fireflyzero.com/dev/stats/ <h2 id="-badges">๐Ÿ… Badges<a class="anchor" href="#-badges">#</a></h2> <p>Badges are achievements that the game rewards to the player for doing some actions. Fore example, collecting a certain number of collectables, finding a rare item, doing a hard combo, etc. You can add badges to your game to encourage players to experiment with features they might not normally use, or to approach your game with entirely different play styles.</p> <p>Badges are defined in <code>firefly.toml</code>:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-toml" data-lang="toml"><span style="display:flex;"><span>[<span style="color:#a6e22e">badges</span>] </span></span><span style="display:flex;"><span><span style="color:#ae81ff">1</span> = { <span style="color:#a6e22e">name</span> = <span style="color:#e6db74">&#34;m i tasti&#34;</span>, <span style="color:#a6e22e">descr</span> = <span style="color:#e6db74">&#34;bite yourself&#34;</span> } </span></span><span style="display:flex;"><span><span style="color:#ae81ff">2</span> = { <span style="color:#a6e22e">name</span> = <span style="color:#e6db74">&#34;u r tasti&#34;</span>, <span style="color:#a6e22e">descr</span> = <span style="color:#e6db74">&#34;bite someone else&#34;</span> } </span></span><span style="display:flex;"><span><span style="color:#ae81ff">3</span> = { <span style="color:#a6e22e">name</span> = <span style="color:#e6db74">&#34;apel tasti&#34;</span>, <span style="color:#a6e22e">descr</span> = <span style="color:#e6db74">&#34;eat 100 apples&#34;</span>, <span style="color:#a6e22e">steps</span> = <span style="color:#ae81ff">100</span> }</span></span></code></pre></div><p>The key of each badge is the ID used to refer to it in the game. It must start at 1, go sequentially up, and never change between releases. For now, there can be at most 20 badges in a single game.</p> Marketing https://docs.fireflyzero.com/internal/marketing/ Mon, 01 Jan 0001 00:00:00 +0000 https://docs.fireflyzero.com/internal/marketing/ <p>The key point in everything we do is we&rsquo;re not a big evil corporation. We are geeks that are tired of ads, AI, and investor-driven businesses. This might make it harder to reach wider audience but the people that do find us will have a stronger bond with our vision.</p> <ul> <li><strong>Writing style</strong> <ul> <li>Keep it simple and honest. Keep it short and to the point.</li> <li>Avoid bullshit words and business speak, like &ldquo;empowering e-commerce businesses to disrupt the industry of AI&rdquo;. Here is some good writing: <ul> <li><a href="https://www.youtube.com/watch?v=AXsLvmukUTc" target="_blank" rel="noopener">Big Walk trailer</a></li> <li><a href="https://play.date/" target="_blank" rel="noopener">Playdate website</a></li> </ul> </li> <li>Use only hashtags relevant to the post content, especially on small platforms.</li> </ul> </li> <li><strong>Advertisement channels</strong> <ul> <li><strong>Bad:</strong> buying annoying ads.</li> <li><strong>Good:</strong> posting useful content to our socials that people will want to re-post.</li> <li><strong>Bad:</strong> paying people for feedback.</li> <li><strong>Good:</strong> providing free (or not) early previews to the geekiest geeks, encouraging them to post their honest reviews.</li> <li><strong>Bad:</strong> spamming every community.</li> <li><strong>Good:</strong> authentically being part of many communities and talking about Firefly.</li> </ul> </li> <li><strong>Graphical style:</strong> <ul> <li>Use <a href="https://lospec.com/palette-list/sweetie-16" target="_blank" rel="noopener">SWEETIE-16</a> color palette.</li> <li>Use pixelated images and fonts (for titles), in the spirit of the graphics on the device.</li> <li>Avoid overly-pixelated fonts for the main text, it might make it hard to read.</li> <li>Use the official art: <a href="https://github.com/firefly-zero/firefly-art" target="_blank" rel="noopener">firefly-art</a>.</li> <li>If the platform allows it, provide alt-text.</li> </ul> </li> <li><strong>Availability:</strong> no important information should be confined to platforms that cannot be viewed without registration, like Xitter, Instagram, or Discord. Open for read (and search indexing) resources: Mastodon, Pixelfed, docs.fireflyzero.com, blog.fireflyzero.com, Github.</li> <li><strong>Ethics:</strong> avoid unethical trends (including past trends), like AI, blockchain, or NFTs.</li> </ul> Debugging https://docs.fireflyzero.com/dev/debugging/ Mon, 01 Jan 0001 00:00:00 +0000 https://docs.fireflyzero.com/dev/debugging/ <p>This page covers how to find bugs in your apps.</p> <h2 id="-cheat-codes">๐Ÿ˜Ž Cheat codes<a class="anchor" href="#-cheat-codes">#</a></h2> <blockquote class='book-hint '> <p>Breaking the law, breaking the law.</p> </blockquote><p>You can add cheat codes to your apps. Cheat codes can be used to put the app into a specific state: jump to a specific level, reset NPCs&rsquo; positions, set character health, etc.</p> <p>First, add <code>[cheats]</code> table into <a href="https://docs.fireflyzero.com/dev/config/"><code>firefly.toml</code></a>. The table maps cheat code names to numbers that get passed into the app:</p> Testing https://docs.fireflyzero.com/dev/testing/ Mon, 01 Jan 0001 00:00:00 +0000 https://docs.fireflyzero.com/dev/testing/ <p>Firefly Zero has an official framework for writing tests for apps. It&rsquo;s written in <a href="https://www.python.org/" target="_blank" rel="noopener">Python</a> and works great with <a href="https://docs.pytest.org/en/stable/" target="_blank" rel="noopener">pytest</a>. If you don&rsquo;t know Python, don&rsquo;t worry. It&rsquo;s quite a simple language and you don&rsquo;t need to know much to succesfully write tests.</p> <img src="https://docs.fireflyzero.com/info.png" class="hint-icon info" /> <blockquote class="book-hint info"> <p><strong>Under the hood</strong></p> <p>The <a href="https://github.com/firefly-zero/firefly-test" target="_blank" rel="noopener">firefly-test</a> Python package is a wrapper around the actual Firefly runtime written in Rust and embedded into the package using <a href="https://pyo3.rs/" target="_blank" rel="noopener">PyO3</a>. So, you can be sure that it works exactly as it will in emulator and you don&rsquo;t even need to have the emulator installed.</p> Terms https://docs.fireflyzero.com/dev/terms/ Mon, 01 Jan 0001 00:00:00 +0000 https://docs.fireflyzero.com/dev/terms/ <p>Below are different terms that the documentation uses. If there is a technical word in the ocumentation that you don&rsquo;t understand, it should be in there. If it&rsquo;s not, send us a pull request or open an issue!</p> <ul> <li><strong>Asset</strong> is a file that an app needs but which isn&rsquo;t the code. It includes sprites, music, sounds, sometimes dialogs and configurations, etc.</li> <li><strong>Frame</strong> is what is show on the screen at one specific moment. Each frame is a rectangle of 240 per 160 pixels.</li> <li><strong>Host function</strong> is a function defined by Firefly runtime (as opposed to functions defined in the app). The Firefly SDK for your language is a wrapper for host functions.</li> <li><strong>ROM</strong> is a distribution of your game. It includes a WebAssembly binary, game assets, metadata, signature, etc. A ROM is distributed in a ZIP (<code>*.zip</code>) file and on the device is stored as a collection of files in a directory in <code>/roms/</code>.</li> <li><strong>TOML</strong> is a configuration format that we use for the <code>firefly.toml</code> config. It&rsquo;s stricter than YAML and more readable than JSON. If you&rsquo;ve seen INI (<code>*.ini</code>) files in WIndows games, TOML should look very familiar.</li> <li><strong>WebAssembly</strong> (aka <strong>wasm</strong>) is a binary format in which all Firefly apps compile. It&rsquo;s like EXE (<code>*.exe</code>) on Windows.</li> </ul> Bulb Script https://docs.fireflyzero.com/dev/bulb/ Mon, 01 Jan 0001 00:00:00 +0000 https://docs.fireflyzero.com/dev/bulb/ <p>Bulb is a scripting language inspired by <a href="https://bitsy.org/" target="_blank" rel="noopener">Bitsy</a> and <a href="https://play.date/pulp/" target="_blank" rel="noopener">Pulp</a> and designed specifically for Firefly to create simple adventure games.</p> <img src="https://docs.fireflyzero.com/info.png" class="hint-icon info" /> <blockquote class="book-hint info"> <p><strong>What kind of games?</strong></p> <p>Bulb is designed for making adventure games: you can walk around, talk to NPCs, interact with objects, and solve puzzles. Bulb cannot be used to implement reaction-based games, physics, real-time behaviors, complex fighting systems, or multiplayer. If your game needs any of these features, go to the main <a href="https://docs.fireflyzero.com/dev/getting-started/" target="_blank" rel="noopener">Getting started</a> to make a game in a proper programming language.</p>