SECRET
DigiMastered Works LLC
Office of Development
DMW107IB7008
Date 02/22/2022 08:48 PM
To: The People
From: Tanner Fry
Subject: Lighting the Path
Complex Lighting With Normal Maps
In our last article we talked about adding "Dynamic Shadows" for clouds. Today we will talk about dynamic lights and how the implementation works. With Unity, lighting and shading from lights can be introduced in many different ways but how we created it within a 2D space was through normal maps. Normal mapping is a texture mapping technique used for faking the lighting of bumps and dents and is an implementation of bump mapping. Many developers use normal mapping to add details without having to use more polygons for a given model. This increases detail without the performance hit from the extra polygons.
In Unity, we create normal maps for our 2D sprites so that lights in-game add more detail and shading to our sprites. Looking below, you will see an example of how normal mapping helps add detail. We have two buildings and two cubes. The left building and cube don't have a normal map applied, while the right versions do. Note that the right-hand side cube better reflects more clearly how normal maps work since it doesn't use any normal map blending. Whereas the right-hand side building does use normal map blending for even more detail:
Lighting and Normal Maps
Headquarters Building
Headquarters Building as a Normal Map
Key locations to look at in the above video are the center corners of the building and the faces of the cube. You will be able to see the shading added to the sprites depending on the light.
If you're still wanting more information on normal maps, check out this resource on Unity's website here. If you'd like to learn more about normal maps with pixel art, check out Adam C Younis on YouTube. He has a great video on it.
Database Saving
It's crucial to mitigate data loss. Players never want to go hours on end through a level, campaign mission, or game mode just to lose their progress from a crash. Some games need to save the state of their game at a particular time. Others don't. AIA definitely does. So I've implemented basic game state saving.
How it works: Basically, every 5 seconds my save manager takes every agent that is created and updates their information in the database. This required some reworking of the update functions for agent information in the database but it wasn't too bad. All I have to do is pass an agent's object to my database manager's update function and it will handle grabbing the information needed from the agent. After grabbing the data, the database manager will update the correct row in the agents table within the database. You can see the current implementation below:
public async void SaveGame() {
await System.Threading.Tasks.Task.Delay(saveInterval * 1000);
if (CharacterManager.Instance != null) {
if (CharacterManager.Instance.allAgents.Count > 0) {
foreach(GameObject agent in CharacterManager.Instance.allAgents) {
DatabaseManager.Instance.databaseTableAgents.UpdateAgentInAgentsTable(
agent.GetComponent<CharacterAgent>());
}
}
}
// Keep looping every saveInterval seconds.
SaveGame();
}
Here's a look at our UpdateAgentInAgentsTable() method:
public void UpdateAgentInAgentsTable(CharacterAgent characterAgent) {
using (databaseManager.dbConnection = new SqliteConnection(databaseManager.connection)) {
databaseManager.dbConnection.Open();
databaseManager.dbCommand = databaseManager.dbConnection.CreateCommand();
databaseManager.sqlQuery = "UPDATE AgentsTable SET name = \""
+ characterAgent.agentName + "\", "
+ "rank = \"" + characterAgent.agentRank + "\", "
+ "age = " + characterAgent.agentAge + ", "
+ "location = \"" + characterAgent.agentLocationName + "\", "
+ "operation = \"" + characterAgent.agentOperationName + "\", "
+ "health = " + characterAgent.agentHealth + ", "
+ "fatigue = " + characterAgent.agentFatigue + ", "
+ "loyalty = " + characterAgent.agentLoyalty + ", "
+ "exp = " + characterAgent.agentExperience + ", "
+ "skill_espionage = " + characterAgent.agentSkillEspionage + ", "
+ "skill_cqc = " + characterAgent.agentSkillCQC + ", "
+ "skill_secrecy = " + characterAgent.agentSkillSecrecy + ", "
+ "skill_gathering = " + characterAgent.agentSkillGathering + ", "
+ "skill_decrypt = " + characterAgent.agentSkillDecrypt + ", "
+ "skill_encrypt = " + characterAgent.agentSkillEncrypt + ", "
+ "pos_x = " + characterAgent.agentX + ", "
+ "pos_y = " + characterAgent.agentY + " "
+ "WHERE "
+ "id = " + characterAgent.agentID + ";";
databaseManager.dbCommand.CommandText = databaseManager.sqlQuery;
databaseManager.dbCommand.ExecuteScalar();
databaseManager.dbConnection.Close();
}
}
Pretty simple. We grab all the agents, take each one and update the information in the database with the in-game values. The database is our backup. We don't work with any values from the database unless we're loading the scene. When loading the scene, we grab the values needed from the database.
The next steps are to implement saving location data, music tracks and the specific time a track is at, player information, and built objects. Location saving is more about the data for a given location whereas saving built objects is for anything else built, such as roads and other infrastructure that may be implemented in the future.
I'm still debating on the semantics of using "buildings" or "locations" because a location can be a building but also a specific area that the agent can "enter" to gain benefits. I'd like for the Director, you, to be able to create locations that would enhance stationed agents at that location which is why I'm having this dilemma.
Agent Location Extraction
Location extraction might sound cool, but it's just a location realizing that an agent has left it. In other terms, agents can now leave buildings. This also reflects in the database in real time.
Agent Moving Into and Out of a Location
Launching the Game
No I'm not talking about launch dates or of the sort. I'm talking about when someone physically launches the game to play it. A few days at the beginning of this month, February, I started working on the sequence of what happens when the game launches. You experience them every time you play a game. Sometimes they show information about the companies and developers who created the game. Other times, there's no launch at all.
Call of Duty and many other AAA games like to add backstory videos that only play if you've freshly installed the game while also having a generic version for if the game has already been successfully launched. In AIA we're developing something of the sorts. A few animations and videos to help the player get a better understanding of the game. Some backstory and grease to keep the gears spinning.
I don't want to give away anything but to those out there developing their own games, the launch sequence is very important. It's the second thing someone experiences when playing your game (the first being your game's icon when starting it up). So take good care of the process and give it the attention it deserves. A game isn't just about the mechanics, the art, or it's sounds. Although important, it's also about the care and attention to detail put into every aspect of your game. Sure, you have an ideal deadline and not everything can be pushed into high quality development, but, at least give a majority of the components some well thought out analysis.
We're working on some exciting enhancements which will hopefully be ready by next months article so keep an eye out. Thanks for tuning in and if you have any suggestions on certain topics that you'd like to know more about, then head on over to our forums and let us know. You can also email our support at Support@digimasteredworks.com.
Roadmap
Milestones To Do:
Milestones Completed:
SECRET
Approved for release: 02/18/22 ID: IB7008
1