Flying Simulator
Up and Down
Side to Side
Roll
Flying Simulator is a … flying simulator.
But wait! You can fly around and collect cubes! The idea behind Flying Simulator is that it is a simplistic game where you can fly wherever you want and collect cubes that play some simple tones. All the while some relaxing music and wind sounds play in the background. The game is meant to be a low stress game where you just fly around. One of the primary reasons I chose to do a flying simulator was that I wanted to make a game that utilized my terrain generator tool pretty well. And flying over multiple terrains happens to fit very well!
Controls :
Ascend and Descend: W and S
Turn Left and Right: A and D
Spin Plane Counterclockwise and Clockwise: Left Arrow Key and Right Arrow Key
Boost: Spacebar
Escape: Quit Game
Systems
Terrain Generation System (https://www.kentphan.com/kpterrain-generator-system):
Utilizing the terrain generator system I made, I generated multiple terrains that the player can fly over.
If I were to address the current interface of my terrain generator system. I feel that it met the basic requirements of quickly generating terrain. However I realize the system comes with a small issue or lack of feature.
The issue I quickly realized my system had was that the units in which I set in my Lua files for properties such as Width, Height, and other size based scalars don’t match the unit sizes I set for game object positions during run-time for some reason. If I wanted two pieces of terrain to line up when a terrain was 100 x 100 sized in dimension, I couldn’t just offset my game objects by units of 50 to get them to line up during run-time. I theorize that there are some conversion issues with floating points when writing to binary and reading from binary. That being said I would have to resolve this by having some conversion properties set,read or processed during run-time.
Srija Kambhampati’s Sound System (https://thedarkmiko.itch.io/audio-engine-system),
Using Srija’s sound system, I played various background tones and ding tones for when the player hits cubes.
I had some bugs I ran into when initially using this system, but they later got resolved in updates. For the most part I didn’t have issues using this system, I only wish I could set some property fields for things like volume or something.
Pluto She’s Collision System (http://www.plutoshe.com/blog/project1_writeup),
Using Pluto’s Collision System, I detected collisions between the player and cubes that they could collect. Collecting cubes would result in a sound and a movement of the cube.
I ran into a bug involving the copy constructor of the CollisionLists not properly copying everything, but Pluto helped me resolve this.
For the most part the system worked in letting me detect collisions between the player and the cubes. I only wish that I could tie collision events to call back events or something to stray away from checking multiple boolean conditions between game objects.
Game Objects:
When it came to using the game object interface I created, I didn’t really have issues per say, I more lacked features that I needed to implement or rework.
Game Object Parenting:
One big lacking feature that resulted in me cutting a feature, was the lack of game object parenting. I ran into a moment where I wanted to rotate the model separate from the camera, and I wanted the camera to not rotate with the plane, but still follow the main transform. Not having some form of Game Object parenting structure made this fairly more complicated to implement.
Not also that implementing Game Object parenting in my engine would quickly complicate multiple levels code complexity whether that be in game objects or outside of game objects. I would have to worry about submitting game objects within game objects, and also ensure that memory clean up would be handled correctly.
Looking Back
Looking at most of the interfaces I designed within the engine, I don’t have any obvious regrets on how I designed most aspects. I more saw additional things I could implement to either add additional functionality, or simplify functionality.
Such an example of going further and simplifying functionality would be to wrap game objects in some kind of managed structured managed by an instance. Doing so would allow me to delegate redundant tasks to the manger that would simplify the needs from the perspective of a game-play programmer. Things such as object clean up, parenting transforms, and especially submitting objects to the graphics card. A game-play developer shouldn’t have to worry about submitting objects to the graphics card, and should more worry about game logic that creates and destroys game objects.
I would also like to adopt some form of component based system to attach functions to game-objects versus creating a one game-object does all type of structure. This would give user flexibility to reusing functions, and would give the engine the opportunity to optimize component specific logic whether that be caching or saving space. This is commonly used in most public game engines nowadays.
Working with the code of my classmates to implement core systems (Sound and Collision) for the most part was easy despite the small amount of bugs I ran into that required fixes. If I were take one thing away from this however, I feel like integrating core systems like Sound and Collision require some engine integration if I want to optimize the systems within the engine, as well as make it fit with the overall structure and design of the engine.
For example, if my engine uses a component based structure, and a game-play programmer wants to add sound to their game. That requires a Sound Component, which would require me to perform some extra work in integrating a sound library into the engine.
I can see that there is possibly a cost benefit scenario here. If I take an exterior library and try to mostly utilize it by the tips (what its interface provides me). I possibly simplify it’s existence in my engine at the cost of possible performance optimizations. Whereas I take the library and try to directly integrate it into underlying logic, I can get some performance gains, but at the same time I’m hiding functions from the game-play programmer that could lead to additional complexity.
Overall Learning Experience
The Goal Of Designing All These Systems:
If I were summarize the overall goal of working on all of these systems and design interfaces, it would be this: Thinking ahead to design and structure things in a manner that will save a lot of time in the long run. And this includes many aspects such as designing something to save another person time from understanding something. Designing something that can easily be swapped to adapt to different platforms. And designing something so that it can either be optimized or lead to less buggy code.
Build Dependencies And Project Structure:
On a previous engine project I worked on, I didn’t adopt a library based building structure, I more or less cross referenced everything between projects. This resulted in long build times that eventually slowed down the development process. One proud thing I will take from working on this project is the management of property files to handle redundant build configurations, and the building of libraries and utilization of dependencies with those libraries to avoid redundant building. This in a way also isolates logic between libraries and projects to make it easier to scope everything in mind.
Binary Based Files
I never really understood the reason in which Unreal Engine utilizes a lot of binary files instead of human readable files until now. I realize that there is a huge performance gain in serializing all of your data within binary files. But of course this comes at the cost of human readability. This can also be seen in the Unity Engine where if you serialize all files to be human readable, you get the trade-off of load times when utilizing the engine.
Architecture:
I am the type of person that likes to spend extra time in the initial stages of a project to design something flexible and robust in the beginning. I like to try my best to minimize redundant work that I will have to do later in the project due to unexpected scenarios. But of course, there is a balance in this. There is a reason that Waterfall isn’t a popular practice in a lot of the tech industry. It’s just unreasonable to expect that you can foresee every possible case at the beginning of a project sometimes. The best we can do is try to look ahead as far as possible, design around that, and then iterate against the things that we did not foresee. The cost of not foreseeing things ahead of time can result in total re designs or inefficient use of time. As all things, there is a balance.
Good Software Architecture in my mind, is that you have designed while considering the probability of iteration or usage of something.
If I am working on some performance heavy logic like quaternion math, I can expect that such logic won’t be iterated on that much, and so I can make the trade-off of readability for performance by spreading math operations and minimizing redundant operations.
If I am working on say a Sound System for Windows, I can make the assumption that future platforms may be OS dependent, and so I design my architecture to make this easy to swap out.
If I am designing a function to create a GameObject, I want to ensure that the parameters for that function make a lot of sense to an exterior user, because I can expect this function to be used a lot.
Bad Software Architecture in my mind , is when we fail to account for how something might be iterated upon or used.
Bad naming schemes that don’t reflect the underlying function of something very well. SoundSource versus Sound, etc.
I integrated OpenGL specific logic so deeply into my engine, that adding on support for Direct3D would require a full engine rework.
At the end of the day, good architecture is subjective, the best we can do is make it easily usable or modifiable to the most people that come after us.
Credits
Models:
All models were made by myself using Maya
Sounds:
Ding: https://freesound.org/people/InspectorJ/sounds/484344/
Song: No Name Song By Dayna Ambrosio https://www.daynaambrosio.com/
Systems:
Collision: Pluto She
Sound: Srija Kambhampati