Under the Hood

Hello, friends!

Well into v0.34 now, which is a build that is primarily about quality. I don’t have much from that body of work that I want to show you right now, so instead, I figured I’d talk a bit about the nuts and bolts of development for the one or two people who’ve asked me about this.

I don’t usually like to crow about things I’ve done while programming, since I’ve never seen myself as anything like a role model in this regard. I’m much more comfortable with self deprecation in this arena, so I’ll start by saying, “Please forgive my ugly but adequately competent code.”

Most of the standards I’ve adopted for Unity development are things I’ve come up with on my own. Most of the example code I saw when I started was pretty simplistic and/or didn’t look like it would scale well. They didn’t have any classes for people to learn best practices at the time either (keep meaning to check one of those out).

code1.png

After a bit of trial and error, and a bit of refactoring, I settled on something resembling an MVC architecture. Each Unity scene is a major system with its own UI needs, such as combat, dungeon exploring, and the overland map. In the script, each of these scenes has a “master” class (OverlandMaster, DungeonMaster, etc), which is a Monobehaviour at the top of the GameObject hierarchy that hooks into various parts of the Unity game space for presentation purposes, such as opening dialogs or receiving input from user controls, making it analogous to an MVC view component.

Closely linked to the master class is a “context” class, which is the true power behind the throne.

code2.png

These contain all of the data for scene-specific game state and have references to a number of “manager” mini-boss classes that handle things like rendering overland locations, spawning characters in combat, or serving localized strings for labels or character dialogue. From the perspective of the game logic, if you want to get something done without bothering to understand anything in the Unity API, there’s probably a function abstracting it all away inside one of the context classes. This makes them sort of like an MVC controller, but also sort of like the MVC model.

But if you want to the most central, most model-like part of the system, you can go to the end-game boss, GlobalContext, or gCon as I like to call it.

code3.png

So many data objects… And yes, I should probably refactor those to not be Util functions…

GlobalContext holds all the core game data, and all of the game state information that isn’t scene specific. That doesn’t mean all the graphics and audio are loaded here, but gCon knows where those things can be found. Want to know what a murkbeast looks like? Do a resource load for gCon.GetCharByKey(“8D4E421BA0FBCAB”).profilePic; Want to know what sort of terrain is at (127, 504)? gCon.terrainCodes[127, 504]; Want to know who’s stationed in the city of Vetorna right now? gCon.cities[“VETORNA_INFO”].idleDudes.dudes;

Oh, yeah. I have been using a few silly names for variables…

About 95% of all the data crammed into a save file comes from gCon. And the remaining 5% is probably stuff that should be moved there.

Want some music? gCon.per.PlayClip(SoundPaths.OVERLAND_BG1, 1); This makes reference to “per,” which is the Persistence class, sort of a global view component. It’s a Monobehaviour that sticks around between scene changes, handling audio and a few visual effects, like fades to black. Persistence also executes scene changes, which is a fairly simple process right now, but might eventually have some threading.

Anyway, that’s a high-level overview of the structure. If you have any specific questions about common problems with Unity projects and how I might have solved them, I’d love to hear them.

Thanks!

Previous
Previous

Rumblings

Next
Next

Life in the Big City