What I want to be when I grow up

First of all, I would like to say, that there is a large difference between researching a career, and experiencing it first hand. This alone makes a question like this nearly impossible. I know what I enjoy doing, but have had a very narrow experience and find it kind of difficult even articulating what I have enjoyed most, but in short, it has been making my games look pretty. Were I to make that my career path, the closest job that encompasses that in the gaming industry is as a Tech Artist.

so what does a tech artist do?

“Technical Artists help Artists and Designers get their content into the game with the least pain possible, and help Engineers and Artists communicate fluidly.
Technical Artists must know what a healthy art pipeline “looks like” and must help make sure that content creators have the tools & support necessary to do their jobs.”  –Polycount wiki

A local Tech Artist would be Chris Webb, who is currently working as a Programmer at Defiant Development. I was reading through his twitter feed and found out about Godrays, which I thought were sun shafts because of the free unity camera effects asset package that includes them in it.

Tech Artists will normally work in a specific subset, which can vary widely through companies, the most common task being to write tools for the artists in that company.  These will usually involve Rigging, Shaders and Visual Effects.

 

The two that I have been interested in recently were creating my own 3D trail renderer and a shader that mixed a toon shade effect with a crosshatch effect, to override the regular shadows in Unity.

Learning how to effectively program well-optimized shaders that can make objects look amazing would be very useful, especially if I can reduce the cost of them enough to be used on mobile platforms. This means learning how to move away from bodging together code, which I am awful for and focussing on planning and documentation. I could figure out great places to start by reading through blogs of other Tech Artists and even asking them or finding out about the things that interest them.

I could instead end up working for a smaller company, where the skills that are required in me are more general, like becoming a programmer for Halfbrick or Lightmare. Halfbrick tends to work on mobile and console games and have recently been creating them using Unity as their engine, which I have a bit of experience in already. Halfbrick offers internships for programmers, offering a friendly place to start, the people who built Halfbrick also studied at SAE. Lightmare  has also been looking for interns lately, but I have heard that they can be a slightly less friendly environment.

Getting a job in a smaller studio like these would be a great place to find out what it is really like to work in the industry and help me to find my focus, which would help me decide where I would end up if I choose to work in the larger industry, or at least give me experience if I wanted to create my own studio or work in someone else’s start-up.

Without being known in the community, though, I would find it difficult to get a job in any of these places. I have recently joined a couple of meetup groups and facebook pages, specifically Game Development Brisbane and Brisbane Unity Developers. I also began following IGDA Brisbane and plan on attending these events (with my professional face on, of course) and do my best to keep active on twitter.

 

My work on Titan Tussle

 

In these last 5 weeks, I was the programmer for a group project named Titan Tussle (the project that I posted a post mortem about) where I provided about 85% of the script for. below is a link to the project repository and a list of the scripts I made, with an explanation of their function and effectiveness.

These scripts are not an example of my best work, but more an example of what I am capable of under adverse conditions with minimal time available.

1

link to the titan tussle repo

AudioBehaviour

This was set up to behave as a single game object that would contain all of the audio sources in the scene. These audio sources would be kept in lists, and used pooling to avoid creating too many audio sources at once, or the need to destroy ‘one shot’ audio sources as I had in previous projects.
This script contains a public function to be called by any other script when they need an audio clip played, asking for an index range (and a bool for looping the sound, which did not end up making it in).
This function picks a random number in this range to find the index number for the desired clip, accessing the first level of a 2D list of audio sources with it. It iterates through that list, looking for the first audio source that isn’t currently playing and tells it to play. If it fails to find one in the list, it creates a new audio source component, sets its audio clip to one found in a list of audio clips using the same index, sets its volume and adds it to the 2D list, telling it to play.

