AGNES, a simple yet powerful engine + framework.

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

na_th_an
Posts: 558
Joined: Mon May 27, 2013 9:40 am

AGNES, a simple yet powerful engine + framework.

Post by na_th_an »

Image

MT Engine MK1 NES / AGNES (or MK1_NES/AGNES for short) is a framework composed by a modular, highly customizable engine and a toolchain designed to make simple games for the NES. MK1_NES/AGNES has been designed to produce games which run in simple discrete logic mappers so they can be easily reproduced using cheap, readily available boards.

So what can you make with this?, you may wonder. Well, many things:
  • Flick-screen games (no scroll).
  • Top-down view or side view (platformer) games.
  • Acceleration/intertia/friction based movement, 100% configurable.
  • Several engines for side view games (run and jump, jet pack, diving, etc).
  • Several ways to kill enemies (shooting engine and, albeit only for the side view engine, punches and kicks, or jumping over enemies).
  • Integrated scripting engine (using a custom, simple language) and / or code injection points to make engine modifications easy.
  • Customizable screen renderer for map data.
  • Several ways to manage items and inventory which can be used together.
  • Interactive elements on screen (for example, NPCs).
  • A simple text box implementation.
  • Several kinds of enemies, and the ability to code simple behaviours.
  • Easy way to configure the actors’ bounding boxes for collision.
  • NROM or CNROM directly supported, GNROM easily manageable, UNROM definitely possible without much hassle.
  • Possibility of using extra, unused CHR-ROM banks to store binary data, making the most of oversize CN-ROM boards (for example, INL’s CNROM board which offers up to 128Kb of CHR-ROM data!).
  • You can always use stuff from our toolchain for things not related to our engine at all.
Little FAQ

- Is this better than NESmaker?
- This is not like NESmaker, not tries to compete against it. I just took our first NES engine and began cleaning it up - but ended rewriting it from scratch and liked the results, so I'm releasing it. It's just a simple engine you can use to create simple yet fun games easily. It targets small, simple discrete logic mappers.

- Do I need to know programming?
- Not really, but surely it helps. The more you can dig in the engine, the more unique your games will be.

- Can I sell the games I create
- Definitely. Just tell us first, we just like to know :-).

You can check some examples:

Cheril Perils Classic
Image

Cadàveriön
Image

Botèe
Image

Grab it at:
https://github.com/mojontwins/MK1_NES

I've managed to write some documentation, but something like this needs a tutorial which I'm in the process of writing.

I know this isn't the best place to promote something like this as most of you are proficient coders, but I just wanted to show you what I've been up to since January. Cheers!
Last edited by na_th_an on Sun Jul 22, 2018 4:44 am, edited 1 time in total.
User avatar
Banshaku
Posts: 2417
Joined: Tue Jun 24, 2008 8:38 pm
Location: Japan
Contact:

Re: AGNES, a simple yet powerful engine + framework.

Post by Banshaku »

I browsed lightly the code yesterday night to check how things can be done in C. My previous attempts were in asm only so example like theses will give me some pointers on how things should be done.

The last thing I worked on 9 years ago what collision detection and had many issues with obscure bugs that I couldn't find the cause. I tried to find some example in you code but it was in the middle of the night so my mind was not clear enough anymore :lol: what I wanted to check is when doing a platformer, in what order the checks are done and why. For example, if the actor would be moving right and falling at the same time, which one has priority when checking collision and why. In my case I think I was checking the attribute of the metatile first in the moving direction then the falling one but sometime the actor was ejected in strange location which I didn't find the cause yet.

Now that I'm remaking that logic in C and keep only the data processing in assembler, maybe those bugs won't happens but I just wanted to look at other people code for inspiration.

As for the code, I didn't check much yet but one thing that really stands out is the amount of conditional compiler flags which I can see is to make it more flexible but at the same time makes the code harder to figure out what it does. I guess if you never edit the engine per-se then it's not an issue. Another thing is a lot of code seems to be in the header files, which seems unusual for me but I didn't code in C for ages so maybe this is a common practice that I was not aware of.

It's good to see initiatives like theses! If I dive more into the code I will see to give some feedbacks about it.
dullahan
Posts: 96
Joined: Mon Dec 07, 2009 11:08 am
Location: USA

Re: AGNES, a simple yet powerful engine + framework.

Post by dullahan »

Thanks for sharing! Will definitely check this out.
na_th_an
Posts: 558
Joined: Mon May 27, 2013 9:40 am

Re: AGNES, a simple yet powerful engine + framework.

Post by na_th_an »

Banshaku wrote:I browsed lightly the code yesterday night to check how things can be done in C. My previous attempts were in asm only so example like theses will give me some pointers on how things should be done.

