I'm creating a new NES game engine at https://github.com/fo-fo/ngin. I started this project around the beginning of March this year. I haven't touched it since June, but do plan to work on it every now and then from now on. I'm going to use this thread as a development blog similar to the one I had when I was working on STREEMERZ.

Some things to note:

The engine depends on the Lua support of NDX extensively, so it cannot really be used with other emulators at this point. This in turn means that only Windows is supported as a host platform.

Some parts of the engine (like the map scroller) only exist as Lua prototypes at this time. These will naturally need to be rewritten in 6502 at some point.

The provided "samples" (in the samples directory) are not so much samples about how to best use the engine, but rather just pieces of code I've used to test parts of it.

If you are on Windows and want to try building the engine and samples despite the long list of dependencies, see the How to Build section in the README file at the GitHub page. If you have troubles with this, let me know.

If you are an artist, or an otherwise curious individual, you might find it interesting to modify some of the assets used in the sample projects. Examples of these are the TMX level files (editable with Tiled) and the sprite animations (.gif files). Probably the best playground for this purpose is the platformer sample. You will need to have the build system set up to be able to see the changes in action, though.

All feedback and suggestions with regard to any part of the engine (code, build pipeline, tools, workflow, etc) are welcome.

License is undecided at this point, and as you can see in the README file, I don't actually recommend that anybody tries to use this engine in their own game projects at this point, given how many features are missing or incomplete.

As for features, here's some of what I have so far (some more complete than others):

Metasprite rendering

Object handling (allocation, deallocation, etc)

Object spawning (Lua prototype only)

Controller reading

Memory operations (copy/etc)

Lua integration

Camera

Map scrolling (Lua prototype only)

Map-Object collision detection (Lua prototype only)

Object-Object collision detection (bounding boxes)

PPU buffer (for nametable updates and so on)

Macros for stuff like 16-bit arithmetic

ngin_tile macro that can be used to define tiles within code (nice for self-contained samples)

Build logging (for generating a text file from build-time data, can contain link time data such as how big a certain segment is)

Sprite animations

Runtime asserts (depends on NDX and Lua): can be used to assert certain conditions at runtime, for example that the carry flag has the expected value

Sound support (depends on Musetracker, I may add support for other sound engines later)

One of my goals has been to integrate the tools in the build process as well as I could. This means that if you modify a TMX map file, the map import script will be automatically run when you build the project. Same goes for changes to other assets like sprite animations and audio files.

Here's a screenshot of the current state of the platformer sample to spice up this post a bit:

Timing was completely coincidental, it was just a matter of me getting around to writing the build instructions and the introduction post.

darryl.revok wrote:

I think this sort of thing is exactly what the NES community needs; a tool to make the development of new games for the console actually practical.

I'd like to help if there's anything I can do.

Just so that there's no misunderstanding: even though I'm developing this engine out in the open, I'm still making it primarily for my own use. If it ends up being useful, interesting and/or educational for others, that's cool, but I'm not trying to turn it into an all-encompassing solution (for the sake of my sanity).

As for help, I don't have anything special in mind, but all kind of comments, suggestions and so on are welcome.

Erockbrox wrote:

This sounds like a huge break thru in nes development. Please keep it up. I would love to see an easy way to make nes games!!!

Quite frankly I think NES development is inherently so complex that no library is ever going to make it "easy". We can try to create libraries to make it easier, of course.

I guess I'll write a few words about the features I have listed/implemented so far.

Metasprite rendering

This is pretty much your run-of-the-mill metasprite rendering implementation. There's a function ngin_SpriteRenderer_render that takes in a pointer to the metasprite data, and a screen-space position where the sprite should be rendered. The coordinates of the position use 16 bits to allow the sprite to be moved off-screen smoothly. The implementation is at https://github.com/fo-fo/ngin/blob/mast ... renderer.s

I have wrapped all functions in macros to make it easier to change the parameter passing mechanism later on. Right now a global variable is allocated for each parameter of each function, which wastes a lot of memory. The wrapper macro simply copies the parameters to their memory locations and JSRs to the function implementation. The function call wrapper and some helper macros are defined in https://github.com/fo-fo/ngin/blob/mast ... nderer.inc

My metasprite data consists of a delay for the frame and link to the next frame (for animations); and the data itself, which is just 4 bytes per hardware sprite in a format similar to how OAM data is laid out.

To be able to easily import images as metasprites I wrote a tool in Python called sprite-importer.py. This is a fairly simple one since I didn't want to spend a lot of time on complex algorithms for sprite allocation just yet. It simply crops the input image and assigns the tiles starting from the top left corner of the input image. It also crops each sprite row individually. The input image must be in indexed format, where indices used in the image map to the PPU sprite palette indices. Every 4th color is considered transparent, and the different palette layers are separated before conversion. It can also import animations from .gif files or sprite sheets. The sprite allocation done like this is definitely suboptimal, but good enough for testing and prototyping. Source is at https://github.com/fo-fo/ngin/blob/mast ... mporter.py

Maybe at some point I'll try to integrate Tilificator into the build system as well, although I'm not sure how command line friendly it is. Sprite import from NES Screen Tool's metasprite data is also on the TODO list.

The sprites to be imported can be specified in the CMakeLists.txt file (build rules for CMake) for example like this:

The sprite-importer tool will then generate an include file named sprites.h (based on "OUTFILE") that will contain a symbol that references the metasprite data, in this case it's called "sprite". HFLIP/VFLIP/HVFLIP flags can be used to specify that horizontally or vertically flipped variations of the metasprite definition should also be generated. At the moment it's not possible to specify which segment the generated data should go into, but probably this feature needs to be added at some point once I start implementing mapper support.

My map importer operates solely on the visuals of the map; it doesn't care about the tile size as long as the results fit the NES restrictions. Because of this, I literally included the mockup image as is into the map (it's one huge tile in Tiled). I drew the collision data on another layer. This works because the importer merges tile attributes from all layers at import time. It's also possible to set the layer properties to ignore the visuals of a layer; this is used for the Screen Grid layer.

Another nice thing about merging all of the map layers is that it's possible to have "detail" layers on top of the normal ones. This could be useful to non-destructively make variations of tiles, although I'm not much of an artist so I'm not sure how useful it'd be in practice. Might be useful for shadow variations.

I consider this format to be the "authoring format" for maps. Map importer takes care of converting it to whatever format the engine uses. This should make it easy to change the internal map format later on if need be.

Scrolling displays that garble on the edges. I'm sure this will be fixed. Seems as if only collision is implemented as well as some non interacting sprites. I'm sure this was just for testing purposes and will improve greatly with time.

Scrolling displays that garble on the edges. I'm sure this will be fixed.

Yes, in fact it's not even something to "fix", it's entirely dependent on the settings used in the map scrolling code. The scrolling code already has support for all mirroring modes, but currently it's set to one-screen mirroring because that's the most compatible one. This will be a compile-time setting.

Quote:

Seems as if only collision is implemented as well as some non interacting sprites. I'm sure this was just for testing purposes and will improve greatly with time.

That's pretty much it (although the "enemy" sprites do sort of interact with the player and the background already). I do plan to extend the sample with stuff like moving platforms, slope collisions, doors, more object types, special tile types (water, instadeath, ...), etc.

Who is online

Users browsing this forum: No registered users and 2 guests

You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot post attachments in this forum