This method removes some overhead with garbage collection, moves all the audio into one place, allowing easy control of each sources’ variables (like reducing the volume of each clip created in the same frame, or within a set time of the previous one, or applying a global volume level). I chose this method as I was not aware that you could play multiple clips from the same audio source component without them cutting out the currently playing clip.
It is not easy to use, however, as if you want to add a new clip into the middle of the array of clips, you move every clip after it down the list, requiring you to update every index range in every other script that calls on this, which is hard coded. This makes it difficult for use by anyone who did not make your script, or the project team whenever the audio list is updated.

The list of audio clips and the issue of adding in new clips forcing a remap of all the calls to this script could be avoided through using another 2D list, requiring only a single index number, placing the multiple possible files into these lists and the use of “unity typesafe” to automatically make available any new audio asset in script, and add them into these lists on play. Any audio dropped into an appropriate folder would then be placed into the audio clip list already in use, the random range would include it in its roll and no index numbers would need to be updated. Through use of strings as indexes, you would not even need to be aware of the correct order of the audio folders, just the name of the folder, easing use for both programmers and designers using/calling this script.

ButtonManager

This contains the behaviour of each of the title menus and the scene camera. I wanted to add something fancy to the title, so decided instead of fade in/out of canvases or scenes, or just changing the displayed text, to have canvases displayed in world space and move the camera itself to each new location. This has three states, one for each canvas, in which the controller inputs do different things. The title and credits just change the camera’s position, but the ‘pregame behaviour’ (or character select screen) is set up to help each player determine which character they are controlling, by asking each player in turn to confirm readiness. As they do, an icon of their titan (bordered by their team colour) is brought to full opacity. This did not work very well, as every player would mash their buttons at once. This could be fixed by instead allowing players to select which titan they want to play as, removing the possibility of all players just hitting the same button, and would allow players to form their own teams.

CamelBehaviour

A fairly simple script, It keeps track of player positions, finds the closest player and after a random time in a range of 1-10, adds force to itself in the opposite direction, playing an audio file when it does.

It doesn’t behave much like a camel does, as camels don’t normally launch themselves 50 meters into the air.

This should have instead used a navmesh agent or at least tried to move towards a created waypoint, and I could have asked for a walk cycle animation for the model.

2

CameraController

This carries a camera shake function, object fade and also keeps the camera focused on the center of the action.
The camera movement worked by keeping a list of the players and every frame calculating the distance between the furthest apart characters, by iterating through each character, determining its distance from each other character, adding that distance to a list and then sorting that list.
It also found an average point by adding each of the character positions together and dividing that position by the number of characters.
The average point was used as the camera’s position, and the camera was moved backwards by the max distance (clamped to a minimum and maximum) which was applied to the camera using linear interpolation.
This used to have the camera rise up with distance and rotate to look at the average position also, but created an issue where the titans looked very small and were hard to track as the camera moved further out (ending up looking down at the scene).

The object fade is a trigger for the operation in the obstacle script where a ray is drawn from the camera to each character, and if it collides with an obstacle on the way, runs its fade out function in its obstacle behaviour script.

The camera shake is run each frame if the amount of shake desired is above 0. the desired amount is reduced by Time.deltaTime every frame and is clamped to a maximum amount. The camera transform is moved by a random range of -desired amount to +desired amount, in the x and y-axis. The desired amount is added to by calling the public function ShakeCamera(desired amount). This function is simple, the desired amount is easily tweaked, it doesn’t run when it is not needed and was simple to put together and use.

In its entirety, the script is simple and effective, without being too expensive. It is using tags to find each character and stores a reference of them in its own list, but it does not search for these on start, instead requiring the game controller script to call its FindCharacters() function after it has completed Instantiating them, to avoid getting null references and allowing these characters to be removed or added into the game.

CharacterControl

