Ngin (my NES game engine)

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Ngin (my NES game engine)
by on (#152117)
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)
  • Tiled map (TMX) import
  • Sprite import (including animations, as .gif files or sprite sheets)
  • Debug logging (depends on NDX and Lua)
  • 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:
Attachment:
ngin-platformer.png
ngin-platformer.png [ 7.4 KiB | Viewed 7427 times ]
Re: Ngin (my NES game engine)
by on (#152120)
Interesting timing... I wish you luck!
Re: Ngin (my NES game engine)
by on (#152133)
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.
Re: Ngin (my NES game engine)
by on (#152147)
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!!!
Re: Ngin (my NES game engine)
by on (#152154)
Kasumi wrote:
Interesting timing... I wish you luck!

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.
Re: Ngin (my NES game engine)
by on (#152568)
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:
Code:
ngin_spriteAssetLibrary( ngin-sample-imported-sprite-sprites OUTFILE sprites )
    ngin_spriteAsset( IMAGE sprite.png SYMBOL sprite HFLIP VFLIP HVFLIP )
ngin_endSpriteAssetLibrary()

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.

Finally, in directory https://github.com/fo-fo/ngin/tree/mast ... ted-sprite is an example of how a sprite image can be imported and rendered.
Re: Ngin (my NES game engine)
by on (#152802)
Keep it up! I support this!
Re: Ngin (my NES game engine)
by on (#152818)
I pushed a couple of updates. Added another ninjaish (...) song to the sound sample and made it possible to switch the songs. Added surt's village mockup to the platformer sample project.

I also uploaded a video of the current state of the platformer sample at http://youtu.be/tXowAxuKjTY
Re: Ngin (my NES game engine)
by on (#152821)
Here's a screenshot of the map editor with the village mockup:
Attachment:
ngin-tiled.png
ngin-tiled.png [ 62.46 KiB | Viewed 7125 times ]

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.
Re: Ngin (my NES game engine)
by on (#152893)
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.
Re: Ngin (my NES game engine)
by on (#152895)
Erockbrox wrote:
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.
Re: Ngin (my NES game engine)
by on (#153114)
I added support for one-way platforms: https://github.com/fo-fo/ngin/commit/39 ... 1220772218

These blocks allow movement from the sides and the bottom, but block it from the top.

Attachment:
ngin-one-way.png
ngin-one-way.png [ 44.49 KiB | Viewed 7015 times ]
Re: Ngin (my NES game engine)
by on (#153500)
Another impressive project by thefox! Congratulations! :)
Re: Ngin (my NES game engine)
by on (#154374)
looking good ;)
Re: Ngin (my NES game engine)
by on (#155133)
Wait wait wait wait....

Is this an engine like one would have in a gamemaker where you just (simplified) essentially drop your art, levels and music in and BOOM! game?

Im simplifying this a lot because i need it to be simple for my brains' sake.
Re: Ngin (my NES game engine)
by on (#155237)
You know how there exist engines like Unity and unreal and gamemakr and such for current gen games. Wouldn't it be cool if someone made a big game engine for like NES or SNES or something retro.

I know you are making one, but I mean like a big company producing a big game engine for a retro console. I'm sure people would pay for an engine like that.
Re: Ngin (my NES game engine)
by on (#155246)
Estlib wrote:
Is this an engine like one would have in a gamemaker where you just (simplified) essentially drop your art, levels and music in and BOOM! game?

Nope. There are elements of that (map import from Tiled, for example), but it's never going to be drag&drop.

Erockbrox wrote:
I know you are making one, but I mean like a big company producing a big game engine for a retro console. I'm sure people would pay for an engine like that.

On the contrary, I'm sure that people would not pay for something like that. Besides that, the big game engines of today (Unity, Unreal, ...) are very much reliant on the massive amounts of processing power available in current computers, consoles and smart phones. That's what allows them to be so flexible and easy to pick up. There's simply no way to duplicate that kind of an experience on a limited platform.
Re: Ngin (my NES game engine)
by on (#155265)
Perhaps with the recent copyright claims against videos of modded Super Mario games, an original game engine with a level editor might be more welcomed as an alternative to modding Super Mario games.
Re: Ngin (my NES game engine)
by on (#155267)
I would really like to see this become a great game engine that would be easy to use aswell as be customisable.

Perhaps this can roll into a community project?
Re: Ngin (my NES game engine)
by on (#155308)
Estlib wrote:
Perhaps this can roll into a community project?

This project is not mature enough for that yet, but people are of course free to start their own projects. :)
Re: Ngin (my NES game engine)
by on (#158126)
I compiled all of the dependencies (CMake, Ninja, cc65, Python, NDX, Musetracker) into a single ZIP package (for Windows only, but then again so is the engine). The link and instructions are at https://github.com/fo-fo/ngin#easy-start

If somebody decides to try it out, let me know how it goes.
Re: Ngin (my NES game engine)
by on (#158233)
I can't help but feel like I'm partly responsible for giving people the impression that this is a game design platform because I said something about it in one of my first posts on this forum before I had much understanding of anything to do with NES development.

I almost wonder if I should edit it out so that's not the first thing people see and get the incorrect impression.

Now that I understand things a LITTLE better I wanted to come back and really check this out, because this looks like an extremely capable level editor for your game. I'm considering developing or having developed, a level editor for my game vs. keying in level data by hand. I wanted to check for inspiration but unfortunately I haven't been able to get this to work. I am definitely a noob when it comes to compiling and making and python and so, but I downloaded the deps zip and no go.

Okay, I believe I solved it. Command prompt would not execute the script if the parent folder had a space in it. Is this my mistake with a known issue or something with this particular program? I assemble NES apps which reside in my "Documents and Settings" folder through a .bat file which runs in command prompt.

Okay, now I must figure out how to use cmake to get an executable file... I think? This is new to me. I'm a little closer though. :)
Re: Ngin (my NES game engine)
by on (#158234)
darryl.revok wrote:
Command prompt would not execute the script if the parent folder had a space in it. Is this my mistake with a known issue or something with this particular program? I assemble NES apps which reside in my "Documents and Settings" folder through a .bat file which runs in command prompt.


from the README:
Quote:
The path of the engine source code must not contain spaces. An error will be given by CMake if this is the case.
Re: Ngin (my NES game engine)
by on (#158235)
Oh geez it was right there in the readme and the github. I feel dumb.

I guess I've made the program... I don't know what to do with the resulting files though.
Re: Ngin (my NES game engine)
by on (#158236)
It took me until now to realize how to say "ngin". I was just mentally saying the "gin" part like in "begin", and thinking it was a strange name.
Re: Ngin (my NES game engine)
by on (#158264)
darryl.revok wrote:
Oh geez it was right there in the readme and the github. I feel dumb.

Looks like that comment actually ended up in a non-obvious section when I modified the text. I should move it further up I guess...

darryl.revok wrote:
I guess I've made the program... I don't know what to do with the resulting files though.

Not much more to do than to start some of the samples in the emulator. You have to use the build targets for this because the working directory needs to be correct for Lua support. E.g. for the platformer sample the command is:
Code:
build-debug start-ngin-sample-platformer

You can also try changing some of the files (like the sprites, or the maps (requires Tiled)) and re-run the command to see how the build system magically re-imports everything. ;)
Re: Ngin (my NES game engine)
by on (#158269)
thefox wrote:
Looks like that comment actually ended up in a non-obvious section when I modified the text. I should move it further up I guess...

I see now why I missed it. It's in the dependencies section and I skipped that because I downloaded the library.
Quote:
If you use the above package, you can skip straight to the Configuring section.

I mean really I should have taken an extra couple minutes to read the rest of it but I executed this like a JMP instruction...
Quote:
You have to use the build targets for this because the working directory needs to be correct for Lua support.

Right on. That worked. Are the files in the samples folder the ones that are edited?
Re: Ngin (my NES game engine)
by on (#158279)
darryl.revok wrote:
Right on. That worked. Are the files in the samples folder the ones that are edited?

Yeah, that should be the only directory where there are non-code assets. The names of the sample folders correspond to the target names ("platformer" => "ngin-sample-platformer").
Re: Ngin (my NES game engine)
by on (#158519)
Amazing.

Is there any instruction to install?


Spanish:
Increible.

¿Existe alguna instrucción para poder instalar?
Re: Ngin (my NES game engine)
by on (#158636)
Diskover wrote:
Amazing.

Is there any instruction to install?


Spanish:
Increible.

¿Existe alguna instrucción para poder instalar?

Not beyond what's on the GitHub page.
Re: Ngin (my NES game engine)
by on (#160038)
You project looks very interesting !

Could you tell me under what license do you plan to publish it ? I could not find this information on your github repo.
I understood you do not plan to release it for mainstream usage, but I guess it would be good to clarify under what license your project is available on the repository.

Thanks !
Re: Ngin (my NES game engine)
by on (#160044)
There's currently no license, so it's "all rights reserved", simply because I haven't given it much thought yet.
Re: Ngin (my NES game engine)
by on (#161089)
Looking good as always thefox :).

I've been playing around a bit with a game idea I have lately, and the ability to prototype in lua and have it run in Nintendulator sounds enticing, the link to NDX on github, and in the NDX thread here is broken though :(.

Do you have a repo for NDX somehwere or any alternative download mirrors?
Re: Ngin (my NES game engine)
by on (#161379)
Anders_A wrote:
I've been playing around a bit with a game idea I have lately, and the ability to prototype in lua and have it run in Nintendulator sounds enticing, the link to NDX on github, and in the NDX thread here is broken though :(.

Do you have a repo for NDX somehwere or any alternative download mirrors?

My VPS provider accidentally (...) deleted all content on my server not long ago and I haven't bothered restoring anything. I'll put it back up at some point.
Re: Ngin (my NES game engine)
by on (#161452)
Anders_A wrote:
Looking good as always thefox :).

I've been playing around a bit with a game idea I have lately, and the ability to prototype in lua and have it run in Nintendulator sounds enticing, the link to NDX on github, and in the NDX thread here is broken though :(.

Do you have a repo for NDX somehwere or any alternative download mirrors?

I actually forgot about the prepackaged dependencies (ngin-deps-v01.zip, link in the GitHub page); NDX is included there.

Fair warning about Lua prototyping: I haven't given much attention to exposing Lua scripting to user code yet.