Technical Writing - NESmaker Design Document
- JoeGranatoIV
- Jan 25, 2021
- 8 min read

Joe Granato IV
v.10.13.20
NESmaker 4.3.x, supplemental
This general design document is to denote changes for the stop-gap version of NESmaker, which will likely be the 4.3.x public release, or potentially push into the 4.4.x beata version. It will push in the direction intended for 5.0, but not be contingent upon all of those updates being completed and stress tested in order to allow users to work with it.
The purpose of this version is to correct bugs and issues, remove legacied methods, prepare for Byte-Off 2020 competition, include all promised aspects denoted in the Kickstarter (minus the modules, though they will come) and begin the pivot towards methods to be used in future versions.
Aside from the bug fixes and UI updates listed as urgent in Trello, here is a list of features that should be present.
1. Post-Splash
NEED: One issue that new users complain about is that they’ll start creating without having loaded a module or created a graphics folder. There is a quick fix for this. Many modern software packages have a post-splash file browser. After the splash screen, a “New/Open” splash will pop up prior to being able to work on the tool. The user can choose to open a file or start a new one, with recent files visible. The New / Open selections will do the same thing as their respective File routines do, but having it in a post-splash window will force a user to either open an existing project or create a new one, choosing their module of choice. This will prevent users from accidentally starting the tutorials with no splash.
Below is an image of Adobe’s. Ours can be far simpler than this. The important thing is just to have the new / open options prior to actually being able to start messing around in the tool. Effectively, there is no canvas upon which to paint the proverbial game until you’ve done this.

2. Direct Tile Painting
NEED: We want to give the user a way to directly paint tiles to the screen. This will allow them to make assets, OR to just paint tiles, collision data, and attributes independently. We already have methods allowing a user to do the last two, so the asset process is cumbersome for those that want to start painting screens with immediacy.
In addition, implementing an 8x8 px nametable mode will allow them to effectively make all the special screens they want, or even make more detailed screens with less screens available. This solves the problem of the variable data space in special screen banks. The same screen byte data will be regimented, but in 8x8 screens, 4x the data will yield 1/4th the screens per bank. Another benefit is that users will make use of the same tilesets that any other screen would use now, and the same method of tileset organization.
Tile Painter
I have rearranged some of the items on the screen painter slightly to make this fit. While I am not married to this exact organization, I think it would be wise to put instructions right there on the screen, too. So, use T to paint with the “tile painter”. Zero to paint with the collision painter (right now it says attribute which is confusing, since the color data is the “attributes”). QWER to paint with the attribute painter.
You can see now the tileset is loaded, and just like with the asset creator, a user can pick a tile. Doing this selects it, deselects the asset, and it becomes the”cursor”, the same way that the tile did before. Similar to other places in the tool, we should have a shift-select method in the tileset to select an area at once for placement. Just like with assets, escape deselects, or clicking on an asset would also deselect a selected tile.

Map Handling for 8px (think “special”) screens
We need to create a scenario for 8x8 px screen drawing. For that, we need to recoup a lot of data. If we ONLY export 8 screens worth of data instead of 32, we can fit full valued nametables into a bank. Here is a visual of what would happen from a map perspective:

In the image, you can see the first bank (consisting of 32 screens) has become an 8x8 px mode. That means that only data for 8 screens will fit in the bank. One way of visually suggesting this to a user is as above. The other would be to just gray out the remaining 24 screens, but this is my preference.
Users should be able to select a bank of screens (every 32 screens = a bank) and opt to manually change from 32 metatile screens to 8 regular tile screens. Doing so would give them an error that all screens in that area would be erased, and they will have the option to cancel. Approving the change will delete all screens in that range and change the mode.
If a bank is in metatile mode, nothing changes about the output.
If a bank switches to 8px mode, only screens 0-7 (or 32-39, etc) output their nametables (which will be 4x the size of metatile exports). The rest of the screens in that bank...8-31 or 40-63, etc...for any bank set in this mode would create an empty file with a sum data size of zero. This will make sure the links don’t break (the labels are defined in the includes), but there is no data being included, meaning there will be enough space for those 8 full nametables.
Same thing with collision and attribute tables, though they’ll be the same size data in either mode. We only export data for the 8 of them while the rest would be blank.
3. Labels for screen types
There are 256 possible screen types. Each should be able to get a labled name, able to be set in project labels in a big list. In the screen info dialog, where it gives the screen type number, it should be associated with the name.
Doing this makes it easy to read screen type and set conditionals. Rather than worrying about game states, we can do the same sort of thing with screen types. If screenType = 0, the start button runs any start button scripts associated with screenType 0. This helps us get closer to streamlining how things work rather than having special screens created different from normal screens.
4. Fix Flash Button
Having the flash button run this batch file (create it and put it in the folder with the exe) will fix flash problems, AND allow us to easily modify the batch file if ever the hardware protocols are changed again.
copy GameEngineData\game.nes Flasher\INL-retro-progdump_map30\host\game.nes CD Flasher\INL-retro-progdump_map30\host\ call flashcart.bat
5. FamiStudio to replace Music Tracker AND Sounds
With permission, we have licensed FamiStudio to come stocked with NESmaker as part of the tool chain. It can be accessed like the pixel editor. In it, you can create things or you can import a fami/text file for tweaking. You have to (export) save it over the top of the default file for the songs to be included. Then, it will compile through the gradual games converter when the project is assembled, and it will work with the game. We should maintain the ability to load famitracker text files into it, and export famitracker text data.
The latest version of that is at famistudio.org
6. Removal of broken and legacied items
(coming soon)This will be the last thing we do, when we have feature lock for this version.
7. MESEN the default emulator.
With permission, we can include the latest version of MESEN in the emulator folder, and DEFAULT the emulator settings to (path)\game.nes opening in MESEN. Here is the site to get MESEN: https://www.mesen.ca/
(coming soon)
8. “Export Project” tab to match NESmaker player needs
(coming soon) - again, one of the last things to sort out when we see where feature lock is.
9. Alternate Sprite Output
This will be an alternate set of tables, which should be incredibly easy to construct and spit out, so I’d like to include it in this version. Then, it will be using the METHOD of the new way to do animations I’ve got planned for 5.x without having to change the interface. It’ll just spit out the data differently. But it’ll let me write the new animation routines to fit the current way while experimenting the new way. This will better prepare us for the subsequent update to version 5.x.
Effectively, in future versions, there will be no gridded sprite template. You’ll have an x,y origin point for an object, and sprites will be drawn relatively from there, with each tile having its x and y offset, tile index, and attribute (palette) byte.
Also, because of the way tiles are organized, there is only 0-7f...then 0-7f (+80) for monsters, which reads from the second tileset. That means that values 80-FF are never actually used and can be used for opcodes for drawing routines...FF being the logical “DONE” command.
So for all intents and purposes, we’re going to have the tool *pretend* that current objects are built the same way, and that the user just happened to line them up on a grid, and blast out tile data with an FF at the end of a sprite.
To make this work, we need one hi/lo table set to point to the anim type, another hi/lo table set for each frame of that animation, and then a table for each animation. This is not so dissimilar to what we do now, except really for the last part.
Here’s how it should work:

This is basically the current sprite interface, with the new concept laid over the top (offsets in hex).
For right now with the current interface, we’d get four different tiles drawn, and each would have an x, y, an index, and an attribute..
This frame of this animation for this sprite would be:
Object0_idle_frame0: .db. #$00, #$00, #$00, #%00000000
.db #$08, #$00, #$01, #%00000000
.db #$00, #$08, #$10, #%00000000
.db #$08, #$08, #$11, #%00000000
.db #$FF
If the next frame saw the character only 1 pixel high, it would still have to draw the entire sprite, and just put dummy values in the blank spots. In the new method, we will only output data that is actually drawn. So without the top two tiles, the export would just be:
Object0_idle_frame1:
.db #$00, #$08, #$10, #%00000000
.db #$08, #$08, #$11, #%00000000
.db #$FF
In this way, there doesn’t have to be consistency from frame to frame, and this will still work fine. This sets up the possibility that sprites would no longer have to line up on the grid. They could be drawn using any number of tiles in any position relative to the origin point that would constitute a “frame” of animation.
So the first thing that needs to be generated here is the table of frames, per animation, just that way. If an animation has six frames, we’d expect Object0_animName_frame0 - frame5, and each would contain the x offset, y offset, tile index, and attribute data (which includes the flips and the palette info...you should already be the index and the attributes in a different format...let me know if there are questions about the bit correlation in the attribute byte, but you’re already doing it so probably have it referenced somewhere)
The #$FF is an opcode that tells the drawing routine that this sprite’s animation frame is finished drawing. But with this method, using the x and y offsets, we don’t have to try to keep track of width or height in tiles, and don’t need to count the number of tiles that make up an animation either (and they could even change between frame to frame without issue!). Blank areas don’t have to be drawn, conserving ram and draw time. Modular animation (like a head bobbing or arm thrusting forward) becomes simple.
The second thing we need to do - we also need to generate the pointers to each frame. To simplify this, we can use “words” (.dw) instead of “bytes” (.db).
Object0_idle:
.dw Object0_idle_frame0
.dw Object0_idle_frame1
.db #$ff ;; db is on purpose...again, this is an opcode that will trigger the
;; animation done flag.
Object0_walk:
.dw Object0_walk_frame0
.dw Object0_walk_frame1
.dw Object0_walk_frame2
.dw Object0_walk_frame3
.db #$ff
We also can jettison the direction pointers. Instead, users will create directions called “walkLeft” and “walkUp”, and when they press the corresponding key, they will execute a piece of code to “change to animation”, and have the choices of animations they’ve created for that object. So they bypass a whole lookup, and we drop the need for a whole table. Then, they’re not wasting output and references if they only have left and right, or they could even make more directions than diagonal, like 30 degree rotations or whatever...totally up to them how they want to build that or change animations.
Comments