Internal on Firefly Zero docs https://docs.fireflyzero.com/internal/ Recent content in Internal 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> 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> 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> 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>