FAQ. **** Why did you make this? ====================== After finishing the jam game "Goodboy Advance", Rik and I decided to make a post-jam version, which eventually became `Goodboy Galaxy `_. The old jam code sucked, so we planned to rewrite it from scratch. And C was slowing us down a lot - it's verbose, lacks good abstraction mechanisms, and does a terrible job at protecting you from your own mistakes. At that time I was also learning Nim to make desktop games with SDL - something it's `very `_ `good `_ at. I wasn't expecting Nim to work on the GBA. After all, many compiled languages such as Haxe and Swift have hefty runtimes making them unsuitable for embedded platforms. But I gave it a try and to my surprise it worked brilliantly! I wrapped the entirety of `libtonc `_ to create a library called `nim-tonc`. As I grew comfortable with Nim, I learned how to write more idiomatic code instead of treating it as just a "nicer C". I renamed the library to `natu` and started using my experience to create nicer APIs: * Before: `REG_DISPCNT = (REG_DISPCNT and not DCNT_MODE_MASK) or DCNT_MODE4` * After: |nbsp| `dispcnt.mode = 4` While working on the game, I tackled problems such as image conversion, palette management and sprite tile alloction. These eventually made their way into Natu for re-use in future projects. Natu is for those who want to enjoy writing GBA games in a flexible compiled language that *feels* like a scripting language. You get to work directly with the hardware and build your own engine, but you don't have to reinvent the *entire* wheel. ---- How does Natu compare to ... ================================ libtonc ------- `libtonc `_ is the accompanying library to the excellent Tonc tutorial. It exposes the entire GBA hardware in C, and provides several utilities such as fixed point math, text rendering, and interrupt management. Natu started as a wrapper for libtonc, also wrapping additional libraries such as :doc:`Maxmod ` and :doc:`posprintf`. New features were added, some libtonc modules were eventually replaced with idiomatic Nim code, and others by alternatives such as ugba's :doc:`interrupt manager `. However many parts remain, notably :doc:`Tonc Text Engine ` and the :doc:`Surface ` API. .. Additionally, the `legacy` module contains the original libtonc I/O registers and constants, some of which have no idiomatic replacement yet, for example DMA functions. Butano ------ `Butano `_ is a high-level engine using modern C++ ideas such as `RAII `_ to save you the burden of managing resources (VRAM, palettes, etc.). Natu is lower-level than Butano, encouraging you to read and write I/O registers directly. Like Butano, it provides an asset conversion system, and allocators for Obj VRAM and Obj Pal RAM. Unlike Butano, you have to call the allocators manually. Also there are no allocators for backgrounds, you just manage them by hand. It's worth noting that Nim's `ARC `_ memory-management strategy allows you to implement the same RAII patterns as in C++, so you could use Natu to build a "Butano-lite" if you wanted. If you were to do this, you'd find the resulting code to be *way shorter*! ---- Nimble says "``Package 'natu' has an incorrect structure``"? ===================================================================== If you see a warning like this, don't worry: .. code-block:: text Warning: Package 'natu' has an incorrect structure. It should contain a single directory hierarchy for source files, named 'natupkg', but file 'backgrounds.nim' is in a directory named 'natu' instead. This will be an error in the future. The structure is fine, Nimble is just overly prescriptive. The warning predates several additions to the language such as the `./` prefix for local imports, and the `std/` prefix for stdlib imports. Hopefully they'll remove it soon. ---- .. Error "``linker input file unused because linking not done``" ======================================================================================== If you are on Windows and you get the following error: .. code-block:: text ... Building natu/mmutil.exe using c backend gcc.exe: warning: : linker input file unused because linking not done gcc.exe: error: : linker input file not found: No such file or directory Error: execution of an external program failed: 'gcc.exe -c -w -fmax-errors=3 -mno-ms-bitfields ""-DPACKAGE_VERSION=\"1.9.0\""" -O3 -fno-strict-aliasing -fno-ident -IC:\Users\Me\.choosenim\toolchains\nim-1.6.6\lib -IC:\Users\Me\natu -o C:\Users\Me\nimcache\mmutil_r\adpcm.c.o C:\Users\Me\natu\vendor\mmutil\source\adpcm.c' ---- Error "`` is not in region .iwram``" ============================================================= This likely means your global / top-level variables are occupying too much :abbr:`IWRAM (Internal Work RAM)`, which is the small region of memory where all variables go by default (see `Where do my code & data end up in memory?`_). To fix this, you could try any of the following: * If you have some values that never changes, you could make them `const`. * If the variables aren't performance-critical, use ``{.codegenDecl:DataInEwram.}`` to move them into :abbr:`EWRAM (External Work RAM)`. * Look out for memory-hungry variables such as large arrays/objects, and try reducing their size by using smaller datatypes, using the `{.bitsize.} `_ pragma to pack your objects, and removing unnecesary fields. * Make your variables local to allocate them on the stack, or turn them into ``ref`` objects or manually-managed ``ptr``\ s to allocate them on the heap. This ensures that they won't consume memory when they're not in use. ---- Where do my code & data end up in memory? ========================================= By default: * **Procedures** are compiled to Thumb code and placed in ROM. * **Local variables** are allocated on the stack, which is in IWRAM. * **`ref` objects** are allocated on the heap, which is in EWRAM. * **Top-level variables** are generally placed in IWRAM, but: - **`let` variables** go in ROM only if they're ordinal types (or arrays of such) whose values are known at compile-time. - **`const`s** go in ROM, or may have their values substituted in-place at the point of usage (if they're small). The following modifiers are available for use with the `codegenDecl `_ pragma to control how code and data are placed. * :xref:`ArmCodeInIwram` - the procedure/function will be compiled to ARM code and placed in IWRAM. This can give a substantial speed boost! * :xref:`ThumbCodeInEwram` - the procedure/function will be compiled to Thumb code and placed in EWRAM. This may be occasionally useful for purposes such as a "cartridge removed!" screen, or for code which reads from SRAM. * :xref:`DataInEwram` - the top-level variable will be placed in EWRAM instead of IWRAM. ---- .. How do I get a pointer to constant data? ======================================== This can be troublesome, because you can't take the address of a `const` in Nim, and `let` won't put data in ROM unless it's a simple array. To work around this issue, you might consider outputting your data as C or ASM files and then using the `importc` pragma to access it from Nim. .. code-block:: c // TODO: use a struct example instead. const char marioImg[] = "\000@vwF@wvw@uDt@U\004@@U\004\000\000D\000........"; .. code-block:: nim {.compile: "mario.c".} let marioImg* {.importc, codegenDecl:"extern const $# $#".}: array[256, uint8] The downside to this is that you can't use `marioImg` at compile-time anymore. A better solution is often to avoid pointers altogether and use enums instead: .. code-block:: nim # TODO This is also what the Natu project tool does when converting graphics / bgs / sounds. ---- .. Why are some fields cint/cuint instead of int/uint? =================================================== .. To facilitate porting your game to other platforms. I made a game! How do I distribute it legally? ============================================== Yo, congrats! Natu is under the zlib license which means you don't have to credit me (though it would be nice if you did!) however, many of its dependencies (libtonc, maxmod, etc.) are under the MIT or ISC licenses, which require that the author's *copyright notice* and the *full license text* be included somewhere alongside your game. The easiest way to follow this is simply to include a text file with your game, listing all the dependencies, their copyright notices, and their licenses. Here's an `example text file `__ from a project made with Natu that you could use (adapting the text at the top to suit your project, and also adding any additional libraries that you may have used). Another option would be to include the text in the game itself (on a 'licenses' screen or such). This takes some work but has the advantage that the license text can't become separated from the game, so it's impossible for anyone to distribute it incorrectly.