• Add Review
  • Subscribe
  • Nominate
  • Submit Media
  • RSS

"Initializer" monsters

I wound up spending most of what time I had for game dev this month on the DynBattleDisplay plugin again. When I tried to drop it into Forgotten Gates, it caused memory access errors. :P I suspected this was due to the fact that FG uses "transforming" monsters, and I was right, but not for quite the same reason I thought. It didn't help that when I tried using the simple demo RM2K3 project I made for DynBattleDisplay to test the plugin with monster transforming, it didn't cause any apparent problems. Even worse, when I added debug code to try and trace when the crash was happening in FG, the exact point of failure would change depending on how much debug code was present. X)

Eventually though, I noticed that even the demo project was getting some minor graphical glitches in response to monsters transforming, even if it wasn't crashing. It turns out that when a monster in RM2K3 transforms, it keeps its current HP and MP, even if they're more than the maximum for its new form. DynBattleDisplay was calculating the width of HP and MP bars to be more than 100%, and as a result was reaching into memory beyond what was allocated for the bar images. This was especially egregious in FG because the "initializer" monsters I use for setting up battles have the most HP and MP possible. X) So I fixed it such that the bars could only go to 100% at most...and then I added a couple other features, seeing as I needed to re-release the plugin anyway. X9 There's now an option to show the exact amount of HP/MP as a number, and to make the display show while the player is pointing at a particular battler.

Since I mentioned "initializer" monsters in the above explanation, I think that would make a good topic for this month's in-depth glance. The initializer system is a hack born of not just convenience, but desperation. My battle system for FG is extremely custom, and it involves a lot of monster group scripting -- in other words, event script that is associated with a specific monster group in the database. This is necessary because there are certain event commands which can only be used in monster group scripting, most notably those which affect monsters (since they don't exist outside of battle). As you might imagine, my plan was to implement everything in a single "template" monster group, then copy that to make other monster groups as needed. Not a great system, especially considering I'd certainly need to make changes every so often and then recreate the other monster groups alllll over again, but you do what you have to, right?

Well, at one point I decided to go ahead and make a bunch of copies of the template group just as a stress test of sorts. The results were not pretty. After I made a certain number of copies, the editor popped up an error message saying there wasn't enough memory to form a stream. Worse still, when I hit the OK button to try saving what it already had, it popped the same message up, then promptly deleted the whole database. X) Empty maps, no heroes, nothing. Fortunately I was doing this on a copy of the project, and even if I hadn't I would've been able to recover everything from my thumb drive. Still, after trying this over again with all sorts of variations, I concluded that I'd be limited to a couple hundred monster groups (and even that number would probably go down as I continued to add other things to the project) if I continued this way, and that was unacceptable.

For a little while I pondered (not for the first time) the possibilities of porting the project to a new platform. I'd already purchased a license for RPG Maker XP, mainly just to ethically justify my use of RM2K3, which wasn't available for purchase at the time. RMXP uses Ruby scripting, which is much more object-oriented and easier to write in than RM2K3's point-and-click scripting, so it wouldn't take nearly as long to reimplement the systems as it took originally. It does have one or two peculiarities of its own that I'd much rather avoid, though, and I really like the FF6-style combat system of RM2K3. I could also have tried implementing the game from scratch using a much more open-ended game development environment like Flash or even C++, which would frankly have been better experience for me as a programmer. But, that would've meant having to deal with a lot of low-level details like menu systems, graphical manipulations, data saves, etc. etc. etc. And of course, no matter what new platform I might move to, there would be a considerable amount of invested work lost.

So after I considered those options for a while, I went back to RM2K3 and searched for a workaround to my problem...and lo and behold, I found yet another crazy way to make the system do things it was never intended to. X) I created "initializer" monsters, which are blank sprites with a simple behavior: transform into a different monster based on a switch. By making every battle start with a "back attack", I ensured that monsters will go first, which is okay because their first turn is used simply to transform. With this system, I was able to implement a single monster group that could transform into any monsters, even in any combination I might choose. It's a little inconvenient because of the back attack thing, but it works, and it both solved the memory problem and gave me the potential to finely control the composition of monster groups at run-time.

Of course, as with so many other things, I think DynRPG will give me an even better way of handling this. X) There's a command in DynRPG which allows monster transforming to be done manually, without needing them to expend a turn on it even. It's experimental still, but with any luck it will serve my purposes and will allow me to avoid using "back attack" for every battle. I'm considering writing up a tutorial for the initializer method, but I'd like to at least find out whether the DynRPG approach would work so I can link to it as an alternative if possible.