For all of those who know XNA, you know when you’re really lazy and insist on coding everything into the Game.cs class, just so I can control everything from there and not having to worry about stuff?
I did it with Killplex. And I was very, very wrong in doing so.
I had a really big mess of code, where Game.cs would have everything related to network, sound, drawing, and even the input was mixed with regular non-input logic. When I tried to make new features… oh boy. I was like, “let’s browse through the 3000+ lines of code in this mess, and fix it up.”
There was a time when I tried to refactor everything into a tiny little package. And I gave up because I was too lazy to redo all of it.
Right now, I’ve abandoned the general use of Game.cs and made a GameManager.cs, quite like the example given by Microsoft (which you can follow here). Mine is somewhat modified, in a couple of things:
- Instead of doing it like the example, where I only handle input on whatever screen remains on top of the stack, I do have a Focus() function where it basically stores that screen in a reference variable. Then, after running Update() on the stack, I just do something like focusedScreen.UpdateInput().
- I don’t have entrance and exit transitions. Yet. If I need them, I might implement them, but it’s not a necessity right now.
- I have functions to Show, Hide and Focus inside the screens themselves.
- Screens can have three states:
- Active: it updates and it draws regularly;
- Invisible: it updates, but it doesn’t draw;
- Inactive: it doesn’t update nor draw, just sits there.
- As a developer, I always have to have access to a loading screen and a debug console. So I always have those two screens available, through the ShowLoading() and ShowConsole() functions.
- Also, as a developer, I have a need to bind commands to the console. I’ve done this the easy way, by creating a method named AddConsoleCommand(string, Action<Command>). The string is the name of the command, and the Action is the function itself. When I want to remove a command, I just do RemoveConsoleCommand(string), the string being the name of the command.
- I dynamically load the required screens depending on Game mode. I can have classes for something like ScreenMultiplayer, ScreenSingleplayer and so on, and using a string, I can dynamically create an instance of the class (this doesn’t mean the game is going to have Single player! Not right now, at least).
- To load the screens inside a specific Game mode, I just do stuff like ScreenMultiplayerUiHUD screenHUD = new (…), and add it to the manager (making sure to remove it from the stack once the game session ends).
- To add or remove a screen to the manager, I just do it like the example (AddScreen() and RemoveScreen()), with a few modifications in the methods themselves, and to acknowledge screen states and possible focus calls.
Now, is this all worth it?
The game is a bit more efficient now, and much better organized. I can easily extend it now, without worrying about how things fit, since the base classes have it all coded for me.
As for performance, it shouldn’t be affected, if not better than before.
How far along am I in this implementation?
Yes, you read that right. It’s still not done yet, and it’ll take a while for me to port everything and test under the right circumstances… but I guess that’s what an alpha is all about, right?
I’m almost done though, just need to port the Weapon and the Team Selection screens, along with a few other functions. The game just freaks out right when Endround is activated, but I’ll work on that. Also, the Bloom component I’m using doesn’t like this new structure, so I’ll be porting it, and that should take about 2 hours.
Tonight I will try and finish everything up, and tomorrow I will try to release v4, along with bug fixes to whatever was discovered in v3. I’m pretty certain that, with all of this rewriting, a lot more bugs will crop up, but those will be fixed as they’re discovered as well, if not faster.
Meanwhile, here’s a screenshot about a lonely boy in a lonely world. Which is just me on dm_arena without a HUD.
So yeah, that’s all for now.