The most difficult building to program in Stranded is this:
Players can concoct various drinks at a bar, such as Fruit Juice or Alcohol, once you unlocked their recipes. NPCs can then come to the bar, sit down and consume them.
One day, players suggested that it would be good if you can change the recipe of the bar without having to dismantle and rebuild the bar, as recipe selection for choosing what you want the bar to concoct is done during construction.
Sounds easy doesn’t it? Just add a reset button!
The Reset Button
So I coded it and it works…98% of the time.
When you hit the reset button, the player is now prompted to re-select a new recipe. It works, so what’s wrong?
Well here’s the thing I just found out.
If you open a bar to make Fruit Juice, NPCs sit in the bar and take about 5 seconds to finish drinking it. Yes, there is a delay. In the process, they gain ‘Thirst’ gradually over those 5 seconds.
However, if in those 5 seconds, you decided to change the recipe while they were drinking, to ‘Alcohol’, which provides ‘Happiness’ instead of ‘Thirst’, then would the NPCs suddenly switch?
Well, no problem I just set the coroutine to specify the drinkType at the start of the interaction. That way if they started with juice, they’d continue to drink juice even if the bar now produces Alcohol.
But wait, what if the player decides that before those 5 seconds are up, he decides to PAUSE the game, and hit SAVE. Then exit the game.
The game has to be persistent, thankfully I already save all building states and recipes to a savefile, as well as a full list of NPCs who happen to be interacting or using each building. And yes I also save their ‘drink progress’, so if an NPC had 2 seconds out of 5 seconds of drinking done, they’d reload and only gain a remaining of 3 seconds worth of stats. That took some work but at least I got it. Haha, how smart, I thought. Then as I read my code, I realise something.
When the player reloads the game, the game initializes the buildings’ recipes, and guess what? All the NPCs at that bar are now drinking alcohol even though they started with Fruit Juice! And they are now gaining ‘happiness’ instead of ‘thirst’, even though they consumed the Juice items.
So what I’d have to do now is to create a new save variable for every character to store what drink they are drinking so that if the recipe changes, they still remember what they are drinking after quitting and reloading.
This is getting to become a lot of work.
But that’s not difficult because this is do-able and isn’t what makes the bar difficult. Here’s where I almost had a meltdown.
Stranded was coded to have buildings be interacted with in only one way. See, some buildings in Stranded can be ‘interacted’ with to either produce resources or consume resources.
Example of Production buildings:
There is a Water Pump. You pump water. You get water, done.
There is a Cookhouse. You cook food. You get Food, done.
Example of Consumption buildings:
There is a Water Tank. You drink from it, you gain Thirst, done.
There is a Dining Table. You eat on it, you fulfill Hunger, done.
Then…there is the Bar. You make juices. You get juices. done? No wait. The bar is BOTH a production building and a consumption building. You also have NPCs consuming juices at the bar!
For a long while in Stranded, I made NPCs take juices from the bar, and go to a separate facility to consume the drink. But the logic always bothered me because then settlers could collect a drink and then have to travel across the map to a ‘Dining Table’ to consume the measely drink.
I had a long think about whether to begin the daunting task of refactoring the code to allow the Bar to execute both and eventually attempted it. I don’t regret it but darn, it was very annoying. See the thing about interaction is there is a list of Characters to store so buildings have a reference to who is currently using it.
That character list exists for every building and cannot be shared. If you assign a settler to produce, it goes to that building and it must know that it was set to ‘Produce’ role instead of ‘Consume’ role.
Call it a stupid implementation but I set up interaction to be versatile enough that each building would default to execute a certain code depending on whether I set it to be ‘Production’ or ‘Consumption’, so there was no way to merge the code as buildings were either one or the other. A settler would go to a building knowing its role but the building would handle the interaction. Combining the list would result in something like a character going to the Bar to drink, and end up bartending instead of drinking, and the second character who was going to go there, realise that the ‘Bartender’ slot is taken up, thus assigns himself to drink instead! But because of the failsafe I added that he only accepts the ‘Bartender’ role, he won’t drink but he ends up defaulting to wandering around looking for another Bar. So while some parts may appear to not break the game, a lot of hell will break lose. And hence the game is actually breaking silently and running quite inefficiently.
Beginning to rewrite my code
I began to refactor the block of code containing building interactions, separating the logic into ‘interact’ and ‘work’. Working for production, Interacting for consumption.
I had double the amount of code and functions. But things got really messy when I began getting involved with the UI bits. I had to complicate the saving code, the UI code, the character code.
Every time I refactored one function, I had two other functions invoked by it that needed refactoring. Soon it was just a never-ending growing list of functions that needed to be refactored.
The 90/10 Solution
After about a full night of work, I decided to discontinue the fixes.
Yes, it was only one night, but I could see this taking up a lot of time and this was an experiment. Every feature I add to the game is an experiment. If it’s something great, I keep on it and if it’s not, I have to resist falling in love with something unworkable and trash it. In this case, I had deemed it unworthy to continue on this.
For every problem we face, there is something called the “90/10 solution”.
A solution where you spend 10% of the effort to achieve 90% of the result.
I decided that refactoring a whole manager class was not ideal to support just ONE measly building. So what I did was just to make the bar ‘automated’. So the bar produces drinks by itself! It does not hurt the gameplay that much, and I can balance around that quite easily.
I kept the reset recipe button.
I added the ability to go drinking at bars.
I was considering to take out bartending, but since the solution works 98% of the time, I think I am leaving it as an experimental feature for now. It’s cool and I can always take it out in future if it is too troubling! I know 98% is not 100%, but hey this is a prototype after all and I have room for experimentation.
Problem solved! And now I can spend all this extra time working on stuff that actually matters.
The thing about games is there is a lot of things running in parallel. Unlike say developing an app, where things may somewhat run linearly, in Stranded your character may be running about, taking resources out from a building, moving the building while NPCs are trying to reach it, or taking resources from a building that NPCs are interacting with. All while in the background, animations are playing, the weather is changing, the lighting is dimming as rain falls, and the rain then waters the farms, which causes their production to increase, etc. And then realise all this code has to also be somewhat duplicated to work in multiplayer.
There’s like a bunch of different system managers I have in my code, sometimes I wonder if I am programming them as efficiently as I should. Every new mechanic that I add that requires its own gameplay manager has to work with every single previous manager and not cause bugs in the other systems. If it’s an independent system that is easy, but if it’s something that depends or links with other managers, it gets tricky.
A player (PlayerManager) in a multiplayer room (MultiplayerManager) presses the arrow keys (InputManager) to build something (BuildingManager). This updates the walkable areas for the AI (NavMeshManager) and takes resources (InventoryManager) to put into the settlement (ResourceManager), to advance his technology (ResearchManager), where he can assign (JobManager) settler NPCs (CharacterManager) to work while looking out for potential new settlers arriving by sea (BoatManager) to exchange items with (TradeManager). When that happens, there is a notification (NotificationManager) and since this is his first time trading, there is a brief tutorial (TutorialManager), but it can be disabled through settings (SettingsManager). And when it rains (WeatherManager), it plays sounds (AudioManager) and maybe cause some story events (StoryManager)… Okay imma stop.
Well, welcome to game development. That’s all for now. Until next time!
In a game set in the ocean, water plays a huge part in the graphics as it is what you see a lot.
Unfortunately, ocean water is a tricky thing to replicate in games for a few reasons.
Its surface needs to not look flat
It is transparent
It needs to have reflections and ideally glimmer in sunlight
It can refract objects underwater
The deeper you see into the water, the more ‘foggy’ it appears. (Shallow water and deep water display differently)
It needs to be easy for the GPU to render, as this is a game and while important, water should not be heavy to process on the device.
I played around with different shaders I found online.
My favourite part about this water is it has foam around the intersections where objects touch the water. It’s a really sweet effect but without any surface detail, it looks really bland. Even if I add a texture, it’s still evenly flat throughout.
It is a standard shader, but with a few tricks. To create a believable effect, I used two normal maps animated in different directions, perpendicular to each other (e.g. one normal map scrolls northeast, the other northwest). Not only does having two layers of normal maps overlapping making it look really cool, but what the perpendicular angles does is it makes it look like it’s really flowy. In my opinion, this is a great balance of visuals with performance.
The only catch is that I could not get reflections to work as intended.
Screen-space reflections was used above. It has too many artifacts and gets dark when approaching the horizon, which is not supposed to be the case. As for planar reflections, it is restricted to Unity’s HDRP, a different render pipeline in the engine that I use and an existing solution requires a custom shader which does not have the overlapping normal map support.
Look at those reflections! This one has dual layered normal maps, but the intensity of the surface bumps cannot be varied. Nonetheless, the reflections look really pretty at night when the city lights up.
These reflections are not screen space, therefore you can actually see the underneath of things that aren’t visible to the camera. What it does is there is a second camera that captures the objects in the world and projects it as reflection. It sounds intensive and it does indeed almost double the processing time requires because it has to draw everything twice. Which is why the resolution of the reflections is capped at 256 by default. I don’t need the reflections to be super crisp and sharp or detailed. This makes it a lot more manageable to calculate reflections.
A different mode of the water above allows it to not only be translucent, but also refract things underneath it. This is really cool, and I submerged my city even more in the above screenshot to really see the effect. It’s really cool as I can use it to illustrate shallow and deep water with a few more tricks, but out of all the water shaders, this is the most EXPENSIVE for the device to render because the water now has to calculate how to refract things underneath it.
But what if I could push graphical fidelity to the highest? What would be the best looking water?
The best looking water of all! No trickery with normal or height maps but actual waves being simulated! There is a foam, refraction, and you can even dive underwater! There is underwater ‘fog’, and even caustics (refraction of light rays causing the rainbow colours on the sand!)
This is truly amazing but I’m holding off implementing this in my game for now. The above was made possible with Crest, an ocean plugin that I sourced from Github.
Ultimately, I used both water 2a and 3a in my game. I offer a high quality toggle mode that allows people to turn off the advanced water effects of 3a, and use water 2a instead. By default, mobile devices will use 2a, and desktops use 3a.
Wait did I just mention mobile?
Yes I did a test of this game and it runs on my android device!
Experimental Mobile Build
I wanted to be able to play my game and show it off while on the move, so I built a mobile version of my game!
It actually looked better than I expected, but because it was a very quick test, it is not optimized and will drain quite some battery.
Mobile is still experimental, so it is still being tried out as a low priority. I had to adapt the controls for mobile from arrow keys to click to move. I don’t want a keypad or joystick yet as I think it takes up a lot of screen space.
While playing with materials, I ended up accidentally making what looks like a winter DLC for my game!
In here, I am trying out performance improvements if I were to switch to using a technique called Color Atlasing where I can use a single material shared between different 3d models. This greatly reduces the work the GPU needs to do to draw multiple objects on screen, as it allows the engine to ‘batch’ render.
Batching reduces the work needed by your computer, similar to how you only need to make one phone call to order 10 foods from your supermarket.
Without batching, it may be like having to make 10 phone calls to order food from 10 different supermarkets. It is much more work to do and time consuming. Batching them means if certain conditions are met, you only need to issue a single set of instructions to execute multiple tasks.
It is not automatic and my 3D assets have to be created in a way that allows the engine to perform optimization.
The above was a test to see what difference it makes, so I can evaluate the ratio of the effort required to work on it versus the outcomes of this optimization technique as compared to other methods.
I made a dance animation using my game assets to celebrate Mother’s Day, which occured last Saturday on 8 May 2021. Above is the video.
My mother was listening to this song on repeat some time ago so I made this for her using my game’s assets. Happy Mother’s Day to all mothers!
Dance Choreography Design
I used to take dance classes, and I really enjoyed Dance as it was a way to express myself without having to use words. It also is a fun way to exercise and keep fit. I never would’ve expected that it would come in useful in my career as a game developer. Well not exactly related to games, but still.
It was really fun to ‘design’ this dance and you can see above that the dance has ‘layers’, which are animated with offsets. I learned about layers from my dance classes, and I integrated it here.
My favourite bit was actually syncing the camera angles to the music beats near the middle of the video.
The great thing about designing a digital choreography is you can keep going back to it and finetune the dance until it is perfectly how you envision it, and if the animation or timing doesn’t look right or feel great, you can very easily tweak it. You can duplicate more dancers, remove dancers just with a few clicks, it’s just insane. You can get the perfect timing, perfect moves and even their positions because everything is virtual and you just replay and replay until it matches your vision.
It is really surreal when you’re moving the dancers with a flick of your mouse, and making them dance faster just by changing an ‘animation speed’ property, and easily shift the camera angles virtually to get the perfect composition.
I built this cinematic using the Unity game engine, sequencing it together with Timeline, and using Cinemamachine to design the composition, the camera angles and shots.
The animations were obtained from Mixamo and its animation data was imported into the game engine as clips I could splice together in Timeline.
The entire animation is real-time rendered.
Total production time: 2 hours
I didn’t count exactly, but I started work on the night before Mother’s Day after I ended work that night and had my dinner, which was around 9pm, and I was done by 11pm. I had to keep my headphones on while working with the music and pacing as this video was meant to be a surprise. I managed to trick my mother into thinking that I was asking her for feedback on an animation instead of a Mother’s Day video, which was really funny.
Of course, the reality is that making animations is a lot of work and usually takes days and not hours. I am only able to build it fast because I’m experienced and am familiar with my workflow, and with help to the tools within the game engine that make this possible:
Using Game Engines to create 3D animations & Cinematics
A lot of people have a misconception that game engines can only create games. And most people don’t use game engines to create 3D animations or cinematic content. That second part is true, but only because I think many people are still more used to the traditional technique of using Maya or Blender, as game engines were not built for this purposes until recently a few years ago. Additionally, it is rare to find the skillset for doing this in game engines, as it is currently quite niche from what I hear.
I however, have found several advantages to using a game engine for creating cinematic content.
The great thing about a game engine is since my game is already built with the game engine, I can just use it to also create animations without having to export the assets into another tool.
I can very easily create animations without going into Maya or another DCC. I also iterate extremely quickly because I am very familiar with game production tools and I have a separate set of scripts to assist in creating cinematics rapidly. And of course, the best thing about a game engine is it uses real-time rendering, so lighting is not just easily adjustable, but what you see in the viewport is the final lighting and effects which do not require compositing.
In terms of workflow, I find myself many times more productive and able to make many more creative decisions in a short time span. While it may seem like the quality isn’t directly ‘better’ than traditional techniques, the hidden costs saved is in how much more quality you get from having greater creative freedom and time expenditure wise, it is much better.
The entire video is a direct output recorded from Unity, including even the music and any sound effects, so the final render does not even have to go through Premiere or After Effects. I just hit render and upload it online. Amazing isn’t it?
In Part 1, I talked about coming up with a concept and creating a demo prototype in 3 days to test the idea.
After creating the demo prototype, I wanted to program the game systems properly moving forward.
The first system is a BuildingManager script, as buildings are core to the game.
A manager in programming is similar to a manager in real life – it manages a group of people objects in the game, and I can retrieve information like how many buildings are on the map in total, how many of them are houses, etc.
This is important as it will be where I write the code to determine the construction logic. For example, to construct a building, I need to do 3 checks:
Do I have enough resources to build this thing?
Is there a wooden deck underneath to build this on? (Cannot build on water)
Is this grid occupied by something else? (Check for overlaps)
Aside from that, I need to create for myself a way to store building properties. I created ScriptableObjects which store data for each building, and these values are all easily adjustable in one place.
Things like what is its name, its description, its cost, what resource it consumes and produces, are all stored in one convenient place, and can be adjusted on the fly.
I had modelled different buildings and to save time, created a scene with all buildings in it.
To capture the icons, I use a 1:1 aspect ratio and scale them to fit the screen.
One of the cool scripts I wrote in a previous project is an automated way to capture 2D icons of 3D objects, and output them with a pre-determined file name, so that if the 3d model is updated, I just need to run the script to update the 2D icons. Cool isn’t it?
I am working alone, and don’t have a UI artist or a concept artist to work with to handle the 2D elements, so I have to think of ways I can reduce my workload in those areas and work smart.
To make a plan of what kind of buildings I want to design, I sketched out a pretty looking game flow.
One of the issues I struggle with is how to blend RTS and RPG together.
In an RTS, the camera is of a third person view and usually very far away, to give players an overview of their base, and the ability to freely move the camera and click on any object on screen.
But in an RPG, the camera is usually up close to give you a more intimate feeling.
While the game now has a player character to control and follow, this was not the initial plan. Initially, I wanted this to be more of an RTS. You don’t take control of a character – you’re more like god building up a town.
But one of the conscious choices I made early on in the development, after consulting with a friend, is to give the player a a playable character that they control. Rather than using the arrow keys to move the camera, the arrows keys will move an avatar, and this player character is how they interact with the world.
It is a dramatic change.
But I think it is better this way as it adds a level of immersion into the world. You’re not just a god manipulating the world, you’re an actual person living in it, and you now make choices through this character, that will influence the world and people around you. I think that with a character, the game will flow much better, and you as a player can immerse yourself into the world of Stranded.
Not to mention, if the game has a story, it would be better experienced by a character.
Lastly, I am going for a game with very relaxing vibes. Here is a slide I wrote in my deck about my vision for this game. I think if the game were to have activities to engage in, or even quests to talk to people, which is a very RPG thing, then having a player character is beneficial.
Speaking of which, I wrote a story draft.
Currently, you are able to build a pier in the game.
When you build it, the game will show a short 3 second cutscene, and the camera’s aspect ratio changes to a cinematic one. The cutscene is only triggered by the player’s action. It is made seamless and flows naturally in the world to not take away too much control from the player or disrupt them.
I believe this is an improvement to storytelling from my previous games. All cutscenes should ideally be a result of player’s actions, and will trigger an event to happen. It should also be clear what is going on. In the above case, a boat with a survivor appears.
It should also not have distracting elements. Thus I hide the UI in cinematic mode and the black bars coming in is an indication to the player that ‘hey! this is a cutscene, you don’t have to click anything, just watch what happens’.
You can then go closer to Alf and click on him to talk to him. You are then presented with a Dialog.
I scripted a dialog system similar to the one I wrote for Enchanted Heroes. It allows me to create multiple player choices, which will be very interesting down the line, and allow different choices made to have different consequences in the world. My dialog script is also dynamic enough to do some really cool story events.
I personally love having mystery in the game, and I love science-fiction, so thinking of those elements made me really excited to develop the world and story.
One improvement I made over Enchanted Heroes is using TextMeshPro for my project, which unlocks better ways to display my text and include sprites within dialogs as well to better make fancier text and provide clarity. This being a resource management game, saying 20 Wood is rather long, but saying 20 <icon of wood> is a much faster way to read the information.
The sentence at the top is not only shorter but you can clearly read the resources you require by opening your inventory as the inventory displays all your item icons.
Something exciting is happening. I am very excited to present a new game I will be working on!
Six weeks ago, on March 13 2021, I have officially started on a new game project, called Stranded. Below, you will see a demo video of the prototype I made in 3 days to showcase the concept.
In this post, I want to talk about what this game will be about, and how I arrived at its concept. As well as share my inspiration.
What is Stranded?
It is a strategy survival game I will be working on during my leisure time.
I love serene peaceful vibes and the idea of being stuck on an island in the middle of nowhere has come up a lot in my 3D art and drawings.
However, I never thought about making a game around this theme. Until one night at 3am, my sleep deprived brain got a little crazy, and I wrote this.
I had a simple composition of a stack of houses, with people on what appears to be a floating pier, and had a strange idea to make this into an actual game.
It was a rapid prototype – the people are just a sphere and capsule and they jump around with no animation.
However, I added music, a calm relaxing ambience and that immediately set the mood. Instantly, I imagined myself not reveling at a loud party but relaxing by myself on a floating pier in the ocean. At 3am, I was all by myself and my feelings peaked. Off topic, I feel like this would be a game that attracts Introverts lol. Just kidding though.
The above 3D environment was made years ago, in 2018, as part of Project Grey, a side project serving as a test to create procedural houses. It was honestly just a fun thing that never really took shape as I was never serious about it. That and even when I got the idea in July 2020, making a game is a lot of hard work and investment and I didn’t want to start a new idea unless I was really sure I could execute it.
I didn’t know it back then, but this composition would eventually form the baseline and inspiration for Stranded.
Fast forward to 2021, I have developed Unlikely Heroes, my prettiest looking 3D game, where I was the Technical Artist and Programmer.
Alongside other 3D projects, I believe I now have the abilities to take on such a challenge, and handle both the art production and programming as a fallback as I do not expect to be able to easily find collaborators early on.
In February 2021 I wrote a game deck listing 3 ideas I was really interested in to take further.
Enchanted Heroes 2, a 2D Idle RPG
Stranded (this one)
A science-fiction Tower Defense.
I shared the ideas with friends of various groups (gamers and non-gamers) and at the end, there was an overwhelming number of votes for one of these three ideas, and the one that got voted most was Stranded. I was surprised, as I spent equal amount of effort pitching the ideas and almost everybody I talked to lit up when I explained Stranded’s concept, and proceeded to talk about it as though the other ideas did not exist. It was amazing.
It is not all the time you get a clear winner or decision to make, but on that day, I decided what game I was going to build.
At the core, I wanted to build a resource management and simulation game, as I love Tower Defense and Strategy.
This idea isn’t solely about being alone and stuck in nowhere, but the core inspiration was a vibe of peace and calm. Not exactly things you think of when you play a real-time strategy isn’t it?
That’s why I am not trying to make this game be solely that. I want to try to inject some RPG mechanics. My core inspiration for that will be Stardew Valley. And that’s when I thought that this game could be a twist, a blend between RPG and RTS. I don’t know if the idea will work, but I believe it is worth a shot.
When I first played it, its intro hit me in the feels. It follows a story of a person who chooses to leave his mundane office job to do something different with his life. Quite an outlier and I kinda relate to that. It hooked me in immediately.
However, I never got through the game. It is too sandbox-y for my taste, and I got lost at what to do that I didn’t have much motivation to play again. I think the biggest issue in the sandbox genre is the lack of goals. Most goals are made by the player rather than the game giving you specified objectives, but not everybody would give themselves goals to do in the game. And personally I happen to be one such player, haha.
That is why for Stranded, I want to have a main ‘questline’ that will guide the players. It is optional, but for players who need goals, this should give players some guidance on what the next thing to work for is.
Thus, what I imagine for this game is Stardew Valley meets resource management, in a survival setting.
You have to attract people and feed them, keep them happy and working
You research technology to improve Quality of Life, such a automation or electricity.
The game will have you start as nothing in the middle of an ocean and the end goal is a sprawling city.
For archiving of my thought process, I wrote the pros and cons of this idea at the start of the project to remind myself how I arrived at this decision.
Why I want to make this:
– A really fun and cool idea, friends seem to like its premise
– The idea of reaching different “milestones” of progression can add interesting depth and twists to the game
– Had a lot of fun with resource management games, so I can see its appeal
– I really love Planetbase and this could be some form of it
– The sense of isolation can create interesting narrative and visuals
Why it may be a bad idea:
– I have not played similar games very much
– I am not as experienced in building base building games (from a game design perspective), compared to the other ideas here
– Could still try to be more unique from existing games (look at Airborne Kingdom, Flotsam and Raft Survival)
Yes. The truth is I have not played or built a game similar to this, so it is risky from a game design perspective. I do however really like how much potential this idea has after discussing with friends.
I don’t have any more pictures to share so I will end this post before it gets too wordy and I ramble on. I promise that future posts will have less words and more images and videos.
The next post will be about how I start building the base game.
For those that don’t know what Ludum Dare is, it is the world’s most famous game jam competition where participants have either 48 or 72 hours to make a game related to the announced theme. Anyone from any country can enter. On 1 December 2018, the theme for Ludum Dare 43 was announced – “Sacrifices have to be made”, and I spontaneously decided to take part, inviting Chris with me to join.
Here I will talk about how this game was developed in 3 days, how the core idea came to be, how it changed and will contain spoilers for the game so if you intend to enjoy the very short story or experience the little surprises in the game for yourself, you may want to play it first. Or if you don’t care, just read on.
This is also an exciting post because I will write about the entire game development pipeline all in one long post, from design to art to code to sound. Here we go!
Day 1 – Ideation
In light of the theme revolving around ‘sacrifices’, we initially had the idea of doing something related to the Trolley Problem, and make it into a game where the player has to make moral decisions, such as between sacrificing 1 loved one or 1000 strangers, and play out multiple scenarios like this one where you roleplay as possibly a different person each time.
However, in the end we decided that we needed to have an emotional context, or the player won’t feel anything for the sacrifices. So we needed a story! We needed a main character, so we decided about a Man. And maybe a dog! Basically, we want to tell a story about a man and a dog – I wonder what such a game should be called. The decisions the man has to make will get incrementally more devastating, starting with small decisions before ending with possibly having to sacrifice something he loves.
Given the time constraint, and this being our very first Ludum Dare entry, we had to be careful and humble with our scope.
Now that we had our idea grounded, we needed to settle how the game would look like or play out.
For art style, Chris suggested that we look at ‘The Monster Inside‘, aiming for a black and white, low poly Film Noir appearance. Our priority isn’t to have fantastic looking graphics as we want to spend the time focusing on our idea.
We spent about 1-2 hours just talking about the story and gameplay on Skype and Chris awesomely wrote down our discussion into a neat flow chart to structure our story and to label each scene for development.
I then dived into writing the code and a system to establish the flow of the game and within a night I had a prototype running up with a complete system to add, remove and insert scenes wherever they are needed. This was done by creating a StoryManager singleton which can be thought of as a master script that controls the scenes and how they flow between each other.
Why make a system when I could have easily done it faster with something simple like if-else statements?
Well, for me that is my preference and my takeaway from past projects. Thinking of and writing the code for a proper system can cost more time initially, but I felt it was important to have the flexibility of removing, rearranging or chucking in new scenes easily since this was our core concept and I didn’t want to waste time rewriting code later on if we underwent major story revamps.
I got started with some previsualization (previz) by modelling some simple objects for a typical forest scene. This was basically to visualize how the game looks and feels with some very basic assets (the 3D models of trees were just modelled with the bare minimum details to look like trees), so as to visualize a forest, which is our primary location.
This is the first look of our game on our first night I made up with some simple animated trees and some particle effects at the bottom (they are used for the campfire and fireflies). I quickly put those together to inspire Chris before he began working on the official art:
Along with some mock gameplay to test out our idea:
The player is able to select their choices by clicking the buttons below and they would each lead to a different scene, transitioned with black screen fade outs. Music was later added and is persistent through scenes.
I then showed this to Chris. Some things we noted: The characters were static and would only play out fixed animations based on the options we chose. The only thing the player can do is to pick one of two options. We felt this made the game feel too short and wasn’t very immersive. We wanted some level of interaction, where the player is able to interact with the environment and make choices on what to interact with.
We had only spent a few hours. Our first day was very short (less than half a day) as the jam was actually announced at a very bad timing called right-before-my-bedtime. So I went to sleep just as the jam started and we only had a few hours to work for day 1 before Chris knocked off for his turn to sleep.
Day 2 – New perspective and movement
The next day, we decided to then try out having controllable character movement similar to MOBA games like Dota. But we opted for WASD movement instead of clicking to move. The size of the world was also increased. It gave us this.
But now the world was too big and trees would occlude the camera view. However, we liked the dialogue popups that would appear as we get closer to certain objects and disappear as we moved away. Being able to control the character also improved immersion. So we shrunk the world back down to keep the play area small and kept the things that we liked.
Day 2.5 – Integrating final graphics
Then came the time to create the art. Chris handled much of this area, whipping up all the necessary 3D assets to create awesome environments, props, and characters. We went for very minimalistic shapes for the characters – cubes. But I felt the cube characters were a little bit too simple and I was worried the player may not be able to identify the secondary characters too clearly, so I added more facial features, such as jaws to the wolf to clearly identify it as a menacing creature, and two legs to the woman character, to show that she is a humanoid and not a four-legged animal.
The tree swaying and dog idle animations were made with by Chris with something called blend shapes – to make the tree move from one position to another smoothly, two “snapshots” of the tree’s shapes at the extreme positions are made, and then the software blends them together to form the missing pieces (the in-between frames) to give the illusion of motion, and hence, blend shapes!
For workflow, he passes me the characters and props assets individually as FBX files. FBX files are 3D model files (like PNGs but in 3D). So the tree FBX contains the geometry of the tree, the animation data (blend shapes) and also the textures. In this case, it may not look like we have textures, but we still have a ‘grey material’ on the tree.
We used only a single tree.fbx.
And then we have 16 environment models exported as FBX into the Unity game engine. The environment FBXes look roughly like this:
But the trees in the environment here weren’t exported with animation (by intention), just the geometry. So to get all the trees to animate they would have to be individually re-positioned in the engine (Unity) again even if they are done from the 3D modelling software! But isn’t that a waste of effort and time to do double work?
Well, I didn’t want to manually go through scene by scene and replace each tree 1 by 1 with the animated version of it, so I wrote a script to do that for me!
I’m not sure if this is actually a pipeline-related issue of exporting files from one software and importing into another, but from time to time on projects I face “time-costing” issues that are stuff which are super simple to do but just tedious. Sometimes I just use scripts to handle repetitive chores because that’s what programming is for – save time on repetitive tasks, even when it comes to art. So here I just wrote my own tool to save time when handling the importing of assets from different software. This script will add the necessary components needed for the animation and take care of scale, positioning, rotation of trees across all current, and future imported scenes. I ran the code in a safe test environment to confirm that it works (in case the script ends up destroying stuff), before finally letting the code run within the editor on the actual models. Within a few minutes I had replaced all the static trees with animated ones. It would be a LOT less fun to do this by hand with manual labour, and take up way too much time in a game jam.
The last thing to do was to play the animations at random timings so all the trees sway at different speeds. Yes, we only had just ONE tree model, ONE tree animation for the game. They were all just of different scale values, and playing at different animation intervals to make it look like we had a variety of trees. Talk about efficiency and cutting costs time!
Cool-looking swaying trees by Chris
Along with occasional particle effects, our forest was looking very alive. This is important even for a game where the environment isn’t the main feature because it makes your game more immersive, and you make the player actually feel eager to want to explore. Now that we had our cool-looking swaying trees, it was time to move on.
I continued working on getting the dialogues ready.
This was a lot harder than it seems as every scene can have multiple dialogues as opposed to the previous system fixed at one dialogue per scene. The dialogues were also now at the world-space level rather than as a user interface, which means that they are placed within the game world itself rather than as a UI element overlay. We completely removed the need to interact with the mouse and choices can be made with the “Q” and “E” keys. Also in the image above, the dialogues were varying in sizes, so I changed them to be more consistent in size and positions, and used this shader which would make the UI render on top of all 3D objects, regardless of their z-pos. (By default, objects closer to the camera are drawn on top of objects behind. However, that shader allows me to have a dialogue panel all the way at the back of the environment, and yet still be drawn on top of it, without getting blocked by trees that are actually physically positioned “in front” of it in the world.)
Chris also suggested that I lower the opacity of the dialogue background panels. This way, they weren’t as obstructive and I could make them bigger, and have larger font sizes for better readability.
Now we were getting somewhere.
Scripting wise, I wrote the text in Visual Studio, the IDE I use for programming.
Dialogue was previously determined in code. It was my preferred way. The script would determine what each scene says – the scene name, description, the dialogue choices and all the text data was nicely packed in one script and easily navigatable instead of scattering the text throughout different scenes.
However, with the change to support different dialogue panels per scene, doing it by script could actually be less organized. So I implemented the dialogue in a more object-oriented fashion, which was more visual. So I got rid of the old scripting way of setting text.
Above, I am able to dive into any dialogue panel and edit the text immediately and move them around in the editor to anywhere I want.
The ‘range’ in which the player must be in for the dialogues to appear are indicated by the green spheres at the bottom, again very visual for me to edit and each dialogue panel’s radius can be customized too.
Day 3 – Animation and Scripting
Now came to the final day. This was the most intensive day of all. Chris had by now completed the 3D assets and prepared some sounds for the game. I worked to implement the story and scene animation.
Events were being triggered mostly through colliders. I placed a trigger collider on the player which makes it easy for me to trigger events based on player’s position to the target ‘interactable’ object. I would use these events to trigger various things like animations, dialogue popups to appear, and even sounds. This makes it super easy for me to call animations dynamically.
But that was the hard part too – dynamic animations meant some things had to be scripted rather than having purely keyframed animations.
This was a huge chore, and the animations for each scene would take me between 1 to 2 hours each! It’s not just animation, but scripting as well as the animations are pertaining to dialogue choices. The game is actually more animation-heavy than I thought, as we have many scenarios and each scenario has multiple choices and outcomes!
For one of the scenes, Scene 6, I had “6a”, “6b” and “6c” animations to make, just for one scene! Even if they are just four seconds of animation each, they each take time.
There was not a lot of time left so I worked through the night to animate everything. All the animations were done on the game engine side, using Unity’s Animator tool.
The animator allows me to trigger events and functions, so you can have a trigger activating an animation that triggers an event that triggers some sound to play and triggers another animation. If you’re not careful you end up with ‘triggerception’.
If you’re actually reading my code, which you should not be, note that my code for the jam isn’t actually the cleanest. It is a game jam afterall, and speed is prioritized over cleanliness for some scenarios, though I always make an effort to stay organized.
Intertwining animation events and code frequently does get really complex in a narrative or story driven game like this one which relies a lot on these. I had never made such a game before so this was definitely a good learning experience.
Precious time was ticking by as I only had a few hours left.
I also changed the camera from Perspective to Orthographic, which was an idea by Chris, to make you feel like you are in control of the person from some higher being, and to get the 2.5D isometric look.
The perspective mode has a more 3D look and has more depth, but we didn’t need a huge looking world, just a small one where you can view the world at a distance. It also eliminates the worry of needing to have details up close, which matches our low poly style.
However, I really liked the perspective view, so I kept that for the Main Menu’s camera. Speaking about the main menu, it was time to do up a proper menu. A Main Menu is important because it is the first impression players get about the game. So making sure it’s not too haphazard was one of my priorities. I added a slick camera transition to move to and from the achievements, which was later improved to this:
This was easily done by grouping the achievements’ UI and separating it to render under a different (world) canvas from the screen canvas, a trick which I’ve always used to render world-space text and UI. By using multiple canvases, I could fade out specific UI without affecting others, and also control each canvas’ graphic raycaster, thanks to Unity’s <CanvasGroup> component.
This also allows me to ignore clicking on the screenspace canvas when it is faded out, resolving a bug where invisible objects were still receiving user input from mouse clicks and causing buttons to trigger clicks unintentionally.
With that, it was time to export the game to WebGL, so that it can be played within the browser! I was careful to make sure this was set up right because porting it to web can cause many issues depending in the project if not done well. I had lost hours just digging through web issues in the past where bugs or problems would occur on the web versions of the game despite looking fine when I played it locally on the computer.
This time, I faced no issues getting it to work on the web. I had made an interactive web piece recently, so the workflow and knowledge I had to export the game to WebGL was still fresh in my mind and this was done very quickly.
I also added an achievements screen into the main menu.
At this point Chris has also just woken up and was able to help with addition of some sounds to help improve the game.
Even in a short game jam, sounds are very important to give audio feedback to the player, in addition to the visual feedback. Playing a sad whimpering dog sound versus a happy, excited dog bark makes the difference to help the readability of the consequences of the player’s decision in the game. Chris did a good job finding the sound.
One of the fun sounds I wanted to add was a jarring jump scare sound that I really wanted to have for this ‘shocking’ scene, where the player gets abruptly smashed by a FREAKING GIGANTIC CUBE with SHARP SPIKES AT THE BOTTOM.
NOTE: EXPECT SPOILERS FOR THE GAME BELOW!
20 minutes left – But one last thing to do
With 20 minutes left to the final submission, I quickly cooked up a final feature, to make the final scene a lot more impactful.
For the entire game there was one thing evidently missing in the world by intention – colour. I wanted the final scene to have a visual impact and really sell the ending. As it is a simple game, there isn’t much more we could do to enhance gameplay or story. But to make the ending be more powerful, I added color.
Yes it is partly because I was sick of seeing the grey, colourless world, but hopefully it also breaks the expectations of the audience to do something cool.
This was a quick way for me to make the ending of the game cool and memorable. It was done with swapping out the default post processing effect’s profile I had put on the camera with one that supported (de)saturation and changing the saturation level by script. Basically it’s realtime scriptable color grading, pretty cool.
By the way, the game assets are actually black and white, and the final scene is the only one where I gave them coloured materials.
To make this scene even more prominent that it’s the final scene, I extended the size of the map with a flipped duplicate of the square terrain (which I bet you did not notice). Not only does this give you more ‘distance’ to walk for the colour to fade in more gradually, but I feel it also kinda marks it in your subconscious brain that this is different from the previous levels and is the final level, setting the right expectations that the game has ended, leaving you satisfied instead of feeling abrupt.
And with that I submitted the game for the competition!
Polishing the little things
I added an achievement panel popups for when the player earns an achievement for the first time, so they know they unlocked something.
Then I added a proper settings panel with the ability to restart or quit, and adjust music and sound volumes separately.
The achievement icons got upgraded graphics and have some animated FX on the icons for when they are earned.
I also used depth of field to create a background blur effect when the player dies.
I also added ambient occlusion (SSAO) to ground the scene more and to get more dark shadows underneath the pine trees so the cone layers of the trees look more defined and closer to Chris’ reference layout images.
Honestly it looks so much better. In case you were wondering why it isn’t baked, the effect is screen-spaced as there simply wasn’t enough time to use baked lighting to obtain true global illumination (GI) and AO for the 16 scenes that we have, so performance wise and visuals wise this could’ve been improved through baking the AO outside of the jam. This method is also so much quicker to do as it is just a few clicks.
It was also after the submission when I made the change to the final coloring visual effect to the final scene here, to transition based on player’s distance to the exit, so as he gets closer to the exit, color will slowly fade in. This was really cool, as opposed to the previous method where it just gradually faded in. I didn’t have time to write the proper code during the jam so it was only done when I had time for polishing.
Unrelated to the game, here are some cinematic shots of the environment taken with a completely different perspective from the game. It has a totally different feel with colours and even looks like an entirely different game. I picked out some of my favourite compositions, which is basically all of them.
1 day after the game’s release, we got our first rating and comment from a nice person on the internet, Lizouille.
Some improvements to make to the game as comments from my friend was that the first two endings didn’t felt like endings, which was not helped by how the “you died” panel wasn’t significantly different. So I will work on changing that. I initially planned to have a transition to full black screen slowly and then have just text on the final screen of each ending, but I had no time to do that during the jam, so it was dropped.
I also want the achievements popup to say 1/3 or 2/3 achievements earned, so the player knows that more endings are possible to get in the game.
My Thoughts / Reflections
This is one of my most relaxing game jams. I actually slept, bathed and ate normally. I didn’t feel that pressured by time until the last day, when it got pretty crazy. But it was still pretty chill. It was my intention to not want to sacrifice my sleep or take it too seriously because it was just a tryout and I was already late to the competition anyway, so I just wanted to take it with a more relaxed mindset as opposed to feeling frantically forced to work at a fast pace. I think we all have had enough of that in life already 🙂
And yes, I was late because I was confused by the actual competition’s start time due to different timezones. I thought I still had time to sleep before starting, but it actually started way earlier than I anticipated. I didn’t even have a team so I actually only started asking all my friends if anybody was interested to join me. And this was AFTER the jam had ALREADY started, and having to explain to everyone I asked that this was a super last-minute thing. I was half not expecting anybody to be able to commit on such sudden notice. Only one friend was free enough, Chris, which I am grateful for.
This being my first Ludum Dare, I was expecting to make many newbie mistakes too. But so far it was pretty smooth. I think having created lots of games before and having experience helps. As I was on Youtube reading and looking at other peoples’ jams, I saw that a number of people actually failed to submit – they just didn’t know how to fix their bugs, encountered problems with their project or simply faced technical issues that stopped them from making their game. So I am definitely happy with what we made and it really is something to celebrate to be one of the 2500 games in the world that made a game for this competition, given how little preparation we had. There were bugs on release definitely, such as the character getting stuck in the environment.
(Which I’ve fixed.)
And the dog spawning in weird locations and falling off screen.
(Which I’ve also fixed..)
And a bug where the blur caused by depth of field did not get disabled.
Was that list of bugs ever going to end? Anyway, so what did I learn from this experience?
Expanding my Design & Technical scope
This is not the usual type of games I make. I have a preference for creating games with fun gameplay and a sense of progression, but I didn’t want to always work on familiar territory and genres or topics, so teaming up with Chris, and in joining this Ludum Dare, I get very curious to see what games other people would make too with the theme. This way my scope is expanded, and as mentioned above, I may be using familiar tools (Unity, Animator), but I’ve used them in new ways to create things that are normally not required of my projects, so this is a good learning opportunity for me as well.
While I could have gone solo, working in a team almost always provides better quality results, and is especially important during the design and feedback phase.
This jam also lets me practice, train up and apply the animation principles I’ve learnt in the past year while studying Animation. I doubt I would’ve been capable of creating these animations without studying proper animation techniques prior. To make simple cubes look good, you have to think outside the box. Ha ha. Squash and stretch, easing in and out, staging – you’ll see those at play for many of the scenes and character animations created – I want to inject life into lifeless black and white cubes and make it feel good to look at them.
This project is a reminder to myself that animation isn’t just about making something move or performing an action for the sake of it. You want to make that behaviour look obvious, readable and the action interpretable by the player, without leaving him confused as to what he just saw or leading him to the wrong focal point. Moreover, you want to aim to have the animation be pleasing to watch if possible.
My favourite one is the dog circling animation at the start of the page which plays when you offer to share food with the dog (the other smaller cube).
The way the dog appears to bob up and down excitedly, pouncing around in circles. He’s not just moving and rotating in a circle around a point which could’ve been the easy way out to ditch animation quality for time in the game jam.
The ones that got me spending the most time on was animating the final wolf scenes. Here are spoilers of the animations.
Okay so I am not an animation expert but these were what I did to make the scene’s animation as believable as possible. Having some anticipation action before the wolf lunges forward prepares the viewer for what is about to happen. The stretching of the wolf as he’s in the air and the squash as he gets hit by the man’s weapon exaggerates the impact and action. The man character leaning forward in the direction he is jumping toward gives him weight and makes the jump believable as you can tell by the posture where he is jumping toward even if it were to be a still picture. The man swinging the weapon backward just before he strikes the wolf makes the swing look more powerful as it looks like the energy has been built up. The big wolf’s rocking body as he struggles to get up when he’s overturned makes him feel heavy and stuck. And overall staging makes sure every character’s animation is the focal point at the right time and will be read by the audience. Usually only one animation should be playing at once and sufficient time should be given to ‘register’ an action, so that multiple animations don’t overlap and fight for the audience’s attention. (However, above there were some parts where the animation overlapped after I made a last minute edit that slightly screwed the timing). That’s animation in a nutshell and if I did it well, I will have to thank the animation professors who have taught me.
The best part of these animations is they were all just to do with rotating, scaling, and moving of the objects and all done in the engine without the need to go back to Maya or the 3D modelling software. No need for complex blend shapes or rigging (setting up of a skeletal joint system for characters) so in terms of the technique itself, there was nothing fairly fancy and complex which is perfect for a game jam as it is simple and saves time.
WHEW and that was how I spent my 3-day weekend. With all that done, it was time to get some rest, and look for the next exciting project!
Oh, and if you’ve read this far, thanks, and please consider rating the game HERE as every game needs at least 20 ratings to be qualified for a score during the results announcement in January 2019. And also maybe try out the other games. Ludum Dare really spawns some creative ideas out of people and some of the top games of past competitions are really creative!
Most achievements should be attainable now, though I may need to decrease values further since this is just based on peoples’ statistics, and some people have gotten really far in the game that the data may not be good to use.
This was quite some time ago. I saw comments on how the level 200 (final boss) monster’s description said that you could tap him to do damage even though it is immune to tap.
I was going to add a simple ‘Immune to Tap’ description to replace the boss’ hover tooltip, but then I somehow thought of this crazy idea where it would actually reflect your tap damage back onto your heroes if you try to tap him.
I got the idea when I was writing the dialogue for what the corrupted rune should say when you try to click on him… Hmm so what should it say?
It being the final boss, I was a little more motivated to make it do something never done in the game before, so I decided to see if I could do that.
I even drew a shield icon for when this happens but I think it’s going to be covered by all the damage numbers from the heroes. And after that was done, TADA!
For fun: Secret Merchant
The character above is the Secret Merchant. He lives in the desert and is the person in charge of the Secret Shop. I intend to use him for some minor compensation in the future if I do intend to decrease the cost of items in the secret shop or even the guardian shop.
Note: This has nothing to do with the game and more of my personal thoughts, you may skip this if you are not looking to read about me.
As I am going to be starting my studies soon, I predict that I may not be able to spend as much time developing this game as I want to, and juggling schoolwork + my personal projects may not be very easy. As such, I wanted to wrap the game up and my goal was to finish up Guardian 2 + Storyline conclusion before 23rd July. Fortunately I was just able to do it in the last week. As such, the game would probably not have anymore content or updates further down the road. Even if they are, they would likely only be fixes.
On the night I published the final update (v0.80), I decided to lurk in the game’s chatroom. I had a nice chat with some of the people in the chat. It was really fun and creating this game and publishing it is definitely an experience I won’t forget. Talking to these people and reading positive comments really remind me of the joy of creating something – creating a game, and sharing it with others can be a really magical experience.
The thing is, most of the comments I read on the game’s comment section are usually complaints or bug reports. Sometimes, I get comments that don’t make sense at all, getting called a sexist for the game not having so many male characters, or even get posts of browser problems that may be unrelated, etc. My friend did tell me that it is unlikely that much of what you read on the internet would be something good or encouraging I suppose, so I do kind of expect that most comments would not be something very positive.
However, I do occasionally read comments that brighten up my day. But I guess another thing I was also told to take note of when publishing a game is that it’s less of how I feel, and more of how other people feel. Reading the comments is something that I end up having to do, not to make myself feel better, but to make improvements to the game so that other people feel better. So it’s less about yourself and how you feel, but more of what the people feel.
Being in the chat room however, made me feel at ease. Perhaps I’ve been a little too stressed out lately, but talking with these other people who were enjoying the game and casually chatting rather than responding to issues made me feel so much better. It made me feel relaxed and happy to have created and published this game.
Making an Idle Game Part 9 – Cutscene Work & Optimizations
In this post I will mostly talk about some of the stuff in Unity. They probably aren’t too technical if you’re familiar with Unity, but for most people who don’t make games, I’ll just mark it as ‘technical’ since it may contain some jargon.
Aside from that, this is also a continuation of the previous post and I will talk a little bit about the cutscenes I had worked on.
Oh, here’s something I did for a particular space scene. I felt that for this scene, I wanted to have the ball look like it was shot out from something like a wormhole to denote that it is coming from another dimension. Without the wormhole, it looks like it just came from outside the camera and came into view. But I was a little tired to go back to my scene and add a wormhole, so I drew it as a separate asset and got the idea to animate it in Unity, using a particle effect system:
The above is not how it looks like in the game since and was just a quick test. I think the wormhole with FX may look better than just being a static object which I had originally made it out to be.
Level 150 Storyline Boss
I also drew a new boss! Yeah!
I had been planning to make the game have an ending. Zone 201+ was meant to be for people who wanted to continue playing the game, and I wanted to make it clear that there was not going to be any more story content past that, so the game had to be split into what most games do – have a campaign and survival.
I had a few ideas but it all ended up really convoluted and confusing, especially because I the game has 5 savefiles, 1 autosave, 6 cloud files, and then trying to make another type of ‘survival save file’ ends up just making a mess of the entire thing because there now has to be two copies of every single savefile. Then I need to think of whether I need some kind of “Load Story Game” and “Load Survival Game” in the menu? It was awkward design so I ended up with something simpler – just having a submenu after choosing a savefile to load.
After completing level 200, the savefile will be marked as a survival save file and you can only play on in survival mode.
There is nothing special for survival mode, though I did at one point considered changing the Level 300 boss to something. But I didn’t want to give any hints that there would be any form of storyline continuation, so I decided not to add anything to survival.
Unity Canvas (technical)
When making my cutscene, I had to decide what kind of canvas to use. In Unity, you would likely have to use a canvas – a canvas is something which contains all your UI objects (buttons, panels) and in your 2D game, it can contain images like your character sprites.
There are three types of Canvases in Unity and I had to think carefully about which was the best canvas to use for my cutscenes. Each canvas has its pros and cons which I was considering.
The three types of canvases in Unity are:
Screen Space – Camera
Screen Space – Overlay
1) World Canvas
The World Canvas is good for a lot of things. For reference, a world is basically where you put all your primary objects like your heroes, and enemies.
Therefore a world canvas is good for making UI part of your world – eg health bars over the enemy, floating damage numbers text. It’s the canvas I use for my main game.
However, there are parts of the UI that I don’t want to be part of the world. Things like the Gold UI and text should not be part of the world.
This is what screen space overlay is for.
2) Screen Space Overlay
For my Tower Defense game, I had to switch to using a Screen Space Overlay. Unlike the World Canvas, screen space overlay is put ON TOP of everything in your world. It’s perfect for UI.
For my Tower Defense, I move the camera a lot. It pans to follow an object, has zooming in and out…
Above, you can see the UI on the right does not zoom in and out with the camera. If you use a world canvas, objects will behave like world objects do, and zoom in/out, which is not what you want for your screen UI. In this case, I would use a screen space overlay for such UI.
3) Screen Space Camera
Screen Space Camera is like Overlay, except that since it isn’t an overlay, you can render stuff on top of the Screen Space Camera, which I primarily use if I want to have particle effects on top of the UI, like glowing sparkly buttons.
Because the Screen Space camera requires a camera, this allows me to do very specific camera stuff and special tricks.
For example, I can have a camera that only draws UI and another camera for everything else. I can even set up a camera for a top down shooter game that only draws the background and characters and not draw trees or enemies – useful if I want to make something like a game mini map.
The reason for having a specific camera to render the UI is because if you have a side scrolling platformer game, and your camera moves with the character, you don’t want to re-position all your UI all over again as the moment an object’s position changes in the game, you will have to recalculate its collider, bounding box, and apply physics to it (if you have physics rigidbodies on your objects). Therefore, when using Screen Space Camera, I set my UI to a separate stationary camera that does not move with the world camera.
In the end, I went with a totally different approach. I decided not to use the canvas for my world objects, and use a World Canvas only for the UI in the scene. I put characters and heroes and other objects outside the canvas and grouped the objects by the Cutscene they are used in.
Draw Calls (technical)
Another part of optimizing the game is to reduce draw calls, which I had done quite awhile back. I also did something in the game to help decrease memory consumption further (the game currently doesn’t use much memory while it runs anyway, but this may help on older PCs)
What is a draw call?
To draw an object (like a character) on your screen, the engine (unity in this case), has to make a draw call to the graphics API, which interacts with the GPU and “tells” the GPU what to draw on the screen – at least that’s the definition I read.
So if I had a hero that I want to render on the screen, Unity would get the texture of the hero, call the GPU and tell it to draw it on the screen. (To be accurate and according to Unity, the call is made to the graphics API like OpenGL, which interacts with the GPU)
But if I had another object, like an enemy on the screen, now I have to make two draw calls every frame. If I put in a background, I would need three draw calls. Here is a picture that starts out with a white wizard character and I slowly add objects to the scene:
However, if two sprites share identical textures, then no additional draw call is needed. Think of it as only one draw call would be made to the GPU, and it would be told to draw the texture thrice, at position A, B and C, rather than making three separate draw calls each time to draw the object. (this assumes all the objects share the same material). So if I add more enemies to the scene above, the draw calls made would not increase.
Draw calls are expensive and can be taxing on the CPU (and make your game lag), so you would want to reduce the number of draw calls in your game as much as possible.
In Unity, draw calls are also known as ‘setpass calls’ and the number of calls being made can be seen in the editor. In the picture with the white wizard I gave above, it is possible to reduce the draw calls from 3 to 1 – the background, the white wizard and the 3 bush enemies can all be drawn with a single call, thanks to something called the Sprite Atlas.
Sprite Sheets and Sprite Atlases
If you’ve tried making a game before, you would know of spritesheets. If you have a character walking animation containing 5 frames, and if they were five different images, the engine would have to make a separate draw call each time you want to change the frame – from frame 1 to frame 2, from frame 2 to frame 3, etc because it is using a different image.
But what a spritesheet does is no matter what frame your character is at, it is drawing the character using the SAME texture, and you don’t have to swap the texture to draw a different animation frame.
So all the engine needs to do is to tell the GPU to use the same texture, but draw a different section of it. Here’s my own neat animation of how spritesheets work, using my warrior character:
The engine slices your texture into different ‘boxes’ called frames and you specify which frame the character is on, and which frame to draw onto the screen. The slicing is done behind the scenes and is invisible to you, so you only need to specify the width/height of each box and the engine will ‘slice’ your texture internally.
So even though my texture has 8 different character frames in it, at any one point, only one slice will be drawn onto the screen at once, so you can’t have two frames at once.
Moving beyond that, there is something called the Sprite Atlas, which is like a spritesheet. There isn’t significant differences between them.
Below is one of my Skill Atlases, which is one of the many Sprite Atlas-es used in my game. The skill atlas is a single huge image comprising of several individual textures. When I need to retrieve a particular frame or texture, I need to ‘download’ the whole atlas, and then retrieve the frame that I want.
I mentioned this in one of my previous posts and atlases work similarly to spritesheets, but you can pack a lot of things, even sprites that you may use for different objects or characters. Sprite atlases help to reduce the size of your game, the memory it uses (for WebGL). It is one step above spritesheets and can reduces draw calls since multiple objects will only require one atlas.
In the atlas above, I have three skills using this atlas – the blue Dragon Skin skill, the purple Weaken skill, and the yellow Slashing skill. All these 3 skills will only take ONE draw call instead of three as it normally would have been if I use just sprite sheets.
Also notice that the atlas above is square and is power of two (2048 by 2048 pixels). This is by intention as it allows the atlas to be compressed in a better compression format which further reduces memory consumption/ game size.
You can also enable rotation to pack the sprites in a more compact way so that as much of the 2048 x 2048 pixel space is filled up and no space goes wasted. If packed properly, this is a very huge gamechanger.
Memory consumption (technical)
This is very much linked to the topic above on sprite atlases and is pretty wordy.
I was looking into how the game is using its memory and a large portion of it is taken up by textures.
When a texture is loaded in the game, it takes up some memory. Bigger textures generally take more memory as each pixel of the texture takes up 1 to 8 bytes, depending on the compression format. Memory can be used up in other ways too – but for my game, 70% of it is by memory and you can see it in the picture.
In the first line, it states that the game is taking up 106.7MB of memory (out of 256MB that the game is given). This is in the game battle scene, which is the busiest and most resource intensive scene.
Out of that 106.7MB, 73MB is used by the GfxDriver, which is mainly textures. So I looked at the breakdown in texture memory.
Note that the above table is a snapshot of the EDITOR memory as I can’t seem to get the values of the actual player. As such the values above are MUCH higher than in the WebGL player and may not be accurate, but it is the best I can use and useful for a gauge on what’s contributing to the memory usage. You can see that the highest contributors to memory (IN THE EDITOR) were backgrounds and skill effects.
I decided to trim additional transparency in the background. Although trimming transparency doesn’t help very much with file size since all it does is remove the empty pixels, doing so reduces the memory used by the texture. As for skill effects, I cannot trim their transparent pixels as much since they are spritesheets and each frame has to maintain a certain width and height for the sprite to animate easily as seen above in the SpriteSheets section.
In all honesty, it is extremely difficult for the game to actually hit the memory limit, which is set at 256MB currently, and my time is actually better spent developing other stuff, like content, or fixing issues. However, I decided to take a look and dedicate time for this.
Above are my jungle area’s monster sprites. I throw them into an atlas below with the platform sprite (the huge tree). I’ve marked it in red because I’m going to talk about it below.
Two power-of-two (POT atlases are formed as a result and they are 2048 x 2048 and 2048 x 1024 px respectively. There is also quite some transparent space, due to the platform, (l have indicated the sprite’s bounds with a red rectangle) which shows that some “wasted” memory is allocated just to store the empty pixels in the texture. Can I pack them in a way such that I use the transparent pixels’ space? Apparently, yes! But it does come with some drawbacks.
Here’s a picture of the new atlas. Notice how the transparent pixels have decreased A LOT and they are packed so much more efficiently, and closer together.
In the game, I decided to change the way sprites were packed – and specified certain sprites to allow them to be packed with a tight rotation policy – these are mostly sprites like the platforms and monsters. Unity’s atlas tight packing policy will pack them with its own algorithm to make it space efficient. Packing sprites tightly reduces the memory taken up by texture, reduces the time taken to load the game and also improves performance as it gives the CPU more time to process other stuff rather than focusing on drawing stuff to the screen. A video here explains it much better than I can.
(I should make a game about optimization, and it shall be the opposite of an incremental game where you try to get as less pixels as possible! – Nah just kidding)
The tight rotated packing, while better than the default rectangular packing, does come with some drawbacks so I cannot use them for everything. I therefore have to specify some sprites to continue using rect packing. OpenGL may also handle rotated sprites differently and cause the sprite to look different if it applies additional anti aliasing / artifacts during the rotation process, but thankfully I don’t notice a noticeable drop in the sprite quality so far.
I also changed the way skills were packed and not pack frequently used skills together with infrequently used skills. This is because if you pack them both together, then whenever you cast a frequent skill, you end up loading the atlas of the infrequently used skill.
The above is the atlas for a skill called Wisdom. It has a high cooldown and can be cast quite infrequently, so I have given it its own atlas. This atlas is destroyed if the skill is done casting so it does not persist in memory, but has to be reloaded each time it is cast. I might change this if the reload actually causes a noticeable lag, in which case it is better for such textures to remain in the memory. Again it all depends on how frequently the skill is cast and thus how frequently the texture has to be (re)loaded.
This was done for the other less frequently used skills which were given their own atlas, and packed with a tighter policy. And when these skills (mostly buffs) are done casting, I remove the texture from memory. This will cause some overhead if I try to load the texture again, because now that it is gone from memory, all references to the skill’s spritesheet is DESTROYED, meaning that if I were to cast this skill, I need to reload and re-create the texture to put in memory again, which takes up CPU. And that is the tradeoff here. So although destroying a texture after it’s done frees up memory, I only do this for skills with exceptionally long cooldowns or are cast infrequently so that when it does not interrupt the game too much.
In the end, I decided not to destroy the texture after it is loaded, as the game consumes very little memory and hardly hits the 256MB limit unless you have played for a very long time, and I’m not sure if the performance tradeoff is worth it. However, the improved packing still helps to decrease memory usage and draw calls as the atlas is split more efficiently.
This post will be very heavy on a new guardian for the game, an upcoming content which I hope to release by the end of of July or August. I may split this giant patch into smaller updates since there’s a lot of things to do.
Guardian 2 Dialogues
Guardian 2 was a little more complex to add than I originally planned out to be. And a large part of it was due to how to introduce this guardian to the game as well as organising the flow and dialogues.
I haven’t yet thought about how to design a simple straight forward way to organize the game’s dialogue messages in code – I currently ID them and link them from each dialogue (eg dialogue 228 can lead to 229 or 230) and because everything is written in code it gets very hard for me to visualize which dialogue leads to which. So sometimes, I draw flow charts. The introduction of Guardian 2 has 30 new dialogue panels! Half of which is part of a ‘Quiz’ dialogue which is something new to the game, and am pretty excited.
When getting Guardian 1 in the game, you can pay him 10 gems to ‘bribe’ him. This is good for those who do not want to wait to get him. But for those who want to sacrifice gems, they can get the Guardian 1 for free just by making their characters strong.
For Guardian 2, there is an upfront cost of 20 gems to get him. But you can reduce this cost by doing a very simple test. 🙂 I don’t want to spoil this too much though. It was very fun to write the test actually. But for those people who don’t like tests, they can go ahead and pay 20 gems to skip it. I intended Guardian 2 to be perhaps unlocked in the second run and I may reduce the cost to 15 gems since 20 can be a little high for new players. It’s a one-time cost.
I’ve also added buttons to change your current guardian. On the left, you can see my initial design. Two buttons just for previous and next. The second picture on the right is what the game uses now.
I decided to replace arrows with a picture of the guardian’s head. I think the guardian’s heads look very unique and identifiable – I’ve made their heads have a unique colour so even though I drew their heads with similar structures (so they look like guardians and not too human-like), no two guardians have the same head colour tones. This was something I kept in mind when designing my new guardians, speaking of which…
Designing the new Guardians
NOTE: There won’t actually be new Guardians added to the game. This is made mainly to end the story.
Above were the sketches of what I envisioned the new Guardians to look like. My favourite has got to be the “Guardian of Creation”:
Each guardian has his own colour tone. The guardian of Creation above is clad in purple robes and is holding a sphere like object. There are other smaller circles (spheres) around the character to represent planets, while the giant yellow sphere he’s holding is like a crystal ball that will show the galaxy.
Since the five Guardians revolve around being in space and being these other worldly beings, I took to the stars for inspiration. Here are some of the pictures that inspired me (not all of them are linked to what I wanted):
You can see above where I got the idea to make the guardian hold a ‘crystal ball’ of the universe. I also got my colour scheme when I realized a lot of the images have bluish to purplish hues. 🙂
Oh, just to get in the mood, I listened to thiswhile drawing, looping it on repeat. It’s the soundtrack of one of the best and inspiring documentaries I’ve watched about space. I really love the wonders of space and this kind of things and I think this is what makes drawing the guardians and the Crossworld really, really fun!
I also drew inspiration from the movie, Thor. I enjoyed the Thor world’s visual effect and especially liked the universe / starry space scenes, as well as the Gate Keeper.
I took a look at the Gate Keeper’s costume (picture on the left below), which is really cool, and used it as inspiration for the helmet’s shape of one of my guardians.
Something new to the game will be story cutscenes. I put together a completely new way of delivering the later part of the story. There will be only one cutscene sequence in the game.
Above is a draft of one of the cutscenes that will occur. Everything you see above is unofficial, so is the background – this was just a fast and quickly-animated scene for me to see how this particular shot plays out in the game. I most likely will not animate the sprites of element very much – for the particular scene above, I intended them to be just silhouettes.
I have drawn out a storyboard out for this sequence. (There will be only one story sequence in the game). One sequence comprises of several scenes.
The storyboard has several boxes, where each box is one scene of the sequence, like the animation above. I also refer to ‘scene’ as ‘cutscenes’. Each cutscene can have several states. States are one level below ‘cutscene’, and I use it to fine tune animations and control the triggers to certain events, in addition to using timers to control when stuff happen).
Now onto the programming and integration aspect. To make it easy to script the sequence and have control over the events that occur in a scene, I organise the scenes such that I have an indicator on which cutscene and state I am currently on.
‘currentMessage’ above refers to the accompanying text for the cutscene. For example, in a scene where I have to gradually fade in five guardians one by one,
I can use ‘currentState’ here to control which guardian is currently being faded in and which one to fade in next.
The entire cutscene took me about a week to do.
I spent one day writing out the story script, then drawing out the storyboard as well as some mock up art assets (the black outlines you saw in the animation above).
Then I spent the next few days drawing and creating the official art assets and animations- the characters and such.
While doing so, I also spent an equal amount of time in Unity choreographing the sequence and animations, as well as scripting the events that follow. I also wrote an AnimatedText script to animate the text to appear letter by letter. I added a few functions for myself to make the script re-usable if I do decide to extend this script to use for future games.
I added my own special way to easily add pauses into text, and you can see me type <p=1> in the story messages below:
Adding <p=1> makes the animated text pause for a second, before resuming. This makes it convenient for me to add delays in the dialogue via the message string itself! This is useful in cases where for example, I add a 1 second delay at the end of a long sentence, before displaying the next sentence in the same string. A one second pause is usually enough, but I can do <p=2> or higher to make it pause for longer durations.
Also just for fun, I did a mock of what I felt would be a cool main menu, with a crudely drawn bad shadowy guy of course, since I don’t have the art for him at this point.
As probably mentioned above, story is a really time consuming thing to do. It’s heavy on the art and planning side and can be very exhausting to execute. It was also not that relaxing on the programming aspect since each cutscene has unique effects and you got to code most of them manually most of the time.
Also, here are some icon variations I drew for the new Guardian’s abilities. (Note: They may not be the final icons to appear in-game, I will pick the ones I feel are most appropriate to be the official icons)
Balancing / Changes
I’m always working on other areas of the game even though I am focused on content for Guardian 2 right now. One of the things I wanted to address was the uselessness of the Blacksmith upgrade.
Countless comments are talking about it, here’s one. I didn’t have to look far to find it.
To address this, I intend to make Blacksmith apply its bonuses on ALL equipment/hero upgrades and not just be limited to enhancements to make it worth its high cost at higher levels. The formula will be changed to allow it to allow to in the future, have some way of being able to increase its max level beyond 10. (Currently it is capped at level 5, at a -50% cost reduction).
People also could not purchase expensive gem ugprades, so I made them cost enchanted gems if they are beyond a certain cost. Currently, the only upgrade facing this problem is Blacksmith.
Here’s a look at the old vs new blacksmith upgrade.
This is part 7 of my making of an Idle Game. And here are some of the things that I have worked on, am working on, will be working on, and will not be working on.
Guardian 2 Storyline
After pushing out v0.72 and having cloud save download, I could finally move on to other more exciting stuff. With only about a month left before school starts, I hope to at least get Guardian 2 out. That would also mean that I want to wrap up on this game and hopefully finalize the content. This also means that with the release of Guardian 2, content generation for the game will come to a halt soon. I’m not sure if I can juggle schoolwork and Enchanted Heroes simultaneously and even so, it will be extremely exhausting for me.
Anyhow, here’s a picture of the new boss that I just drew. It will be part of the Guardian 2’s storyline. You may get to fight him.
As you probably can tell by his looks, he will spawn somewhere in a forest zone.
There will be some new really minor storyline related items. This is a new item that may look familiar to some players because of the item that this was inspired from:
I actually feel like improving some of the monster art, especially the bosses. Perhaps when I have the time to, I will be replacing some of the monsters.
Some days ago I had a chat with one of my friends who was providing feedback for my game. He drew up a mock of how the UI can be improved on a sheet of paper. I think it would be great if the game could have this new UI, but it frankly is a lot of effort.
As much as I like to think that it’s just shifting things around as and when you like for fun, it is really not that straightforward.
I probably won’t have time to work on this and I may not even get to doing it since it is really quite a lot of work and this by the way, means that there will need to be two separate UI layouts for the mobile and WebGL versions, again, this can get messy if not done well. Furthermore, when I built this game I didn’t intend to have the game be able to support dynamically switching UI elements around like that.
Anyhow, here were some UI improvements I made for the game recently.
I noticed many people wanted to see their maxed upgrades remain in the shop, so I made them retain in the shop but move them to the bottom so they don’t block or make it troublesome to find unpurchased upgrades. I also made them greyed out a little. (See the above screenshot of the comparison between normal shade and darkened shade of the upgrade)
I also added a border around skill icons to signify what class the skill originated from.
I think this is the cleanest way to do it and to easily distinguish a buff/active skill. I might thicken the border since it looks pretty small.
Minor Skill Balancing (and the MP regen problem)
Skill Balancing is something I may never get to work on because of how little time I have left before school starts on 23rd July.
But I rolled out a minor skill patch. I actually have a BIG list for skills. But I may not have time to implement all. I may roll them out in minor patches, or not at all.
Here was the first minor change – the mana cost of Resurrect.
On the right, you can see the old absurd values, and on the leftyou can see the new values. The cost of resurrect was too high to make it useful especially in higher levels, so it was decreased. It was also capped at 75,000.
On the other hand, I want to solve the problem of “priest has lack of mana”, which appears many times in comments. I realised this is happening because the EXP cost needed to upgrade the skill falls much lower than the gold cost required to upgrade the earring’s MP regen. I think most people didn’t get that it was better to save your EXP if upgrading a skill means that it takes your toll on mana – I guess I didn’t design the mechanic well so it isn’t easy to tell straightaway that you should level down your skill if that happens. I guess trying to add a bit of ‘MP or resource management’ and adding some strategy on what your skill levels should be at didn’t exactly turn out the way I wanted to. Oh well.
Ideally, just when the cost of the skill gets too high, you should be able to get enough gold to upgrade your MP regen, but right now the skill’s EXP cost does not scale fast enough to keep up with the gold cost, which makes it easy to quickly upgrade a skill and before you know it – BAM! It’s costing loads of MP, loads more than how much MP you actually have.
When making this game, I had planned for a boss every 100 zones, up to the 500th Zone. Unfortunately I was not able to design them all in time and only created the Warlock and the Zone 200 boss. To wrap up this game, I may add a final boss. The final boss will either replace the current Zone 200 boss or be a new Zone 300 boss.
Adding it as a Zone 300 boss is going to take a lot more time as content and story needs to be developed. Though I have a story script that is being developed for Zones 150-250, it takes time to add all that in and implementing such stuff is a real time killer. If done wrongly, the game turns out being grindy and not very fun. It is easier to make it replace the current Zone 200 boss, but it depends on how much time I can dedicate to this game.
The art for the final boss was done long ago, but did not get added into the game due to the lack of time. I may or may not be adding a boss at or after 200. But if you do see it, it might not be a good sign since it means that I will stop updating this game once the final boss is out.