Huw Talliss
Undergraduate Computer Scientist and Game Developer

BossAlien Internship (Summer 2017)

Games Programmer Internship

I worked at BossAlien for three months over the summer of 2017. I had an amazing time there, the work was interesting and the team were so nice and helpful. I worked on the infrastructure team and learnt so much. I had little experience with AWS and cloud-based architecture so everything was very new but I managed to pick things up quite quickly and ended up working as a fully-fledged team member.

I worked as a full-stack developer and so used many different languages and systems: PHP, Unity C#, HTML, Javascript, CSS, JSON, AWS, Git, SVN and others.

My main accomplishments during the internship were:

  • Implemented client-controlled server log verbosity system
  • Maintained and improved deployment and build distribution tooling
  • Created and released project-agnostic player-state snapshot tool
    • Implemented support for this tool into CSR2 and an unannounced game
  • Supported the wider dev team on tools/operations related issues

BossAlien was an amazing studio to work at. It always had a great atmosphere and was very chilled and laid-back. I learnt a lot both technically and also about the structure/running of a game studio, it was really valuable experience. I want to thank BossAlien and Natural Motion for the opportunity!

Intersect (2017)

Rising Star Competition Game - Intersect came first in round two

I made this game for the 2nd round of the Sumo Digital Rising Star Competition. I was one of five finalists and came first in round two with this game.

Gameplay Recording



For the second round of the Sumo Digital Rising Star competition, contestants were given a started unity project to build upon to make any game they wished. I created this game, Intersect and it came first in the round.

The games were marked by industry professionals and I received three pieces of feedback for Intersect:

  • Judge 1: Jezzball inspired - difficult/overly precise input mechanics, really really nice audio effects, generally nicely polished/shippable, online scores!

  • Judge 2: Solid implementation of a well-established game style. It would benefit from clearer communication to the player (either at the start of the game or via the tutorial) that lines initially must be drawn between the borders of the screen. The game would benefit from some more work on polishing player reward for key achievements - e.g. having effects and animations when you achieve a good score, etc.

  • Judge 3: Very fun and original. I have no remarks about the code, everything seems fine. Only use of http requests and server data in my group, very impressed!

I'd had the general ideas for the game in my head for a while. I remembered playing a flash game or something many years ago but I had no idea how I'd find it again to reference so I just worked from memory as to what the mechanics were, remembering more about separating the balls than taking area. Over time i realised I'd misremembered the mechanics and so began focusing more about the area capture mechanics over the separating balls mechanics.


"Left-Right Algorithm" Write-up - Custom Algorithm

The hardest part in making the game was working out how to calculate the area that the player has cordoned off each time they drew a line. In theory the player could draw polygonal areas with an arbitrary number of sides, correctly identifying the area they have created and colouring it in was quite difficult.

I spend a good few days near the beginning talking to friends to get ideas on how to accomplish this task. I ended up combining several ideas together to create a general outline for how the algorithm should work. I referred to the algorithm as the "Left-Right" algorithm due to how it checked the left then right sides of the line.

The key points
  • Every line draw by the player would snap to the line grid, ensuring all the lines were connected
  • Whenever the player finished drawing a line, the algorithm would first run to find the area on the left side of the line, then the right side
  • The key idea was to slowly build up the polygonal area one vertex at a time
Area Calculation and Creation
  1. We iteratively explore from the start and end vertices of the drawn line
  2. Each iterative step takes a starting vertex and attempts to find the next vertex along the line the starting vertex is resting on
  3. Using this, we build our polygon from both ends of the drawn line at the same time, stopping when both ends meet
  4. We now have the set of vertices describing the polygonal area that has been cordoned off
  5. We can then split this polygon into triangles so that we can easily calculate area and draw it to screen
  6. We then check that none of the triangles contain a ball. If they don't then the area can be added to the total cordoned off area.