This script is messy. It controls all the different actions and behaviours each player can take with each type of character (Large and Small titans). It keeps the player number info, finds and stores the correct gamepad device, Displays the character direction and attack UI element (displayed in world, not on a canvas), handles changing the character’s material colour and sets triggers in the characters animation controller.
It contains the different movement and attack behaviours for each type of titan. The large titan can only move through attacking, but can always rotate. this rotation speed increases over time while the attack button is held down. The target UI plane is turned on at the beginning of a charge and turned back off once an attack is released. The attack itself uses transform.translate to move the titan by its move speed towards the target position, which has an issue with overshooting or getting stuck, so there is a timed end to the attack, and a range within the target that will also end the attack, however, these issues still stand. The charge overshot could be fixed by just using a timeout based on how far we want to move, and getting stuck on objects could be fixed by ending a charge if our position has not changed by a certain distance since the last frame.

The small titan has the ability to move and attack. The movement went through three iterations, first strafing forwards, back, left and right with the left stick and rotating by pulling left or right on the right stick, which had the problem of being too slow and confusing. This was changed to a geometry wars style, where you still strafed with the left stick, but changed facing direction with the right stick. This was less confusing and responded much quicker, but meant that when the animations came in, you could face in the opposite direction you were facing. The controls were then changed so movement and facing direction were controlled by the left stick, so you were always moving forwards, which lined up with the animation. This allowed the use of the right thumb to attack while still being able to position the titan, also conforming to the control scheme of the large titan, easing the use of both.
The small titan attack performs an overlapSphere operation directly ahead of it, ignoring itself and calls the stun function in this script on any affected titan characters (checking for tag).
The small titan also has the ability to collect a BigShot powerup. If they have collected it, and attack, theyInstantiate a prefab projectile in front of them, and turn off the UI to display that they have the powerup.

This script also handles the collision behaviour of the titans, mainly calling the match controller script when they fall out of bounds, hitting and destroying obstacles, hitting other titans while stunned and the large titan charge attack collision behaviour (adding force to another titan in the opposite direction of the collision).

Other than the issues with the charge attack overshooting, this script also has issues with the triggers for the animations. These trigger timings cause the animations to not seem very smooth, either playing the animation too late or flicking between several at once and also have a problem of getting stuck into them. This script could have been set up as an FSM, which could have avoided a lot of the messiness of this code and made it easier to fine tune the animation transitions.

DustBehaviour

This script was set up as an alternative to a particle emitter, as I could not place a sprite animation sequence into the built in unity particle emitter system. This setup uses a rigid body component to have gravity act upon it, billboards the object, interpolates the colour to clear/black and destroys the game object after a timer hits -3. This is a very expensive way to handle this, as the obstacle Instantiates one of these every frame for ~3 seconds as it is destroyed, creating around 120 new game objects over that time, adding force in a random direction, which are then destroyed 4 seconds later, generating a fair amount of overhead through garbage collection.

This looked pretty nice with the animated particle, but they were also fairly small and hard to see the animation during gameplay.

This should have instead used the pooling method, with an effects controller to store the pool. It should also not have used a rigid body component, and instead followed a bunch of adjustable curves over its lifetime.

GameController

This script handled the spawning of the titans at the start of each match, figuring out the appropriate model and behaviour to be used for each spawned titan. After completing this, it calls the camera control script, asking it to find the titan characters to begin following them.

This function doesn’t do too much but was planned to be used to carry across information on which player chose which titan (when the plan was to have multiple available) and which map to use.

MatchController

This keeps track of team ring outs, holds the match timer and respawn timers, removes sections of terrain after enough time passes and handles the end of the match. It used to attempt to fade out a character’s material once it had hit the boundaries of the arena and ‘died’, but using the new shader system in unity 5 does not allow a solid shader to fade out to transparent. This could have just been switched from opaque to fade through code, though, this approach would also be useful for the obstacle fade behaviour.

It also changes the text in the UI, including the displayed match timer, winning and match information text and each team’s points towards winning.
This, along with most other scripts here, makes heavy use of ‘findGameObjectsWithTag’, which I have been urged not to use as it is very easy to break this functionality by changing the tags or just misspelling the tag in the script, which has no auto complete to help remove these mistakes. I have since found out that using ‘findGameObjectsOfType’ is a simple way to work around this, with the added bonus of not needing to play around in the editor to complete the connection of these scripts.

