Thursday 22 August 2019

Magnum foundation: POUCH and Level loading

Hello there!
Here is a blog post on some updates regarding Magnum Foundation like its 'POUCH' and level loading component .

Preface

I decided some time ago that I wouldn't just use "Magnum Foundation" for making Bounty Hunter III or Othermind. I thought about using it to make any game that has a 2D top-down perspective; it could be a mystery game or even an RPG. It would also save me time trying to create the map loader, scripting and movement from scratch.

Cutscene scripting

I've made a lot of changes to POUCH, namely the way that scripting is operated, rather than being stored in the data of a trigger like Bounty Hunter II, it is stored in the data of the map itself. Triggers exist as an instrument to call parts of the script.

The areas which the triggers call in the script are called labels, which are basically entry points in the script. The pointer which points to a specific instruction in the script goes where the label is and one-by one calls the instructions until it reaches a "break event" command. The instructions involve things like moving an object to a particular place, loading a certain map, enabling/disabling an object, putting up a dialogue box etc. The reason I think it's a good idea to put a script in the map rather than confine it in a trigger is if multiple triggers call the same script, it would save me time having to copy and paste the same trigger and events. It's also convenient if I want to edit the event later on, because I only need to change it once.

It looks a little bit hard to understand
One aspect of POUCH I would like to implement but haven't implemented yet is a static script. This script is not confined to a specific map, it can be used anywhere. This would be useful for events such as saving, game overs etc.

This system was inspired by Cave Story's scripting system in its map editor. Labels are called by certain objects and instructions are executed until they reach an "end" block.

Level loading

I've implemented functions for putting in tile objects, characters and triggers into the map based on some JSON data. When the loader loads map data, it calls functions that handle spawning objects and setting parameters for them .These functions can be overridden with functions that check the loaded object's ID and set their parameters accordingly. This can be useful for things like the minigame objects I talked about in my previous post relating to Othermind.

The "override" functions are prevalent here


I also put in custom parameters for level data, it can be a string or a number, associated with a name. I did this because I feel like trying to hard-code all these parameters into the level data itself would be incredibly tedious and make the process needlessly complicated. Custom parameters are much easier and is a far more broad way of implementing new bits of data without needing to write new code to cater to a certain objects data.

I'll write about this idea in action; say I have a character who requires a certain item or an enemy can help the player. Hard-coding is a solution, but is not a great one, since I would need to write more code and would be disastrous later on when I clutter the source code with characters' code which have very few differences from its base. To combat this issue, I would create a parameter called "Desired item" or "Relationship" and put the name of the item or the character. This is then saved in, and the only hard-coding I may need to do is to modify the level loader's function to set one variable in a character's code according to these parameters.

Bounty Hunter II did have specific requirements like these, for example in one boss battle, one character was invincible until their minions were defeated. In that game though, I hard-coded the specific names of the minions into the boss' code so they would keep track of them. Now if I were to do a remake of Bounty Hunter II in this engine, I can just simply use custom parameters to tell what characters the boss needs to keep track of.

Path-finding

In one of my 4 projects I'm currently working on at the moment (yes it is a lot for mostly one guy), I've experimented with and implemented path finding. I've talked about this in one of my updates on Bounty Hunter III.

Unlike Earl's Order, where the nodes are all around, the nodes in this are different. The nodes that this engine uses are manually placed and linked to other nodes, a bit like connecting wires to each other. Another difference from Earl's order is that all the nodes are walkable, meaning that there are no "wall" nodes which can't be walked through. Time can be valuably saved using this approach because you do not need to worry about if the pathfinding character gets stuck in a wall because they will always follow the nodes, and you'd need to be crazy if you were to put the nodes in a solid object or a ditch.

This seems fine for an environment that won't change anytime soon, but what about one that will change? Say, a boulder obstructs a path. What could be done about this? I would simply just re-implement the walkable flag on to the node, and if a boulder falls on to a path, the nodes on that path would be unwalkable. Once the boulder is removed, that node would be walkable.

Early into this project's development, I considered to have characters try to path find based on tile nodes, as I thought manually placed nodes were 'cheap'. I did certainly attempt this, but it didn't go to well since it was very buggy and it would look pretty robotic. I then decided against it, but my opinion on manually-placed nodes being cheap has not changed, it's an efficient time-saver and is still better than having enemies that eagerly run towards a player, despite a wall being right in front of them. I think that manually placed nodes will take up less memory space since far less nodes would need to exist and will allow me to have much more autonomy on where the enemy can go. It can certainly help in avoiding ditches as well.

Conclusion

I've been working quite hard on Magnum foundation and I'm in the process of refactoring Bounty Hunter III and Othermind's code. And every day, I completely regret splitting Magnum foundation into these two games rather than making these two games from scratch using this library. Well I'm doing this with the path-finding game that I've got in development, and I hope progress will go much smoother there.

I'm thinking about writing a short post on an in-house application called "PUPPET" (Pixels Ultimate Proprietary Placement Editing Toolkit), since one of my in development games are using that tool to make levels for it. That game is also going to be released the soonest out of all 4 games I have on the development table, on the date of 15th September.

That's all from me.



No comments:

Post a Comment