Dungeon Ho!: Unity has been in development for long enough that I’ve got a solid prototype working, and since one of the primary focuses (foci?) of the project has been refactoring and redesigning, I thought I’d take a moment to talk about the two biggest time-savers I’ve managed to implement in the rewrite.
Using the platform’s native UI framework
This is a huge one. HUGE. I’ll say it louder for the people in the back; IT’S HUGE.
When I first wrote Dungeon Ho! for the Android platform, I didn’t know anything about layouts or its native input controls. All I could do was blit to a SurfaceView, and given that my background was in J2ME development, which is both Java-based and requires you to do that, I knew that would be enough. I was used to rolling my own UI components; I knew how to make buttons click and dropdowns… drop down. I could scoll my own text, even; and I could be assured that it’d all work as I expected and I wouldn’t see some last-minute framerate drop because you can’t overlay, say, a FrameLayout over your SurfaceView because reasons.
That was the idea, anyway; go with what you know to keep development time short. And I think in the long run it was a good idea, because DHo! still took close to two years to finish. Imagine how long it’d have taken if I had to learn Android’s UI stuff on top of it.
Now, I’ve gone the other way. I learned Unity’s UI/canvas system before I started working on the port and all of the UI controls are done “the Unity way”, and it’s saving me a shit-ton of work. All of that event handling code, the animation code, the mouse-clickthrough code, the math and resizing code, all of it is already done for me. Adding a new screen is as easy as drag-and-dropping a new canvas and tossing some buttons on it. I did the entire start-game flow (…with placeholder art, natch) in little under an hour. That would have taken me a day or two, the old way.
So in short, know your tools. You have no idea how much it helps, no matter how good you are in other ways.
Data, data, everywhere
Roguelikes are procedurally-generated, and DHo! probably moreso than most, these days. Everything is created in code, from the maps to the monsters’ stats to the items; there’s no entry in a list that says “Potion of healing: heals 25hp”. The code does it all; generates a base potion, randomly figures out what effects it has when drunk, and then names it accordingly. This makes for a very, very varied playthrough experience.
It also makes for a fucking huge, complex codebase.
I’ve already touched on this when I wrote about the monster definitions; yes, you can follow the same process to copy-paste code templates and rename variables to create a new Monster, but why would you? Just define a JSON file with the monster’s parameters (eg. “Kobolds range from 50 to 100 pounds”) and let a generic routine parse that data and figure it out. It’s so much simpler to add an entry to a generic Item file that says “Daggers can be made of wood or metal” than to have to remember which chunks of code to copy and modify to say “if this item is a dagger, make it out of wood or metal”.
Why didn’t I do this the first time? I think for some reason I assumed that if I defined data files I’d not have the flexibility I had in procedural generation. Also, and this goes back to knowing your tools, I didn’t know how to handle text files, especially JSON, in Android… and didn’t think it was worth researching. I will never do that again.
Well, there you have it; the two biggest lessons I’ve learned in porting this project so far. The new codebase is much cleaner and more flexible than the old, and I’ll be very careful to make sure I don’t sacrifice this going forward. I will also never not take the time to do proper research on a feature and cut corners in my personal projects again. After all, I’m not on a deadline.
Tune in next time when we return to coding, with the promised dungeon generation classes.