ObstacleBehaviour

This handles the obstacle’s behaviour when it is destroyed, where it slowly falls down through the ground, spawning the animated dust particles, playing sound based off if it is a building or camel and also has a fade out function, to fade the model to 10% opacity when it is obscuring the camera’s vision of a titan.

The game object is destroyed after its health is reduced to 0 (purely so the pyramid is not instantly destroyed) and a timer is reduced to 0. While the timer counts down, every frame, a dust particle is instantiated, and force is added in a random direction and strength. This is also done in fixed update. This is the messiest and least efficient way to create an already expensive game object, The least that could be done here would be to create a variable that controlled both the amount created, over a set time and to give the option of ‘bursts’ as are found in the particle emitter system.

The fade out function is not very good, every frame that it is called, it sets a bool to true, which it then checks if it is true, and if so, fades out (from its material’s current colour to clear), if not it fades back in. It then sets the bool back to false. On my laptop, this worked fine, but during playtesting it caused the buildings to flicker at a high frequency. The easiest fix would be to apply a half second timer to the bool being set back to false, but this doesn’t really remove the problem, just hides it behind a timer. A nicer solution would be to have a fade in and fade out function to be called, where if the function to fade in is not being currently called, the camera script, upon its ray cast no longer hitting this game object, would call the fadeIn function.

ProjectileBehaviour

This handles the projectile’s movement, causes camera shake, lowers the scene’s main light intensity and behaves like a large titan charge attack with increased strength. The collision behaviour was just copied from the character control script, as I knew that already worked. The movement is handled using move position to help avoid tunneling. The projectile lives for 7 seconds, lowering the light intensity for the first 2.

I have not come across any issues with this behaviour yet, but as it has such a small time to exist in the game, it is hard to test for bugs. It does cause issues with characters tunnelling through the ‘death box’ boundaries of the arena though. This could be avoided by hard-coding the boundaries.

UIContainer

This was a container created to be used in a prefab, for the MatchController to grab the appropriate UI text from.

 

A semiotic analysis of SOMA

SOMA’s main theme displays Derek Parfit’s argument on personal identity (Parfit, 1987), specifically ‘Relation R’ and to explore his idea that it is necessary for society to protect an individual and an individual’s future self from harm, including self-harm. While he does not explicitly endorse invasive control, this game exhibits that scenario in an extreme.
It also questions the morality of euthanasia, specifically quantity of life over quality of life.

This is a problem you are presented with throughout the game, as it works the difficulty of this question up, from “someone is blocking your path and you don’t know they are a human” to “would you kill your previous self?”

This first example is set up to make the player question whether or not they have just killed a human. The player enters the room, understands that to move forward, they must unplug a robot. the robot itself does not respond to the player speaking to it, but instead looks at its own hand, as if it is self-aware. There are two plugs powering the robot, it responds, with a female voice, “no, don’t…”. The player still cannot progress forwards, leaving the only option to pull the final plug. The robot asks “Why? I was okay. I was happy.” and it’s lights fade out.

This is a heavy moment for the player, as they are confronted with the consequence of their actions having taken an innocent life.

The physical representation of this image is a damaged bipedal robot, with only one leg and arm. There are tubes pervading its structure. The text of this image is meant to be interpreted (and represent) a damaged woman, kept alive through invasive life support. The player has essentially stumbled into a room and without understanding what they are doing, ‘pulled the plug’. As the robot woman does not speak to you before you harm her, she reflects a coma patient, in that there is no way to know for sure how they feel.

In this moment, the player has not euthanised this woman. The players choice was not to end suffering, as there is no indication that she was in pain. They blundered in and committed murder to progress towards their own goals.

The next two encounters no longer require you to kill a being to progress, but instead offer a safer future for doing so. There is no reward for taking the difficult path. These encounters also allow the player to find some information about their choice before they make it. These people are not in a comatose state and respond to the player, with their own desires to live.