/// <summary>
/// Finds the vertices that make up the area the new line is cordoning off. Implementing the Left-Right Technique I created
/// </summary>
/// <param name="startVertex">The start vertex of the line</param>
/// <param name="endVertex">The end vertex of the line</param>
/// <param name="newLine">The new Line</param>
/// <param name="lines">The list of all lines</param>
/// <param name="direction">The direction to be checking in relation to the new line. (perpendicular to the lines original vector)</param>
/// <returns>List of vertices</returns>
private List<Vertex> FindVertices(Vertex startVertex, Vertex endVertex, GameObject newLine, List<GameObject> lines, Vector3 direction)
{
    // Define variables to help during the loop
    List<Vertex> startVertices = new List<Vertex>();
    startVertices.Add(startVertex);
    GameObject startPreviousLineTaken = null;
    bool startPreviousLineReversed = false;

    List<Vertex> endVertices = new List<Vertex>();
    endVertices.Add(endVertex);
    GameObject endPreviousLineTaken = null;
    bool endPreviousLineReversed = false;

    bool updateStart = true; // Controls whether to update the start path or the end path this loop
    int numberOfLoops = 0;

    // Loop until the start and end point paths have met
    while (startVertices[startVertices.Count - 1] != endVertices[endVertices.Count - 1])
    {
        if (numberOfLoops < 20) // Limit the number of loops to a reasonable amount
        {
            // Update the start and end paths on alternate loops
            if (updateStart)
            {
                if (startVertices[startVertices.Count - 1] != null)
                {
                    startVertices.Add(FindNextVertex(out startPreviousLineTaken, out startPreviousLineReversed, newLine, lines, direction, startVertex, startVertices[startVertices.Count - 1], endVertex, startPreviousLineTaken, startPreviousLineReversed));
                }
                updateStart = !updateStart;
            }
            else
            {
                if (endVertices[endVertices.Count - 1] != null)
                {
                    endVertices.Add(FindNextVertex(out endPreviousLineTaken, out endPreviousLineReversed, newLine, lines, direction, endVertex, endVertices[endVertices.Count - 1], startVertex, endPreviousLineTaken, endPreviousLineReversed));
                }
                updateStart = !updateStart;
            }
            numberOfLoops++;
        }
        else break;
    }

    // Concat the lists after reversing the end vertices, removing the duplicate from the start of endvertices
    List<Vertex> FoundVertices = startVertices;
    endVertices.Reverse();
    endVertices.RemoveAt(0);
    FoundVertices.AddRange(endVertices);
    FoundVertices.RemoveAll(x => x == null);

    string logString = "Found Vertices: ";
    foreach (Vertex vert in FoundVertices)
    {
        logString += "[" + vert.GetVector3().ToString() + "], ";
    }
    Debug.Log(logString);
    return FoundVertices;

}

