Effective talk: Creating a code library
Year of Talk: 2021
Video Link: Growing Your Code Library with Each New Project
While many studios and companies will typically build up their code repositories and game engines. That is an uncommon thing to find in smaller teams, especially in freelancers who are constantly changing the teams that they work with.
This comes down to the fact that as you work on different projects there is a good chance that various commonalities will appear which grouping together allows for a speeder process in other areas of code.
Code Libary:
When talking about code libraries this can be a collection of not only code templates or common scripts but also a collection of notes, documentation, and guides that are often referred to. Having this collection of information and setting a checklist in a common location allows you to more quickly access whatever information you typically use when setting up a new project or what information you seem to reuse or find most critical while programming.
The point of it is to make sure that you can easily access the code and compact. This comes down to the fact that it is meant to be a quick guide for setting up and acquiring vital code that you find yourself constantly using. For example, a base singleton class, or a base enemy class that can be later expanded if necessary.
Maintaining Code Libary:
Don't include things that haven't been generalized for multiple projects, or previous project parts. As it might mean that you spend a bunch of time reworking it to better integrate it into other projects.
Especially don't include any pieces of code or information that you don't own or aren't allowed to use in other areas. This can become a problem later if a company finds out and starts a lawsuit.
When to add to the Code Libary:
The two primary points are before starting to code a project and shortly after finishing
This is because when starting a project you can determine what parts of the project you hadn't realized might be useful to reuse for future projects. Meanwhile adding the code after the end of a project allows you to analyze the code more abstractly and understand what areas you would find useful to reuse.
But it is important that when doing so not only does the code get abstracted to a certain level so it is easier to use. It is even more important that when doing so there aren't any details that would point towards any previous projects that you worked on. This is because you don't want to risk previous companies causing problems if they find their code being reused without their permission. You can then place it in an appropriate folder/file where you can easily access it or search for it if necessary.
It is important to store the library in an easily accessible area for you as it contains things that you would likely be constantly accessing and using for different projects. Try to also organize it based on general topics. Examples are animation, saving systems, asset creation, and so on.
Examples:
The rest of the presentation is based on various examples given by the presenter on how they used their code library.
Sound Effect Controller:
The controller contained a list of audio clips, basic control of volume and pitch, and various sound effects when needed. It also was contained as a singleton allowing for easy access by other scripts and can be used almost as a plug and play.
This was later generalized by allowing audio clips to randomly be played and used from a list of given audio clips. Similarly, the audio play was simplified so that it would be easier to call a single method to play any given audio source and affect any important information in the method parameters.
Dialogue System:
Initially started with an already generalized script that worked for a simple dialogue system with speech bubbles. However, being able to improve on it by allowing different types of dialogue systems will allow it to be more versatile and be used more broadly in different projects. This can be done by having a boolean or int value that allows you to use either option while allowing for easy customization for how close or far away the dialogue appears on the screen or in other areas.
At the same time, you can generalize it by creating a simply advancing dialogue system that grabs the next line and animation from arrays to then pass to the designated character. This way you would need to place the appropriate amount of lines with their respective animations and designate which characters say the lines.
Another important factor for the generalization of a dialogue system is having it expect a position. By doing so it means that any new dialogue can quickly change the location it spawns from. Something that can be very useful when changing projects that might want the dialogue to appear on the screen or top of the characters as they move around.
Adding a prerequisite option would be useful as many times certain lines shouldn't appear if it doesn't make sense for the story or the current mood of the scene. This can be done by either disabling certain dialogue after a mission is complete or unlocking other dialogue options after another mission or event has happened.
Extending from a generic script:
Something commonplace is having a generic NPC or player script and wanting to expand it for a specific game or add variant options. The best solution would be having various virtual methods as they allow themselves to be overridden in child classes. Which can allow for extra features to be packed into them or to have things changed. At the same time, there isn't an expectation that they get overridden which means that if a feature is already where it's needed then there isn't any need to override the methods in the child class.
Some examples Virtual methods that were given that can be commonly needed for an enemy controller include; OnSpawn, Attack, TakeDamage, OnDie, SeeObject, and Movement (2D and 3D).
This can be extended to things like the following: UIPopup, OnDialogueEnd, PlayAudio, and others.
Some examples given from the presentation:
Shielded Enemy:
Override:
Setup, Update, TakeDamage
New Tag:
Shielded
New Virtual Methods:
TakeShieldDamage
OnShieldDeath
Boss Enemy:
Overrides (Overrides Shielded Enemy):
ChooseNextBehavior, Attack, TakeDamage, OnDie
New Tag:
Boss
Toxic Enemy:
Overrides:
Awake, Update, Attack
New Tag:
Toxic
The previously mentioned enemy examples were some ways that a generic enemy script could be extended to allow for a wide variety of enemies. The presenter was able to give a lot more options on how it can look/be done.
By doing many of these techniques to reuse code it means that a lot of future projects will become faster. It also allows for quicker prototyping in the early stages as a lot of the basic code would already be done. Allowing you to spend a lot more time just testing out unique game mechanics and making the game better instead of fiddling with a lot of the basic work that can take time and motivation away from the project. It also allows for a more comfortable working in a game engine environment as you don't need to spend as much time remembering what settings to change or trying to remember how to get a certain basic task to work.
It also means that projects arrive in a playable state quicker than normal as you can bring together many of these common features that would otherwise take multiple weeks to a few months to complete. Allowing you to share the project with others to try it out sooner and allow for smoother progress.
Another feature is that when working on adding pieces of code to the library you can include more stuff that you might not normally have time to include but are extremely useful to do so. An example would be accessibility as having the code library allows you to preemptively include some basic features like Control remapping or a high contrast mode. These are things that are super useful to have from the start but might not normally be included or thought on until later down in the project making them harder to implement.
Comments