I’ve spent the last couple of days playing the role of digital marriage counselor, doing my best to get the different parts of the Paper Zeppelin code to sit down and chat. The issue is that the specific objects that I want to talk about, don’t really exist in the code.
I’ll explain. On a basic level, the Paper Engine only creates things. It works almost like a really advanced version of the code I put in The Thief’s Tale that dealt with background objects. So I tell the system to make an object, and then every time the game cycle runs it updates all of the objects. I get the impression this is how most proper game engines work. The silly thing is that the objects that I create they never really exist in any meaningful way. In Thief there were a shitload of rectangles, but each of them were distinct. I could explicitly reference any one of them if I needed to because they were numbered 1-12. Now in Paper Zeppelin if I make ground it’s a spawned thing. It isn’t numbered in any way. The only real way that I have to have them interact is to put them into an explicit list that I can reference. So when I need to see if ground is touching I ask the computer to check against everything in the Ground List, but if I wanted to know about the specific piece of ground at 300,100 – well that’s too bad.
This predicament led me to a kind of cool function that is part of the C# library called Static. What it does is it make a function considered to be an integral part of an entire class. So say I had a function for the players that checks their controls or something, if I make that Static I can call that function from anywhere. The problem that I discovered was that the function that was called was part of the Code, but not an integral part of the object that was running that code. So if I made a static function that wanted to call a value, the system would crash because there is no value because I was not referencing a specific Fighter Plane, but only the Fighter Plane Code as a whole, which seems pretty ridiculous.
What I was trying to do was make the Fighter enemy shoot a bullet. So the next idea was to fetch the player list, so it would know where the player was and do its thing. So I tried to have it look at the list of all the players by making the player list a Static (or integral) part of where it lived. After doing this I discovered a weird thing – the player list did not want to be Static. It created all kinds of problems wherein I couldn’t call my own code. The answer for this came from the structure of the code itself.
This takes some explanation, so bear with me. In the Paper Engine there is the Main game code. This code creates an instance of a Class called Sprite. The Sprite Class in turn creates a code Class called Sprite Manager. The rest of the stuff, everything from players to enemies to explosions are all hanging off of the Sprite Class and the SpriteManager Class. The Sprite Class is the “Arch” Class that more or less lords over all the other Classes (which are enemies and anything else that would be drawn on the screen). It defines what they are, what they need to run and handles all of the drawing and other super basic stuff so that the SubClasses don’t have to worry about it. The Sprite Manager is responsible for creating new versions (or instances) of the SubClasses and making sure that they update and brush their teeth.
The thing about being able to look at stuff is that you can only look at things that are below the part of the code that wants them. So the Sprite Manager can get almost anything from any of the SubClasses. For example, it can know what position stuff is in and uses this information to calculate collision. On the other hand, the Fighter Planes cannot get information from the Sprite Manager, since it is “above” them. Further, it can’t call on information that is next to itself, like the Fighter Plane cannot find information about a player directly.
Going back to the original issue, the list of players could not be considered static, or an integral part of the Sprite Manager Class. The problem was that list itself was part of a larger Game Component Class that lived inside the Arch Sprite Class. Since I can’t call upstream, that didn’t work. That also made it impossible to call the SpawnBullet() function from inside the Fighter Plane code. It lived somewhere else. Even worse, since SpawnBullet() even mentioned something in it that was “above” where I was calling, the whole thing fell down. It’s like the system can follow the specific information and know where it was originally from.
Long story short was that I could have the Fighter Planes know where a player was (since that information could be accessed by the Sprite Manager, which in turn could feed it downstream again to the Fighter Planes), but couldn’t shoot. The solution is our titles, which I’ve finally gotten to. You see, the Fighter Planes just had to ask permission. I was trying to make them do everything themselves, when instead it was far easier to simply just ask. Like this:
“Hey Fighter Planes, do you want to shoot a bullet?”
“Yep, we sure do.”
“Alright, let’s do it then.”
“Eehhh, I can’t. It won’t let me.”
“I want to do it all by myself.”
“Why isn’t there a bullet then?”
“Mean old Sprite Manager won’t let me push the button.”
“Why don’t you ask then?”
“Okay, Mr. Sprite Manager, can you push the button?”
How I did that was add a new function to the Sprite Arch Class. Now it has a thing called Summon(). It does one thing – pass a variable back from the SubClasses. That’s it. However, when the Sprite Manager gets that, it does different things based on what that number is, like create a bullet. I did have to add that to all of the SubClasses, but now that it works, it’s pretty awesome.
– Whew. That was a lot of explanation into how the basic Paper Engine is designed. Sorry about all of that. The question then is, why the hell would I explain how that works, and why care? The reasoning is this – I’ve made the engine generic.
The thinking goes that all the engine does, is spawn things with certain behaviors, track their interactions, handle controls and drawing. Really any game engine does these things. What makes a game specific is the kinds of things that are created. Say I create a ball, and players and bases, I could make a baseball game. Say instead I make a soldier, and some guns and some cover and I could make a cover based shooter. The engine underneath is 95% the same in both cases. Some of the way rules are handled is different, but most of the gameplay is really the objects that are in the game.
So, moving forward from here to anywhere, the Paper Engine can handle almost anything that I can create with it. I’m making Paper Zeppelin, but it will also be able to power The Star Frog EP, and even Silver Knight. Shit, I could rebuild The Thief’s Tale with it. I can build whatever from here moving forward using my dedicated engine. Having it already work will allow me to do crazy fast iteration in future projects and hit the ground making the objects that will define the game itself, not worrying about drawing stuff on the screen and frame rates. A custom engine that I can do anything with. Best thing ever.
I’ve got a golden ticket…