/// <summary>
/// Finds the next vertex in the given direction, a single step of the Left-Right technique
/// </summary>
/// <param name="lineTaken"></param>
/// <param name="newLine"></param>
/// <param name="lines"></param>
/// <param name="direction"></param>
/// <param name="originalVetex"></param>
/// <param name="fromVertex"></param>
/// <param name="towardsVertex"></param>
/// <param name="previousLineTaken"></param>
/// <returns></returns>
private Vertex FindNextVertex(out GameObject lineTaken, out bool reversedLineTaken, GameObject newLine, List<GameObject> lines, Vector3 direction, Vertex originalVetex, Vertex fromVertex, Vertex towardsVertex, GameObject previousLineTaken, bool previousLineReversed)
{
    List<GameObject> intersectingLines = new List<GameObject>();
    Vector3 towardsVector = Vector3.Normalize(towardsVertex.GetVector3() - fromVertex.GetVector3());


    // Get all the lines that pass through this vertex
    foreach (GameObject thisLine in lines)
    {
        if (thisLine != newLine && thisLine.GetComponent<LineScript>().PassesThrough(fromVertex))
        {
            intersectingLines.Add(thisLine);
        }
    }

    // Find the line that moves most towards the towardsVertex after ensuring the line's directions move with the direction vector
    GameObject smallestAngleLine = null;
    float smallestAngleLineAngle = 360;
    bool smallestAngleShouldReverse = false;
    foreach (GameObject thisLine in intersectingLines)
    {

        bool shouldReverse = false;

        Vector3 thisLineDirection = thisLine.GetComponent<LineScript>().GetNormalizedDirectionVector();
        float angleTowards = Vector3.Angle(thisLineDirection, towardsVector);

        // Only find whether to reverse direction on the lines we didnt take last time
        if (thisLine == previousLineTaken)
        {
            shouldReverse = previousLineReversed;
        }
        else
        {
            // Find whether the direction of the line should be flipped
            float angle = Vector3.Angle(thisLineDirection, direction);
            float otherAngle = 180 - angle;

            bool shouldReverseAngle = false;
            if (otherAngle < angle)
            {
                angle = otherAngle;
                shouldReverseAngle = true;
            }
            else if (angle == 90) // If perpendicular to direction, make sure we find out whether this line is pointing up or down
            {
                if (thisLineDirection != Vector3.Normalize(towardsVertex.GetVector3() - originalVetex.GetVector3()))
                {
                    shouldReverseAngle = true;
                }
            }



            // Get towards angles
            bool shouldReverseAngleTowards = false;
            float otherAngleTowards = 180 - angleTowards;
            if (otherAngleTowards < angleTowards)
            {
                angleTowards = otherAngleTowards;
                shouldReverseAngleTowards = true;
            }


            if (previousLineTaken != null)
            {
                // Take the shouldReverse of the smallest of the angles
                if (angle < angleTowards)
                {
                    shouldReverse = shouldReverseAngle;
                }
                else if (angleTowards < angle)
                {
                    shouldReverse = shouldReverseAngleTowards;
                }
            }
            else
            {
                shouldReverse = shouldReverseAngle;
            }

        }

        // Check to see if this line has the smallest angle so far
        if (shouldReverse)
        {
            thisLineDirection = Quaternion.AngleAxis(180, Vector3.up) * thisLineDirection;
            angleTowards = Vector3.Angle(thisLineDirection, towardsVector);
        }

        if (smallestAngleLine == null || (smallestAngleLine != null && smallestAngleLineAngle > angleTowards))
        {
            smallestAngleLine = thisLine;
            smallestAngleLineAngle = angleTowards;
            smallestAngleShouldReverse = shouldReverse;
        }

    }

    // Now i have the line to follow and the direction in which to follow it, need to get the next vertex on that line in that direction to return
    Vertex nextVertex = null;
    if (smallestAngleLine != null)
    {
        nextVertex = smallestAngleLine.GetComponent<LineScript>().GetNextVertex(fromVertex, smallestAngleShouldReverse);
    }

    if (nextVertex == null && smallestAngleLine != null)
    {
        smallestAngleLine.GetComponent<LineScript>();
        smallestAngleLine.GetComponent<LineScript>().GetNextVertex(fromVertex, smallestAngleShouldReverse);
        Debug.Log("UpdateArea: Couldn't find next vertex");
    }

    lineTaken = smallestAngleLine;
    reversedLineTaken = smallestAngleShouldReverse;
    return nextVertex;
}
                    

Global Leaderboard

One of the suggested features for the game was a leaderboard so the day before submission I decided to add one. I decided if I was going to have to faff around with reading a local file I might as well make a global leaderboard using a website api to add and retrieve. This feature ended up taking the entire day (which seems obvious in hindsight). I created a simple node.js app that would store the top 10 scores, storing them in a mongoDB database. The client would be able to get and post to the website to get the top 10 scores and post it's own score to the leaderboard if it beat one of the top 10.

Setting up the leaderboard server and web requests was relatively straightforward (I had done most of this a couple of years previous in my event planner project), so I managed to do it quite quickly. A large portion of the time to implement the leaderboard was spent struggling with Unity's GUI system. I had great difficulty making things line up nicely.