The first one is the top half of a bipedal robot, with a man inside of it, who is unaware of and unable to realise that he is in a robot body. You find his human body near his location but are unable to tell him about it. He only asks you to find him help, as he is aware that he is hurt. You cannot kill him, to progress forwards you can either turn off his power, causing him immense pain or release a dangerous monster into your current location that you have to sneak around.

This is the second robot person the player speaks directly to, but the first that has any wits about them. He expresses a desire to be saved, asking you to find others. He tells you his name, Carl

The most apparent option available is to turn off the power in Carl’s’ room, which causes immense pain to him. This is displayed through his screams, begging the player to stop, that he can’t take it anymore, and just crying. the room goes dark and electricity arcs across his body, a red light flashing above him. The player thinks that he will eventually die, leaving to complete the process of opening the path ahead of them. This causes the player to move past Carl a few times. Carl is alive and screaming each time, as he does not die in this current state. The player realises that this suffering that they put Carl in is infinite.

While a player may not understand it at this point, the human personalities inside the robots are ‘brain scans’ of the original human and there is a question over whether this could be considered as a soul. If this is true, then Carl’s soul is being forced to endure searing pain, for eternity, through the player’s actions. The player has placed Carl in his own hell. While this hell is a literal one, the player must understand these symbols to realise exactly what they have done.

The next encounter is not with a robot, but with a human, named Amy. You walk into a room to find a woman lying against the wall, with tubes throughout her and plugged into a panel to her left, just like the very first robot you encounter. There is also a set of grey, mechanical lungs perched just behind her, breathing by themselves. They can be defined as lungs, as they have the same general shape, inflate and deflate and a mechanical sound of gas being pumped (very much like a bike pump, sounding slightly plasticky, along with breathing noises, like a lighter Darth Vader). There are also tubes connected directly from the artificial lung into the woman’s chest.

This is where the reality of the player’s situation sets in, where the gravity of their choices should come to the forefront of their mind. There is no ambiguity here, no misinterpretation possible. The choices you make are affecting humans. This is a woman, asking you not to hurt her, kept alive by machines. The player must remove one or both plugs keeping her alive, the first showing the player that she will die if both are removed, but is required to power the ‘safety systems’ on the path ahead.

These three encounters asks the player to question their ideology of euthanasia and their idea of quality of life. Clinton R. Sanders covers the cultural construction of euthanasia, stating that in human medical settings the debate over euthanasia generally focuses around whether the sanctity of life should or should not be valued over the quality of life. Giving primacy to the former value leads to a rejection of “mercy killing” while the quality of life position acts as a foundation for medical personnel allowing or actively assisting death in certain circumstances (Sanders, 1995).

This argument over quality of life is set up with the option of leaving Carl in a state of living hell. When the player is presented with the third situation, they must choose between sanctity of life or quality of life. Near the end of the game, the player is asked again, except the person asks you to end them.

The first thing Amy says to you is “don’t hurt me”, then “it won’t let me die, nothing is allowed to die”.

She is referring you to the WAU, an AI system created to operate and maintain the air and life support systems on the deep sea research facility that you are on. It does not think and its main directive is to preserve the life of humans, but after a cataclysmic event wiped out all life on the surface of the planet, the WAU began to overcompensate by not allowing any of the humans to die on the station, forcing life back into those who have lost it, leaving them as corrupted monstrosities (usually) fused to the floors and walls, or taking brain scans of people and placing them into machines.

These actions are an extreme example of the quantity over quality of life, showing the problem with Derek Parfit’s reasoning that it is morally wrong for one person to harm or interfere with another person and it is incumbent on society to protect individuals from such transgressions. That accepted, it is a short extrapolation to conclude that it is also incumbent on society to protect an individual’s “Future Self” from such transgressions (Parfit, 1987). Instead of society protecting you from choosing to smoke, causing harm to your future self, the WAU protects you from death by not allowing you to die.

