Tasks
Moving forward on Samus sprites, we have two tasks ahead.
1. Build in "native" ROM support for custom sprites in the SpriteSomething png format. This should be part of the base ROM build and include the vanilla Samus sprite.
SpriteSomething fundamentally changes how sprites are handled and drawn in some respects. It uses the same VRAM space as vanilla but with (mostly)16-pixel height chunks as a sort of viewport into various poses with minimal flipping and mirroring (this relaxes symmetry requirements that sprite artists would otherwise be very constrained by.) At a high level, the Samus pose/animation code is changed to support this and some extra space for data is claimed.
We need to write our own, equivalent implementation using theirs as a reference (https://github.com/Artheau/SpriteSomething/blob/master/source/snes/metroid3/samus/rom_inject.py). Additionally, we should build this implementation directly into the base build such that the vanilla player sprite works exactly the same as a custom sprite. This will make any debugging/testing easier and in my opinion is also a matter of racing integrity. In practice there is probably little to no difference in timing between a vanilla and custom sprite, but all ROMs should be executing the same code here all things being equal. There are various ways to approach this, more on that below.
One question that needs to be resolved here as well is whether or not to support the original screw-without-space jump animations. We could simply not implement them even though they're in the png. My vote would be to not include this in our implementation.
2. Build a frontend tool that takes a standard SpriteSomething png layout and produces the binary data to be patched.
With #1, we've laid out a specification for this and should be able to more or less do a straightforward binary transformation. We should also use SpriteSomething as a reference here, and potentially use their json data descriptions keeping in mind that they are licensed under CC BY-SA 4.0.
We also have to decide how to implement the necessary tools here. The patcher and any potential tools for the base ROM build should be designed as a library exposing some simple input-output interface. The most straightforward option would be to implement them in Typescript like the rest of the project. I would propose writing the core tools in Rust with webassembly bindings. It's an ideal candidate for the fast binary transformations we want, and can additionally be compiled as its own Rust library or have bindings for other languages written. There are, of course, complexity and maintenance tradeoffs here as well.
Binary Extensions Repo/Side-Project
When we reach this point, we should probably make a separate issue and discuss this more thoroughly. But I don't want to put the cart before the horse here. I was thinking we could maintain separate repo for binary tools/extensions/bindings. Something like dash-bin-ext
. We could more broadly imagine writing tools or drop-in functions that expose a TS API in a compiled language like Rust. For example, we could compile a tool that converts the vanilla player sprite to the new format and place it in the ROM repo's /bin directory to be used alongside the assembler as part of the build. Or we could, theoretically, write a level composer (as a drop-in for the current "hot" patching) or graph solver that takes some input from the TS application and outputs either some native data to be used by the app or binary data to be patched.