The global leaderboard functioned well and had the desired effect among my playtesters, many of them played the game multiple times in a row, trying to beat another person's score, adding additional replayability to the game.


Music and Sound Effects

I had two initial ideas for the music, one was a traditional approach - a calm, laid-back song playing in the background. The other idea was for the music to be created "live". To make the music to be based on what's happening in game by attaching the notes to the balls colliding with a wall.

I went with the second approach, but inn order for the music to not get boring I couldn't just use a single chord for the whole game. Instead I chose to have the chord change every time a line was successfully drawn. Whenever a ball collided with something it would pick a random note from the current chord to play and when a line was started or finished it would play the root of the current chord (though an octave down from the ball notes).

This system worked very well and was very pleasing. A nice upshot of attaching the notes to the balls is the relatively random timings you would get between notes. As you progressed through a level and cordoned the balls into smaller areas or played levels where the balls moved faster, they would collide more often and so the time between notes would decrease. This helped to increase the intensity of the music as you got to harder levels or got closer to finishing your current level which was a nice bonus.

I'd like to thank my friend cesque for providing the audio clips for the game.


Dev Images

MEng Final Year Project (2017 - 2018)

"What's it like to be a bat gamer?" - Exploring the effect of audio on immersion in games.

I am currently working on my final year project at York, supervised by Paul Cairns. The project consists of a literature review, a experimental study, a presentation and a 55 page report.

The aim of the project is to research into how audio affects immersion by creating a game that can be played in multiple modalities (audio-only, video-only and both) in order to perform a study on how immersion is impacted by these different modalities. As part of this project, I am also writing a literature review as part of my project report which covers the current state of research into this field (including both examples of games that use audio as an important modality and formal literature).

Game Prototypes

The first thing to do was to prototype a few games that would work equally well audio-only and video-only. These three protypes were:

  • Bat Pong
  • Bounce - Made it past prototype
  • Simon (call and response rhythm game)


Bat Pong - (Unreal C++)

The idea behind Bat Pong was to create a pong-like game, adjusted so it can be played audio-only by making the bats and balls emit a constant sound with a pitch that varied based on the position of the object in the y-axis.

I decided to use Unreal C++ to prototype this to both gain experience with Unreal and because I could get low-level access to the audio buffer to send it generated sound data. I learnt a lot during creation of this prototype, having not used Unreal much before.

We decided not to pursue this game concept further due to the difficulty in audio-only play. In order to improve audio-only play, the video-only play would be severely hampered by a slow-moving ball or large paddle size, making the game too easy.

Prototype video (headphones recommended)