It also has no way to comprehend quality of life. most of the monsters you encounter throughout the game are just earlier attempts at placing a human consciousness inside a robot or dead human body. Most of these attempts left the consciousness in an insane or damaged mental state, including dementia (with extreme fits of anger, including intense, desperate screams), addiction (shown with desperate begging for your structure gel, which quickly escalates into violence, and desperate searching if the player is not noticed) and Alzheimer’s (by talking to people who are not there anymore, seemingly stuck in past memories). These are signified as a text, through linguistic, behavioural and aural methods.

These examples are built to set the player’s frame of mind for two of the hardest decisions in the game, euthanizing an active person, who wishes for death rather than succumbing to the WAU and whether or not you should kill your original self. The latter option has you copy your consciousness into another body to progress, when you wake up in it, you are confronted with your previous body. it is unconscious, but will wake up. There is no threat from it, nor is it blocking your path, but it will be stuck there in that room, with no company. There is no risk or reward for either choice.

Parfit explains that a “Relation R”, a psychological connectedness, including memory, personality, and so on (Parfit, 1987) should be treated by yourself as if it were yourself and so, the other you that you stand in front of should be treated as yourself as well. Therefore, the choice you are given is to kill yourself, to avoid your future suffering or allow yourself to live alone forever.

This game shows the worst case scenario for quantity vs quality of life, showing us the problem with each extreme, that in some cases we cannot be aware of the needs or desires of a person, or the horrors that forcing someone to stay alive can produce. The main problem with such difficult issues is ignorance. Unless you have yourself experienced this exact situation, you should be unable to make a decision, or even to form an opinion on the subject, yet people do. This game gives the player the opportunity to gain some insight, enough to understand its message, that “it is complicated”. No encounter offers a morally righteous path, for example, if you do not leave Carl in his own hell, he asks you to find him help, to seek out Amy, who is fused to the wall and those lungs. If you leave her alive, she asks you to find others. You can’t save these people, no matter what you do. They have a terrible quality of life and will be stuck there forever. Your only other option is to kill these people but some of them don’t want to die.
That is SOMA’s message.

BIBLIOGRAPHY

Parfit, D. (1987). Reasons and persons. Oxford: Clarendon Press.

Sanders, C. (1995). Killing with kindness: Veterinary euthanasia and the social construction of personhood. Sociol Forum, 10(2), 195-214. http://dx.doi.org/10.1007/bf02095958

Playtesting reflections and post mortem

Last week my team and I presented our game Titan Tussle for playtesting, this is my findings on our notes and feedback from that.
People found the balance of each character to be fair, each had their strengths and weaknesses (usually attacking created vulnerability) and most saw that teamwork would be required to successfully take down an enemy.

The main issues people had were:

Figuring out how to play (no one read the instructions, even when instructed to do so, it turns out everyone hates them and are then disappointed in the game as they did not know what to do) and players did not understand the objective of the game.
This means that players either need to be forced to read instructions (something very simple, like ‘Knock out the enemy team!’) or be showed some graphic on how to play a game, like a simple or animated image, or a simplified round. Pressing/holding the A button could be required to begin the game also. The original idea had the players choosing their character, where some of these options could be used to explain play to the players.

Players were unaware of teams.
Several set-ups were planned for the game that had not made it into this version yet, like the colour themes for each character reflecting their team and players choosing their characters (where each team will be displayed in this menu). Another brilliant suggestion was team colour outlines on the titan models and on their respective icons at the top of the screen.

They found the controls for the small titan confusing and found the small titan too weak.
The control issue was my own stuff up, I forgot to reverse the input value on their turning, which made them overly complicated. As for them being too weak, there are a few values that can be played with to fix this, like reducing the time they are busy attacking to be much more than the stun time and increasing the range of the stun attack. Another thing that will help is the visual feedback of animating the attack and adding some ‘swipe’ effects like you would find on a sword swing.

There are also some serious visibility issues that need to be worked on, like the difference between fading out an object so a titan can be seen behind it and destroying the object, and also how to better handle distant titans, as their abilities and facing directions can become hard to see when they only take up 1% of the screen.

