I'm back!
MAGE[no github link for this one]
Dev topic for this game coming soon!***********
MAGE has always been a tricky one to talk about, the reason for that being mainly because it's still in development. It's a game engine I work on very often and have become very fond of. It's functional, it's strong, and it's damn, damn big.
MAGE is the sort of game engine mad people make. It's a project where you'll be in the black screen stage for literal weeks and still be proud of and into what you're doing. But it does fit all the previous rules I've felt out - it's made for a SPECIFIC game, it has Dynamic Asset Loading (with package system), a Scripting engine for easy extensibility, Fixed object/rendering pipeline with optimization, Extensible component based design, No “bloaties”, working, stable multiplayer, a Dynamic INPUT manager with REBINDABLE keys, and, finally, proper seperation of GUI and objects.
Also, I think I finally figured out this inheritance biz.
DesignMAGE is designed to be lightweight when running, yet responsive and usable for both the person making a (top down fast paced rpg) game with it. The package system means you get to choose what's in the memory at a given time, what functions and mechanics form the "base" of the game, and what can be stapled on - in a word, mods.
This is a little hard to explain, so let me show you the layout of the game directory to sum it up:
/Gamebase
/Packs
/platforms
mage.exe
some.dlls
The most important folder here is the Gamebase folder. When the engine starts up, that's the first folder it goes for. It contains something referred to by the engine as a "package" - which, incidentally, is also the purpose of every folder in the Packs directory. The idea is that all your base code and asset data goes in Gamebase (which contains script files for both server and client) and, while the game is AWARE of all the other, custom packages that exist in Packs, it's up to Gamebase how they're loaded; be it through some gui or just all at once no matter what. A pack cannot ever operate on files outside of it, and all a pack's config files go inside that pack. Pretty simple.
Except it wasn't. I had to redesign 3 times. It's ok now.
Conventions- Camel case. Everywhere.
- I used default arguments only for things that were unimportant.
- Destructors were usually used.
AssetsThe system for assets in MAGE is simple.
All assets in MELT derive from the abstract object Asset. The 3 defaults are Sprite, Sfx and Font. Want to be able to load more? No problem! Derive Asset via the scripting engine. Just remember, your object has to provide a similar interface to Sprite, Sfx and Font for loading and use of the asset, including the routine that loads and prepares it from your file (through the engine's file objects) and the one that loads/unloads it during a loading screen.
Most of the time you don't have to mess with an asset object at all because entity/gui components do that tricky stuff for you. It's only if you're writing your own component that you have to use engine drawing functions. And usually, that's pretty easy!
Assets are separated into packs, and pack assets are separated into public and private. On the server side, Public assets are the most important - they're the ones that are sent to (and subsequently duplicated by) every player that joins your game. Private ones exist only on the server side, because... well, because it's there. You don't need to send, for example, a bunch of generator rules to the client, or a text file showing who has admin privileges. The client implements the same system, but to a different end - "private" assets on the client are for the client only, and "public", while normally kept TO the client, can be requested from them by the server at any time.
Oh, and spritesheets don't have their own animations any more. Instead, you use an animationComponent on an object. Which brings me to....
Game ObjectsThere are two types of Game Object in MAGE:
Both derive from something called config. And config is pretty unique. Config's primary purpose is as an engine utility class that allows for an object with custom attributes defined at runtime rather than a bunch of fixed members that can't change.
You have no idea how liberating something like that is when working with C++.
Config can be used alone, for simple reading of JSON files - it can load them in and export them, populating its variable tree accordingly, without people having to use the engine's default file object for opening files, write their own JSON reader, etc. But it serves a second purpose. Config is what both Window and Entity, vastly different objects, derive from. Both Windows and Entities can, as a result, be saved to and loaded from files or data held in assets.
But both classes expand on this more, by being based on Components. Alone, an Entity (or window) does nothing but exist and take up space. With components, you can have it act in certain ways, move in certain ways, draw in certain ways - the world is your oyster.
InputSame system as VOLT, with some improvements to the console side of things.
NetworkingOh god.
Every feature in MAGE has had to bend around this. Some are still bending.
When I started working on VOLT, I wanted to automate most of this. I wanted to create a networking system where the server/client side of things will keep out of a mod's way, and everything will be automatically handled without VOLT's large packets or dangerously unstable connections.
The first step of this is client/server commands. These are, put simply, a way for mods and the game itself to send their most simple text based communications over the network. A command has a name and a function to be called by it. When whichever side of the client/server model that is on the other end sends a command and an accompanying operand string (which can be processed however you want it to be) the function will be called to handle it. It's a beautifully simple system, without which simple net communication not handled by the engine would be a LOT harder for everyone.
Then there's the synchronization. Since everything is custom, prediction is kind of hard. Since the client doesn't know how something moves, animates, or changes, the server has to do a bit more work. Packets are time stamped, and for entities using engine components, limited prediction is possible. To further improve things, I'm debating whether to allow those using the scripting engine to "predict" object update packets before they arrive.
As I said at the beginning, if this one goes to plan, my devlog will be going up soon. Stay tuned, I guess.
And, of course, I'll probably come up with more stuff to post. But probably not soon. So I'm changing the thread title. Since I'm all out of tales to tell for the time being, this is now a thread for everyone to share their expertise on this subject. Enjoy!