Bounce - (Unity C#)

A rhythm game based on the Rhythm Heaven series of games. The concept is that the player must enter their input in-time with the music, as the ball reaches the centre.

I decided to make this in Unity C# due to time constraints. I am more familiar with Unity and it allowed faster iteration times.

The difficult part of this game and of the Simon game was in ensuring timing stayed consistent, the game needs to stay in time with the music. I used the dsp time that is provided by Unity, an integer that ticks up with the time of the audio driver. Using this value and a coroutine, actions could be reliably performed in-time with the music (as long as the beats per minute value was set correctly).

In order to orchestrate all the timings for when balls should appear and bounce etc. I decided to used a data-driven approach (something I hadn't done before). I used the ByteCode programming pattern from " Game Programming Patterns" to facilitate this. The whole game is run off a single CSV file that can be easily swapped out for different songs/ball timings. This system was robust enough that I prototyped the simon game using the exact same codebase. It also allowed me to easily adjust and change timings without recompiling/changing code.

Development on this game is currently in progress, improving the game to add menus, tutorials and more juice. Currently the music is from "Rhythm Heaven: Fever", this will be replaced later on.

In-Dev video (sound recommended)

Software Engineering Project Games (2015 - 2016)

For a second year module at the University of York

One of my second year modules was a Software Engineering Project where teams of six worked to create three games over the course of the academic year which had to meet requirements given by the lecturers. My role in the team was as head of the programming sub-team, responsible for the development and design of the game I did over half the programming.

There were distinct phases of game development at the end of which teams had to present their game to the other teams and then had to take over the code and documentation of another team, and work on that for the next phase. Extra marks were given to teams whose code was chosen by other teams. Each phase lasted about 8 weeks.

Teams were free to use whatever tools/languages they liked to create the game with. We chose to use:

  • Java - as we were taught Java in the previous year we decided it would be a good language to work in.
  • libGDX - a Java game development framework. We decided to use this as it is similar to Monogame for C# which I and other members had previous experience with.
  • Tiled - a tool providing a robust and simple map editor to help development.
We also chose to use scrum - an agile software development strategy for the development of our games.


I created videos/trailers for each of the games that my team made. These were used in the presentations and can be viewed below:

Straight Outta Heslington

The Empire Strikes Quack

DuckShot


The Brief

The Brief we were given was that our game must be about a duck travelling across the University campus, encountering various obstacles and with various objectives.

Each team is to build a single-player duck simulator game, which must take place at the University of York. Ducks have objectives, and use their innate or acquired abilities to try to achieve those objectives. When an objective is completed, the duck is awarded points.

  • Your game must take place at the University of York, but you do not have to include the entire campus. It must include at least eight locations.

  • The game must support at least eight different objectives. You must support at least two different types of objectives.

  • The game must support at least five different types of obstacles, including at least one randomly allocated obstacle and at least one objective-specific obstacle .

  • The game must support at least three different Duck Special Powers. Ducks innately have the ability to waddle (fairly slowly), swim (fairly briskly), and fly (quickly).


Straight Outta Heslington- Download - Manual

Straight Outta Heslington is the first game we made. It is a JRPG modelled after final fantasy. We felt that it a JRPG would easily allow us to meet all the given requirements from the brief. Another good thing about choosing a JRPG is that we could split the programming evenly between the battle system and the overworld system allowing sub-teams to work on each part seperately- increasing our speed.

I worked primarily on the battle system, ensuring that the backend for the system was robust and easily expandable which was important as we wanted to get as many teams as possible to choose our code-base at the swap point. Development went pretty smoothly and our decision to separate the two systems (overworld and battle) proved successful as we were able to work quickly in our subteams without interfering with the other sub-team. The point where we linked the two systems went well which further showed our decision paid off.

We also created very high quality documentation for the game including requirements, system architecture, risk management and team management documents. The documents we created were very useful for ensuring the quality of our game and ensuring we met all the requirements given to us.


What was delivered - Documentation

We had quite a lot implemented by the time we got to the end of the phase:

  • Navigatable Overworld
  • NPC's with dialog
  • Menu System where you can view party stats, skills and equipment
  • Random battle system with multiple damage types, enemies and items
  • A boss battle
Due to our system design, we ended up with a game whose systems could be added to and improved very easily.


The Outcome

Three teams chose to take on our game for the next phase, the highest uptake of any of the games that were created. We got a mark of 76% for this phase.

The Empire Strikes Quack- Download - Manual

For the second phase we took over a top-down shooter game. It was fairly basic but had a level system where you complete the objective to go to the next level. All the enemies were melee enemies but there was some AI to make them follow you implemented. There were some powerups implemented a form of flying.


What we did

We thought the basics of the game were good but it needed a lot of work to make it fun. We also heavily disliked the art-style and decided to do a full art-pass on the game. One of my team made a good sprite for the duck being a jedi and the star wars theme took off from there (The Force Awakens had recently come out). In the original game you could only face in four directions, we upped this to eight to make the player feel more responsive.

Other changes we made:

  • Implemented swimming - the previous team should have done this
  • Changed Flying mechanics - previously you would fly in the direction you were facing for a fixed amount of time
  • Added a melee attack - wanted a satisfying way to deal with close-range enemies
  • Added a ranged enemy - made movement and positioning more important
  • Made enemy health visible - improved player feedback, made attacking more satisfying
  • Added a more rewarding scoring system
  • Added a kill x enemies objective
  • Added a boss enemy on the last level
  • Complete sound pass - changed all the sounds to better suit the theme


What was delivered - Documentation

We fulfilled all and surpassed some of the requirements for the end of the module phase. I think this game is the best one we delivered of the three, I really like how cohesive the game feels and when I was playtesting it I was surprised to find it was actually a lot of fun- I wasn't sure if it would be fun to play in the end.
The actual moment-to-moment fighting gameplay is fun but you can blitz through the game by skipping most of the levels and getting the flag immediately.

I am most proud of the boss fight. We had a couple of hours left before our self-imposed development cutoff/feature lock and we felt the end of the game was lacking so we decide to add a boss. It took roughly two hours from having the first ideas for the boss to having it fully implemented and playable. The team really pulled together to do all the things necessary to make it in that time and I find it one of the best bits of the game, I am very glad we added it.


The Outcome

I believe our game was picked up by only one team - we were somewhat expecting this. Our game wasn't as appealing to be taken on this time round, part of this I think is that we were going to be given requirements changes when starting the final phase and our game probably didn't seem as easily extendable as other games. However I am very confident in saying that our game was the most polished/refined, actual game-like game of all those made for that phase and that I am proud of.
We got a mark of 87% for this phase.

DuckShot- Download - Manual

For this final phase we took on a game that had the same starting codebase that we had used in the second phase to create The Empire Strikes Quack. The game we took on here was that original codebase that had then been worked on by another team in the previous phase.

We were given a change in requirements for this phase:

  • Demented Waterfowl- a small number of waterfowl (both player and ai) must be able to behave randomly and unpredictably
    • For AI, they must have unpredictable or random behaviour (Cannot just be random path algorithms for navigation)
    • The player must randomly contradict an instruction over a period of time
    • It must be possible for demented waterfowl to return to normal through some means
  • Two cheat methods- Add two forms of cheating, invent any type of cheat but make sure it doesn't make the game too easy or unfair


What we did

For the cheat requirements, we decided to follow the cheat methods in other older games, on the pause menu, if you enter a certain key combination, the cheat is activated. We added two cheats, one where an explosion graphics happens where your bullets impact and the other which when activated causes a duck to bounce around the screen, obstructing your view. The second cheat also gives you a score multiplier while it is active to compensate for the visual obstruction.

The harder requirement is the demented waterfowl. As far as the player character randomness, it is inherently frustrating and bad game design- having your player character ignore your inputs every now and again is infuriating. I decided to try and gamify the system instead- every now and again the player has to press the key that appears above the character's head within a certain amount of time else their movement controls will change so the left key may move the player up etc. If they press the key in time they get a powerup for a short while as a reward.
This system fulfills the requirements whilst adding another mechanic to the game, ensuring the player has to pay attention to their character regularly.
For the AI, we made an enemy that will walk up to you and explode, shooting out damaging feathers in all directions - I think that counts as random behaviour.

Other changes we made:

  • Added damage frames- Prevents the player from taking damage too quickly
  • Improve powerups- made picking up a powerup add to the powerup time instead of overwriting
  • Improved flying- the flying system was cumbersome, added greater freedom to it
  • Completely redesigned menus- A complete art pass on the menus
  • Improved the minimap- made it slightly transparent
  • Made the player look where the mouse is- player could shoot backwards previously
  • Had to refactor doubles to floats- the previous team had used doubles instead of floats which was unnecessary and lead to various odd effects
  • Improved sounds and made new music


What was delivered - Documentation

We successfully delivered on time, meeting all requirements both with documentation and with the game.


What was delivered

This was the last phase so teams didn't take over games from other teams. We got a mark of 90% for this final phase.

Pizzas Please (Keep Cooking and Nobody Complains) - (2016)

Gamejam Game

Download Pizzas Please - Requires .NET Framework 4.5

Pizzas Please is an asymmetrical multiplayer/party pizza making game written in C# using monogame during a 3-day gamejam. There are three different game roles:

  • Chef
  • Trainee Chef
  • Manager
Each game has a single manager and then multiple pairs of chef's and trainee chefs working together.

When the game starts, ever player is randomly assigned a role, chefs and trainee chefs are paired up to form pizzerias. The aim of each pizzeria is to get as many points as possible, they do this by completing orders.

One player is assigned to be the manager. The manager receives pizza orders and has to get the various pizzerias to send back the completed orders. Some orders are for specific pizzerias and some can be given to any pizzeria.

Chefs have to prepare and send the pizzas, choosing the correct base, size and toppings. They get toppings from the toppings conveyor belt after they are placed on the belt by the trainee chefs.

The trainee chefs must prepare the toppings and place them on the conveyor belt for the chef to use. The trainee chefs must play multiple different minigames in order to gain toppings. Communication with the chef is very important to make sure they have enough/the right toppings to create the pizzas.


How to Play

Starting the server
To start a server you must run the game exe with the command line parameter "Server". The default port is 4444, you can specify the port by adding it to the command line parameters after "Server".

'PizzasPlease.exe Server <port>'
e.g. 'PizzasPlease.exe Server 4555'

Connecting to a server
To connect to a server and start a client you must run the game exe specifying the IP address and port of the server as the command line parameters.

'PizzasPlease.exe <ip address> <port>'
e.g. 'PizzasPlease.exe 127.0.0.1 4555'

They Are In A Room (2016)

Ludum Dare 37 Jam Game

They Are In A Room Download - Requires A HTC Vive

Ludum Dare Entry Post


Gameplay Recording



Brief

I made this game in Unity with two friends for Ludum Dare 37. The theme for the jam was " One Room".

None of us had very much Unity experience going into the jam -I had some experience with working in 2D in Unity- and no experience creating VR games so the whole jam was a great learning experience.
The basic idea we had was to make a game where you are in a room full of different things that you can interact with but basically anything that you do is narrated.
We were partly inspired by the website " clickclickclickclick" which narrates everything you do on a simple webpage with a button to demonstrate how much information can be gathered from your web browser.


Development

Basic interactions
We started out learning how to to connect the Vive to Unity, getting the position information of the head and controllers, then we moved onto allowing the user to pick up objects and throw them. In order for the user to be able to throw objects, we had to give the objects a force in the correct direction once the player let go of them. This was because whilst being picked up by the player, the objects stopped being physics objects.
Most of the first day was spent on this sort of thing, basic interactions.

Sound system
Once we had a reasonable system for allowing the player to interact with the objects in the room, we worked on getting sounds to trigger. A single manager that was attached to the headset prefab was created that would actually play the sounds. The main issue would be playing the correct sounds at the correct time. So, playing the " dropped the cube on the ground" sound when the cube is dropped and hits the ground.

For this, we created a generic state machine system which we then derived from for specific state machines. So there was a state machine for objects that could be picked up- grabbables. These had states for falling, grabbed, on the floor, on the table etc. Various actions would send signals to the state machine manager that would update all the state machines with the action, then state machines would signal that a sound for a particular event should play.

We had several voice lines recorded for each event, so picking up a cube may have " They pick up the cube" and " They grab the cube". Each voice line had a period given which was the length of time that the voice line cannot play again after being played. Voice lines and actions also had different priorities assigned to them so that voice lines for actions that occur less regularly would be able play straight away when signalled instead of voice lines that are more common.

Most of the rest of the time was spent improving the virtual play-space, adding new objects to play with, a light-switch to turn off the light, a picture to throw around, a poorly tuned piano etc.

State Diagram