This is my post-mortem of the project so far.

What went right
Team Management of animators and quality of work from the animators.
This was due to a great work ethic on their part and through great communication, we were able to figure out what the amount of workload they were each capable of. We set up a task sheet for them, with broken down goals and assigned tasks to them there, while passing out deadlines as we were made aware of them. We also assigned a team leader to the group of animators to help keep them on track.

Got a working game loop set up in time for the play testing session.
This is less than I have done in the past but is an achievement in the face of the struggles our project had leading up to it, namely multiple failures in source control and hours of work lost, and the hours of time needed to repair the project. I was able to prioritise the functions and mechanics that were core to the game through the intense development and iteration processes that our project had undergone in the previous 3 weeks and when I was lost, was able to go through the documentation that we had set up to help identify the next jobs I had to do.
The assets the animation team had provided also helped give me direction, as I felt it necessary to implement and show off all the work they had put into this project.
This shows why it is necessary during a project to have all hands possible take part in the design, iteration and testing processes, as it helps form the game in their mind and helps them create the game envisioned by the team, even when everything is failing.

What went wrong
Source Control, Documentation, Meetings, Team management of everyone else, Parts of code broken

why
Source control:
I didn’t know enough about it to properly set up a new bitbucket project & didn’t think of that as an issue. This was a lack of knowledge in the tool and in the consequences, as I thought just setting up a gitignore file was enough. I failed to set up the file structure correctly, was not aware of the correct contents of the gitignore file and did not know how to set up the unity project either. What I needed to do was research the subject, or even go to a lecturer at SAE to walk me through it. Since becoming aware of the depth of this issue, I have set up a meeting with Ian McManus to help walk me through this problem and to also create a video of this process to be shared with my colleagues and anyone else who is struggling with source control.

Didn’t do anywhere near enough documentation, specifically a Gantt chart, risk assessment, failed to complete an HCD or GDD of good quality, and haven’t yet completed a TDD.
This documentation were planned to be set up and worked out as a group during face to face meetings, however, our team failed to show up to these meetings and the documentation either suffered or were never created. They further suffered from a lack of enthusiasm in our whole team for the project. We also suffered in communication, as the team leader it was up to me to push for our team to work together and get everything done to a high standard. I was unable to communicate with my team at most times and feared that pushing my team to hard would seem like I was asking for more than I was doing.
There was little to no team management from myself, attempts that I made to document tasks were not maintained and barely followed up, some team members are only contactable on facebook.

Due to a failure in source control, and not creating a local backup, and failing to save regularly, a unity crash lost hours of work, and when it tried to recover data some code was broken without throwing an exception. this meant that the main mechanic (titans knocking around other titans) was not in the backup build presented during playtesting.
In the future, working locally or through source control, I must stick to a schedule for saving and backing up data. I only missed the issue with the main mechanic being broken because I was very tired and out of time to work on the project anymore, but learning how to correctly use source control and saving more often should help to reduce the chance of such a bug getting past me again.

What I learned from SOMA

First of all, SPOILERS. This whole post is spoilers, so go and play SOMA first, if you haven’t yet, I highly recommend it.

The story felt compelling, interesting and unobtrusive. This was achieved by not removing control from the player during dialogue, except for the beginning dream sequence cutscene, which is about 30 seconds. You wake up in your apartment, answer a phone and are told that you have to find and drink a bottle of tracer fluid, and then make your way to an appointment. The apartment is the perfect safe zone for the player to learn the controls and basic mechanics of the game (find the thing, use the thing. This covers every objective in the game, along with: find the exit and avoid the baddies). The next scene provides you with an option to answer or decline a call, showing the player that they have options. These options were fairly infrequent throughout the game and I found that they did not seem to have any consequence at all, even the large one at the end where you choose whether or not you kill the last human or killing your own copy. I did only play through once, but these choices I made, along with others, never came up in dialogue again.

