My final project is a breakout game with a twist. In my breakout game, the player controls a half sphere to hit a bar instead of a bar-shaped paddle, which, I think, makes it more fun and challenging.
I have also added three types of power-ups to the game. The player can pick those up after they hit certain bricks. The three types of power-ups are spawning a life-saving long bar below the player paddle, gaining an extra life, spawning extra obstacles on the screen.
The game resets if there is no ball left in the scene. The player wins the game if they knock down all the bricks.
Controls: Use keyboard to play the game. Left arrow key to move the player paddle to the left. Right arrow key to move the player paddle to the right.
I chose to work on a breakout game because it is classic and simple, and the core gameplay has been proven to be fun by players around the world and many successful games. Mostly importantly, it was one of the best ways to showcase the my collision system since the gameplay is mostly based on collision.
Overall, things were under control when I worked on this game project. There were a few times where I needed to modify my physics engine for new features to make my life easier when I implement gameplay. For example, I had to modify my collision callback function to make it include the information of the colliding colliders so that when I could detect if the player ball overlapped with a power-up item. There were two small bugs in my physic engine I noticed when I was working on my game. I was so glad I was able to detect them fast, and they didn't affect my game project and my classmates who used my physics engine in their games.
Other than my physics engine, I also used Yuhan Wu's audio system to add sound effects to my game. Yuhan's audio project was pretty easy to set up and use. I really appreciate the detailed instructions she listed on her web page. I was able to get all the information I needed from her web page. The audio system itself was well-structured and designed. The interfaces were named in a easy to understand way. It also contained a bunch of cool features that I didn't really need for my game, but it was very interesting to play with.
I'm happy with the result. The game pretty much reflected what my physic engine could do, and it was also a relatively fun game to play with.
This semester was full and interesting. I have learned a good amount from this class that will benefit my whole career as a game engineer.
The assignments gradually introduced the ideas of good coding practice, such as platform specific coding, platform independent interfacing, human-readable design, separating assets from the engine code. And I think the core idea behind these practices is to make the engine easy to use for the users.
Platform specific coding and platform independent interfacing allow the engine programmer to hide different implementations for different platforms behind the scene while keeping the code base organized and improving the performance. The user doesn't need to worry about changing platform settings while using the engine since the functions they need to call are declared as platform independent interfaces.
Human-readable design allows engine users to add and modify content to their game in an intuitive way. Having assets files to be human-readable increases the maintainability of game projects. Behind the scene, human-readable files are being converted to binary format to keep good run-time performance. By sacrificing a little bit of build time, we can gain both good run-time performance and good game project maintainability.
Separating assets from the engine code is a good way to keep game projects organized as well as to increase the maintainability of projects. It's a good way to reduce build time by only building the updated part.
Before taking this class, I always consider myself a gameplay programmer. And when we implementing things, I only care about if it works and pretty ignore the performance and maintainability aspects. Now I have realized the importance of designing systems in a user friendly manner. It was very smart the way how we provide user friendly interfaces for the user in our assignments while fixing run-time performance behind the scene.
I used to design things in a "as I go" way, and only add features when I found the need for them. After this semester, I realize it's probably better to spend more time for a flexible design before start coding. Otherwise it may go out of control when you want to add new features to a rigid code base.
Good architecture should be expandable and separate responsibilities for projects and classes. When designing my physics system, I coupled my GameObject class with collision callback, which actually caused problems for my classmates who used my physics system in their project. This was a design mistake I made where I didn't separate the responsibilities between the physics engine and the game object. And when I realized there were some missing features in my physics system, I actually needed to modify the existing code add new features, which was not difficult to do in this case but could actually cause some headache if the engine project was more complex. All these problems I experienced could be avoided with a more expandable and decoupled design.
Overall, I really enjoyed this class and learned a lot from it. From now on, I will apply the techniques I learned from this class when I work on new systems.