The last thing I worked on 9 years ago what collision detection and had many issues with obscure bugs that I couldn't find the cause. I tried to find some example in you code but it was in the middle of the night so my mind was not clear enough anymore :lol: what I wanted to check is when doing a platformer, in what order the checks are done and why. For example, if the actor would be moving right and falling at the same time, which one has priority when checking collision and why. In my case I think I was checking the attribute of the metatile first in the moving direction then the falling one but sometime the actor was ejected in strange location which I didn't find the cause yet.

Now that I'm remaking that logic in C and keep only the data processing in assembler, maybe those bugs won't happens but I just wanted to look at other people code for inspiration.

As for the code, I didn't check much yet but one thing that really stands out is the amount of conditional compiler flags which I can see is to make it more flexible but at the same time makes the code harder to figure out what it does. I guess if you never edit the engine per-se then it's not an issue. Another thing is a lot of code seems to be in the header files, which seems unusual for me but I didn't code in C for ages so maybe this is a common practice that I was not aware of.

It's good to see initiatives like theses! If I dive more into the code I will see to give some feedbacks about it.
I guess there's a lot of different approaches when it come to collision detection. I use box collision using a couple of points, or three if the player collision box is tall enough to exceed the height of a tile. The key is doing the axes separately. First the vertical, then the horizontal, or the way around (slopes work better if you do horizontal first, but this engine doesn't support slopes yet.

What I usually do, for each axis, is first calculate the changes to V, then apply V to the coordinate, then check for collisions, the adjust if a collision was registered. For collisions, it's easier to branch depending on the sign of V, so for example if you are in the vertical axis and V < 0, you check the points at the top of the collision box only.

As for the amount of conditional code, it's there 'cause there's a main config.h file in which you can heavily configure which modules you want and how they behave. Surely this makes understanding the code harder, but it allows for flexibility. Just changing config.h, the assets, and the code injection points or the script, you can create a wholly different game. Sgt. Helmet Training Day, a top-down shooter is in the testers directory, ported to this engine from the original assets in a matter of minutes.

Take in mind that one of the goals is make the most of cheap mappers, specially CNROM, so the more stuff you can leave out, the better.

For a much more didactic product in this matter (as it features nice, readable code, for example), I'd check NES Starting Kit
User avatar
Banshaku
Posts: 2417
Joined: Tue Jun 24, 2008 8:38 pm
Location: Japan
Contact:

Re: AGNES, a simple yet powerful engine + framework.

Post by Banshaku »

@na_th_an

My code for checking velocity is now based on some ported code from the asm version which used 2 bytes for it, one is the increment and the other was for precision (once precision passes over 0xFF, it increase the velocity) but in C I cannot uses the carry flag like asm so I need to improve the logic. I didn't use negative velocity too (my bad, the code was a quick hack a long time ago to test the engine) so I need to improve the current flow. It makes more sense with negative velocity since it reduces the tests, I need to test it that way.

As for define, I didn't mean to complain, sorry if it looked that way. It just at first it seemed like a lot but there is reason so I have no issue with it. It just for an outsider, at first it's harder until you know the flags. Once known, it will be easier to follow. But like I said, if you never touch the engine then the only thing to be known is what the configuration flags are for.

I will try to vertical collision then horizontal and see how it goes. Thanks for the tips!
User avatar
dougeff
Posts: 3079
Joined: Fri May 08, 2015 7:17 pm

Re: AGNES, a simple yet powerful engine + framework.

Post by dougeff »

My thoughts. This would be more useful if it was easier to read.

1. comment every variable when declared.

https://github.com/mojontwins/MK1_NES/b ... v/ram/zp.h

I tried to make sense of these. Half I can't.

2. Use slightly better descriptions than this...

https://github.com/mojontwins/MK1_NES/b ... ts/enems.h

"// Enems structure is {T XY1 XY2 P} x 3 x MAP_W x MAP_H"

What is T?
What is P?
but I just wanted to look at other people code for inspiration.
So do I. I'm thinking about changing my tutorial completely, to use a "vanilla" neslib approach.

I see @nathan that you are using a modified neslib. What is different about it?
nesdoug.com -- blog/tutorial on programming for the NES
na_th_an
Posts: 558
Joined: Mon May 27, 2013 9:40 am

Re: AGNES, a simple yet powerful engine + framework.

Post by na_th_an »

I didnt intend this to be a piece of readable code ;-) ideally, when the documentation is finished and the tutorial is written, you shouldn't have problems creating games. As I said, this is not a tutorial or a clean code showcase :-D anyways i'll try to find the time to better document the code.

Neslib is not really modified. It's just the old version with famitone2 instead of famitone1.
User avatar
Banshaku
Posts: 2417
Joined: Tue Jun 24, 2008 8:38 pm
Location: Japan
Contact:

Re: AGNES, a simple yet powerful engine + framework.

Post by Banshaku »

Yes, I saw thoses variables too :lol:

I guess there is no rush but if they cannot be renamed, at the least a simple comment about their usage would help to understand the engine better ;)

Regarding neslib, unless you use a framework like AGNES that uses it, I found that I didn't need to use it that much once you understand more about how to interface your asm code with C. What was important was that the latest runtine for C65 was compiled with the strict minimum and I was fine. Neslib helped me understand how to interface my asm code with C so it was very useful as a learning process and I'm grateful about it. Now I do not need the code with what I'm testing. I did kept the pad routines since it was managing the trigger/state, 3 checks and felt it didn't worth updating my code and debug it when one is already working properly anyway.

Since my project used many concept that was different like list of metatile entity that are pushed to OAM buffer once process is finished I couldn't use the current methods. I may use the RLE screen one or maybe random, those one I may find some use at a later stage. As for NMI, I'm using dynamically set ones so I found a way to set them from C, which is useful for state management.

My only concern with C is I don't know what cause bottleneck and should be avoided and what is perfect for. For example, I try to avoid to call method in my logic check for the user input because I'm concerned that all those resulting jsr/parameters on the software stack (when applicable) would slow down then just using one big function. This is one thing I want to check in AGNES to have a better idea what should be done or not.

I hope I can learn a lot of new tricks from it :)
na_th_an
Posts: 558
Joined: Mon May 27, 2013 9:40 am

Re: AGNES, a simple yet powerful engine + framework.

Post by na_th_an »

Thanks for the feedback :)

Next in the TODO list, before v1.0 is released:

- Describe globals in detail, and add comments to bss.h and zp.h.
- Document every #define in config.h.

That would complete basic reference docs. A tutorial will be ready in the near future.

Cheers!
User avatar
dougeff
Posts: 3079
Joined: Fri May 08, 2015 7:17 pm

Re: AGNES, a simple yet powerful engine + framework.

Post by dougeff »

If you are renaming variables, consider renaming this specifically.

i = pad_poll (0);

Found in every game.

'i' is about the least descriptive variable name, and confusing since it is also used for loops, and impossible to search for.
nesdoug.com -- blog/tutorial on programming for the NES
na_th_an
Posts: 558
Joined: Mon May 27, 2013 9:40 am

Re: AGNES, a simple yet powerful engine + framework.

Post by na_th_an »

You are right. I always have called it pad0, I dunno why I didn't get around changing it when I did the rewrite. Maybe 'cause it was gradual and never touched the "heart".
User avatar
Banshaku
Posts: 2417
Joined: Tue Jun 24, 2008 8:38 pm
Location: Japan
Contact:

Re: AGNES, a simple yet powerful engine + framework.

Post by Banshaku »

I guess when you write code fast those details often gets overlooked because they seems pretty obvious at the time and they provide quick feedback while prototyping. In those case, naming is not that important. It just when you start to read back that code 1 year from now and get in a world of hurt.

In my case I don't know if it appropriate but I'm experimenting with a global variable that keep the state of the game so if the player manager requires to know about the pad it would do something like:

Code: Select all

// Retrieve global state 
extern gameState_t g_gameState;

...

// somewhere later in the code 
    if (g_gameState.pad1.trigger & PAD_A) { // or .state , depending on need
that way, it's pretty obvious what you are trying to do. Maybe I'm over-engineering, like always :lol:
na_th_an
Posts: 558
Joined: Mon May 27, 2013 9:40 am

Re: AGNES, a simple yet powerful engine + framework.

Post by na_th_an »

If something makes readable code PLUS you are comfortable with it, go ahead :-D

I renamed "i" to "pad0" and wrote comments to zp.h and bss.h. Also reordered definitions so code is more tidy. All updated in the repo.

Next thing is write up a reference to the #defines in config.h.
na_th_an
Posts: 558
Joined: Mon May 27, 2013 9:40 am

Re: AGNES, a simple yet powerful engine + framework.

Post by na_th_an »

Update: added documentation about all those #defines in config.h and what to do with them. Also fixed a couple of minor bugs.

https://github.com/mojontwins/MK1_NES/b ... _config.md
User avatar
Banshaku
Posts: 2417
Joined: Tue Jun 24, 2008 8:38 pm
Location: Japan
Contact:

Re: AGNES, a simple yet powerful engine + framework.

Post by Banshaku »

I just parsed very fast the md file and there is so much details! So many things can be done with it. Must have take a lot of time to make all of theses ^^;; But this mean with that engine, once you know it well, you can make a lot of small games very fast.

Good work :)
Post Reply