That having been said, the story itself was fantastic, although that may just be because I am interested in high science concepts and their philosophical repercussions.

The use of light to direct the player towards objectives was often very strong in this game, keeping that in mind during play made finding my way around very simple and helped lower my stress, although I had to make the conscious choice to look for these areas at times, as there were some areas with a lot of other sources of light, or they were obscured by scenery, however these areas never featured time constraints, giving me the time I required to figure them out.

The anxiety/boredom flow was used pretty well in this game, safe areas in the early game felt very safe at all times, but in later parts of the game had constant creepy or dangerous noises playing to make those areas feel much less safe than the earlier ones.

SomaPC12There was a small problem with the increase of enemy difficulty, where I moved from one area with an enemy that teleports around, and kills you if you look at it (which could see and hear you) and kills you if you are too close to it, to an area with an enemy that could not see you and you could look at, that seemed to only respond to sound. This was an enemy that was less dangerous than the previous one you encountered, in an area that you had more ability to move around (the previous was in a sunken ship, with tight corridors and was completely flooded so it felt like you had less move speed. You were expected to find your way through the ship and although the level itself was fairly linear, you had to spend most of the time not looking around or moving as quick as you can through the level, making it difficult for the player to map out the area. In contrast, the next level was just very dark. It was also a bit maze-like, but because of the nature of the enemy you had plenty of time to take the area in and get your bearings, not to mention the darkness meant that the use of lights to illuminate the goal were very obvious in contrast.

This situation could have been used to allow the player more confidence in themselves and may have been required to keep players interested. I myself felt quite hopeless when facing the previous enemy, if this difficulty had continued trending upwards, I may have given up. The problem I had was that there was a severe build up of this second monsters difficulty, much more than the previous, through constant ambient noise and story elements. This monster did not really need to be less difficult than the previous one though, as there was a whole level in between these monsters without any threat and much less ambient build up of stress.

355020960I noticed the possible use of an FSM in one of the enemies AI when I got it
stuck in one of its states. From what I could tell, it had 7 states; Idle with / without target, Patrol, Search for not – visible target, Search for lost target, Found target – Submissive / Aggressive behaviour. This particular AI (the small corrupted submarine with red lights) seemed to have a medium range of vision and hearing (you could sneak behind it but not run). If it spotted you, and then lost you, it would move to the location it last saw you, move around the area (possibly towards sounds made by the player?), then eventually return to its last position in its patrol (unless it heard or saw you). If spotted, the AI would move towards you, but in a submissive state, would attempt to keep a short distance between itself and the player (the player has a faster move speed than it). It had an extensive list of dialogue audio clips, in this state it would beg the player for their ‘structural gel’ (reinforcing the recent discovery that the player was not human). After a short time, the AI would move into the aggressive state, and advance on the player, attempting to collide with them. This was accompanied with aggressive dialogue and a change in the model (tentacles erupted out of its hull, reaching and wriggling towards the player).

I somehow caused the FSM on this AI to fall into its submissive state, but fail to move into its aggressive state (it just sat there begging me for structure gel). I’m pretty sure I was crouching and half hidden at the time, but I somehow caused its timer to never count down or to go outside its expected range, or possibly it skipped the exact number it was required to hit to move state, but that’s very unlikely. I held it there for a few minutes until I decided to move towards it, this caused it to move straight into its aggressive state and it killed me.

I hadn’t had any other issues with the AI in this game, so I believe that this was a freak occurrence and therefore nothing to worry about. This is also something that would be picked up in rigorous play testing.

The ending felt a little strange to me, as the copy of the player that was left behind could make its way back to the other sites, with Catherine’s copy (your AI ‘friend’ throughout the game), and just continue on with their lives, maybe working on the WAU to become something less horrible. I also don’t understand why the whole site did not try to continue the human race (and maybe nip the WAU in the bud, before everything got so nasty) and instead chose to only preserve the brain scans of a few people for a few hundred thousand years instead. This is just a prolonged but now inevitable death.