3-Handed Laser Shuffle

I recently competed in a game jam on Itch.io. The requirements were a 128×128 resolution, four colors, one weekend, and a theme of “break out.” So I made this. The controls take some getting used to. It’s intentionally a bit awkward, and requires some practice switching among three controls with only two hands. WASD controls the red laser. TFGH controls the green laser. The arrow keys control blue. Try to destroy the matching blocks before they get too close. Every 100 blocks cleared gives you a power-up that you can use with SPACE. This pauses block movement for a few seconds.

3-Handed Laser Shuffle won first place in the Mini Jam, among 20 entries. Try it out!

Creating a Circuit in Unity

During a recent game jam, my team made a game called Elevator Circuit. The game is now available on for free on Itch: https://tykenn.itch.io/elevator-circuit. The objective is to complete a circuit by moving elevators holding circuit segments, aligning them into a complete path. It currently has five short puzzles with more to come. My biggest role in the project was to program the circuit system.

The idea was that any segment without a path to a generator would be red. A segment with a path from one side, but not a path from the other is yellow. When there is a path to a battery from both sides, current can actually pass through the segment, it turns green. I used Procedural Lightning to indicate that the connectors of two segments are close enough to be connected (It happens even when the two segments are not connected to a battery, but we needed some kind of feedback).

My first (failed) attempt

I made a script for each connector that checked for other connectors to enter and exit its trigger area. It then registered the segment of the other connector to current segment. The connector then told the segment to update its material by recursively checking its neighboring segments, and then its neighbor’s neighbors, until it either dead-ends, loops , or reaches a battery. All the segments along that path would update their materials accordingly. I soon ran into all sorts of race conditions and edge cases. The lightning would correctly connect segments, but the colors of the segments would be wrong half the time. So, I scrapped that and tried something new.

Working from the battery to the segment.

Since there would only ever be a handful of segments in any stage, it would not be too expensive to check for changes every frame. I kept what I had before with each connector registering other segments to its own segments, but instead of updating the materials only during a connection change, the battery would “pulse” every frame. Going recursively to each connected segment from the battery, it would mark the visited segments as “connected” either from the left or right, depending on where the pulse came from. The segments would then all update their materials accordingly, the frame would render, and then the connections would reset for the next pulse.

Here is the script that goes on the individual connectors:

using UnityEngine;

public class CircuitConnector : MonoBehaviour {

    public bool isLeft;
    CircuitSegment segment;

    private void Awake()
    {
        //Expect CircuitSegment script to be on parent.
        segment = transform.parent.GetComponent();
    }

    //Make a connection
    private void OnTriggerEnter(Collider other)
    {
        CircuitConnector otherCon = other.GetComponent();
        if (otherCon != null && otherCon != this)
        {
            //Register connection to segment
            if (isLeft)
            {
                segment.leftSegment = otherCon.segment;
            }
            else
            {
                segment.rightSegment = otherCon.segment;
            }
            //Code for anything else to do during a
            //connection, like instantiate lightning
        }
    }

    //Lose connection
    private void OnTriggerExit(Collider other)
    {
     
        CircuitConnector otherCon = other.GetComponent();
        if (otherCon != null && otherCon != this)
        {
            //Unregister segment
            if (isLeft && segment.leftSegment == otherCon.segment)
            {
                segment.leftSegment = null;
            }
            if (!isLeft && segment.rightSegment == otherCon.segment)
            {
                segment.rightSegment = null;
            }
        }
    }
}

And here is the script that goes on the circuit segment:

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

public class CircuitSegment : MonoBehaviour {

    [HideInInspector]
    public CircuitSegment leftSegment;
    [HideInInspector]
    public CircuitSegment rightSegment;
    [HideInInspector]
    private List meshesToPaint;

    //Usually only one of these in the scene at a time
    public bool hasBattery;

    //I used a red, yellow, and green material
    public Material deadMaterial;
    public Material oneWayMaterial;
    public Material poweredMaterial;

    //Optional event for receiving/losing power,
    //like opening and closing a door
    public UnityEvent powerEvent;
    public UnityEvent losePowerEvent;

    //Resets every frame, set by pulses
    private bool leftPowered = false;
    private bool rightPowered = false;

    //Does not reset, decided after pulsing finishes
    private bool powered = false;

    //only true during a pulse for checking
    //for loops
    private bool pulsing;

    private void Awake()
    {
        //Register all the meshes I want to paint.
        //I tagged all of them with "Wire"
        meshesToPaint = new List();
        foreach (Transform child in transform)
        {
            if (child.tag == "Wire")
            {
                meshesToPaint.Add(child.GetComponent());
            }
        }
        UpdateMat();
    }

    public void Update()
    {
        //Handle events for gaining and losing power.
        if (!powered && leftPowered && rightPowered)
        {
            powered = true;
            powerEvent.Invoke();
        }
        else if (powered && !(leftPowered && rightPowered))
        {
            powered = false;
            losePowerEvent.Invoke();
        }

        //Reset power
        leftPowered = false;
        rightPowered = false;
    }

    //Don't pulse until everything is reset from Update()
    private void LateUpdate()
    {
        //Only segments with batteries start a pulse
        if (hasBattery)
        {
            if (leftSegment != null)
                leftSegment.Pulse(this);
            if (rightSegment != null)
                rightSegment.Pulse(this);
        }
    }

    //Recursive function for deciding connections to batteries
    public void Pulse(CircuitSegment from)
    {
        //If a segment has already been visited in a pulse, it
        //must have looped.
        if (!pulsing)
        {
            pulsing = true;
            if (from == leftSegment && from == rightSegment)
            {
                //Handle edge case of a circuit with only two segments
                leftPowered = true;
                rightPowered = true;
            }
            else if (from == leftSegment)
            {
                leftPowered = true;
                if (rightSegment != null)
                    rightSegment.Pulse(this);
            }
            else if (from == rightSegment)
            {
                rightPowered = true;
                if (leftSegment != null)
                    leftSegment.Pulse(this);
            }
        }
        UpdateMat();
        pulsing = false;
    }

    // Update is called once per frame
    public void UpdateMat() {
        Material mat;
        if (hasBattery)
        {
            //Batteries work a little different. Never red.
            if (leftSegment != null && leftSegment.leftPowered && 
                rightSegment != null && rightSegment.rightPowered)
            {
                mat = poweredMaterial;
            }
            else
            {
                mat = oneWayMaterial;
            }
        }
        else
        {
            if (leftPowered && rightPowered)
            {
               mat = poweredMaterial;
            }
            else if (leftPowered || rightPowered)
            {
                mat = oneWayMaterial;
            }
            else
            {
                mat = deadMaterial;
            }
        }

        //Apply the material to every assigned mesh
        foreach (var rend in meshesToPaint)
        {
            rend.material = mat;
        }
    }
}

Now, in Unity, make a GameObject and attach the CircuitSegment script. Then add some meshes that you want to change colors. Tag them as “Wire” and make the CircuitSegment object its parent. Then also make two connectors, attach the CircuitConnector script to each, and mark one as isLeft. Make them also children of the segment. Now, if you have some object you want a complete circuit to trigger, like opening and closing a door, make a new script with two public methods such as Open() and Close(). On the segment that powers the object, you can assign those methods in the inspector through the Power Event and Lose Power Event.

Ten Super Helpful Unity Assets

As I’ve been working on Nebula Gladiator VRFly Around and Zap Aliens,  and Fail to Win, I’ve relied heavily on the Unity Asset Store. It is a great way to avoid reinventing to wheel. Unity itself all the basic tools you need (physics, animation, etc.), but to get a good starting point for your game, it is pretty much essential to add some packages from the Asset Store. Many of the packages cost a small amount (I have five packages ranging between 5 and 20 dollars), but many are free as well. Anyway, I’ve played around with a lot of Unity packages and found a few to be particularly useful. I’ve limited this list to just code and effect packages, since those tend to be more generally applicable.

1. Ragdoll and Transition to Mecanim

This is what I’m using for the ragdoll transitions in Fail to Win. In a 3D game where your avatar can get hurt (which is almost all of them), using ragdolls is a lot easier than creating death animations. It also tends to respond better to forces than pre-set animations. This tool by BzSoft, makes it even easier by automatically turning a character into a ragdoll when, for example, you fall from a really high ledge. Then, when things calm down, the avatar get back onto his or her feet. Also, it’s free.

2. Procedural Lightning

I am using this to do the zapping part of Fly Around and Zap Aliens. I used to have a simpler procedural lightning effect, but this looks way better. It has a surprising amount of configuration, so if you need anything that even somewhat resembles lightning or sparks, you can probably use this. Despite that, it is super easy to set up. It only costs $9.

3. Log Viewer

This solved a frustrating problem. I tested everything in the Editor, and it worked great. Then I made a build and deployed it to my phone. I opened it up to find the game broken. I could dig around and find the log file, but finding problems that way takes more time, and you may have to dig through a lot more. I then added this to my project and could open the log from my phone with a simple circle swipe gesture. It looks like the Unity console. It also displays the frame rate, memory usage, and other stats. This could be super useful for collecting information from beta testers. This package is free.

4. ProBuilder

So, I’m not much of an artist, and even if I was, I wouldn’t want to go into Blender or Maya and design a level just to test a simple idea. So I spent a lot of time carefully aligning primitives (mostly cubes) into rooms. The Standard Assets Prototyping package helped a little, but it still lacked the kind of control I needed. ProBuilder is a free package that lets you model directly withing the Editor. Granted, it would not be ideal for anything as complex as character design, but it is fantastic for level design.

5. FinalIK

This is the priciest package I’ve listed so far as $90, but if your game involves a lot running around and climbing on stuff, this may make your animations look a thousand times better. I got tired of having floating feet when walking on slopes, so I was really excited to finally have a way to fit my animations seamlessly to the stage just like in AAA games. This package does a lot more than stick feet to floors. Climbing, opening doors, pressing buttons, and pretty much anything else that involves animation and an avatar’s surrounding are going to look a lot better with FinalIK. I’m even using it in Fly Around and Zap Aliens, although I had to be sure to turn it off every time you become a ragdoll; otherwise, weird stuff happens.

6. Mesh Slicer

Another BzSoft package that makes it easy to create a more fun game. It lets you cut a mesh along a plane, or even along the path of a knife (or sword). It is a super satisfying effect in VR. That’s why I added it to Nebula Gladiator VR. A VR sword isn’t going to meet any resistance except maybe when a family member or roommate walks through the living room at the wrong time and gets hit with a controller, so a VR sword should cut cleanly through anything it hits. It got even better when I wrote a simple script that forces the pieces to fly away from each other after being cut.

7. Head Look Controller

I’m amazed this package still works, since it hasn’t been updated since 2010. It is free, and simply makes people look at stuff. There may be some other similar packages that do the same thing and are more up to date, but most of the time, this package should be all you need. It is super easy to set up and is another subtle effect that really makes a game look so much better.

8. MK Glow

It is a nice-looking glow effect that can be added either to individual objects or to a whole scene. I’m probably going to add it to Fly Around and Zap Aliens soon. I’ve played around with it before, and it is really easy to set up. They even have a free version. The upgraded version is only $10, and offers some extra control, but the free version is already super useful.

9. Unity Particle Pack

This is a Unity Essentials pack, so there’s a good chance you have already been using it, but I had to list it here because of how useful it is. I am using its explosions in Fail to Win, but a lot of its more subtle effects like dust and sparks can add the right kind of detail to a game. Most games are going to have a good reason to use at least one of those effects.

10. Post Processing Stack

Another Unity Essentials package, but worth mentioning. When used right, this could help make your game look less like an obvious computer rendering and more like a cinematic masterpiece. I discovered it doesn’t work so well on mobile, but on other platforms, it helps give the finishing touches.

A Final Note

Many of these tools were things I discovered when I was noticing details in my games that made them seem like ugly amateur indie games instead of modern quality masterpieces. Thank you to all the creators of these tools. The asset store is a fantastic resource. I’ve both sold and purchased tools on the asset store, and the system is great. I, of course, haven’t tried everything on the asset store (there are thousands!), so I’m curious if any of my Unity gamedev readers here have used a Unity package they consider a must-have. If so, please share in the comments below.

Fly Around and Zap Aliens Beta

I recently released a game on the Google Play store called Fly Around and Zap Aliens. It is currently in an open beta, so you are welcome to try it out, although I plan change some things in future. You can download it here: https://play.google.com/store/apps/details?id=com.kenningtongames.spacegame.

History

This game actually started back in high school. I had previously made a simple space game in Flash where you and another player orbit a planet, trying to knock each other out of orbit. When I was learning Unity, I thought I would try making a 3D version of the same game. However, I quickly ran into some serious design issues:

  • There’s a lot more space in three dimensions. Traveling from one side of the planet to the other felt like it took way too long, and it was hard to tell how fast you were going until you crashed into something, unable to slow down fast enough.
  • Your field of view is limited, since you are following a spaceship instead of getting a full view of the arena. This made the pull of gravity really confusing. Since there is no up or down in space, the pull of the planet onto the ship just made uncomfortable controls.
  • Multiplayer would be trickier than simply sharing a keyboard with a friend.
  • Boundaries are unclear. In 2D, it was simply the edge of the screen. In 3D, I needed a way to box players in and still have them experience the openness of space.

So I made an entirely new game with a similar-looking stage. There is still a planet in the center, and you still control a spaceship, but now you are defending the planet from aliens. You zap them instead of knocking them backward. There is no real gravity from the planet, but you still fly around it. I originally had a force-field for boundaries, but my force-field effect looked awful. The game was pretty much playable, though. I never could settle on a name. I then took a two-year break from game development and forgot all about it. More recently, I was looking through my old projects and re-discovered it. I had learned a lot since made it (it’s been about five years now), so I decided to start fixing it up.

The Game Now

I chose to port it to mobile because of the availability of tilt controls. Really, a platform like the Nintendo Switch would be more ideal, since it has a little more graphics power than a mobile phone while stile having the same tilt control, but Android is an easier platform to begin publishing for. The Asset Store has come a long way since I started this project, so I was able to make things look a lot nicer, but the game works in pretty much the same way. I did, however, change the boundaries, using a portal instead of a force-field. If you fly too far away from the planet, a portal appears, taking you to the opposite side of the planet, flying toward it instead of away from it. I released it recently to the Play Store, but it still has a few problems. For example, it is possible to dodge the portal and keep flying away. Most people I show the game are initially confused by the controls. It doesn’t take long to get used to them, though. Also, the end screen is kind of boring. I hope to fix these things and more. Still unable to choose a name, I chose the most concise way I could explain it.

The Plan

Between now and the full release, I plan to add the following:

  • Appearance tweaks (Already swapped out the spaceship models; just need to publish that change).
  • Fix the problem of dodging the portal and venturing into the void of space.
  • Add a leader board
  • Have the aliens come in waves instead of a steadily increasing rate.
  • A tutorial
  • Optimizations and device support (If you try the beta, and it does not work on your phone, let me know!)
  • An iOS port

These updates will come gradually as I make them, leading up to the official release. Please try it out and let me know what you think!

Player Motivations: for Novelty or for Sport?

There are many ways to classify players. I most commonly hear casual versus hardcore. This classification is not very useful, since it seems to describe the level of commitment to a game, not the type of commitment. I struggled to classify myself, since I enjoy both casual and hardcore games. I noticed, however, that I had a very different play style compared to many other players, in both casual and hardcore games. I realized that these differences in style could be explained by a difference in motivation. So I propose a new classification based on two kinds of player motivations: for novelty versus for sport. These two groups can be described like this:

Players for novelty (adventurers):

  • Believe games are about trying new things
  • Prioritize accessing new content
  • Care very little about metrics
  • Play recklessly
  • Embrace randomness and imbalance
  • Like things to change

Players for sport (competitors):

  • Believe games are about overcoming challenges
  • Prioritize winning
  • Focus on metrics
  • Play cautiously
  • Get outraged at randomness and imbalance
  • Like stability

This is a spectrum, and while many players will fall somewhere between the two, the direction a player leans will greatly impact the decisions that player makes during the game. I, for example, lean far on the novelty side, meaning I am more of an adventurer than a competitor. Even in physical sports, which obviously are designed more with competitors in mind, I would try to make the game more novel. Because of this, I wasn’t the most competitive. I remember one time in elementary school when I got bored during a game of dodge-ball and thought, “How long could I last without moving my feet?” The children on the other side of the spectrum thought I was being an idiot, since not moving my feet would obviously put me at a disadvantage. I didn’t care about the disadvantage; I just wanted to see what would happen.

Another example, this time with video games, is Super Smash Bros. I like to play timed battles with a random character, on a random stage (no stages removed from the random selection), with all items turned on and with the maximum number of players. Many Smash players probably cringed while reading that last sentence. This introduces tons of luck. You could end up winning a round, not because you have better tactics and reflexes than another player, but because the perfect item happened to drop right in front of you while your opponent is distracted by a random stage hazard, allowing you to deal a final blow a second before the clock hits zero. Many players try to avoid these situations by only playing stock mode on the simple Final Destination stage with all items turned off.  Such a player will feel satisfied that any victory was a result of his or her own skill, and nothing else. It is the pleasure of learning to overcome a difficult problem. Players like me, though, would look at this setup and think, “Why spend all your time playing only half a game?” Sure, the game is unfair and unpredictable with my preferred setup, but each match has a higher chance of seeing a combination of events I have not seen before, and for players like me, that means more fun.

You have two types of players who will judge your game in very different ways. One type wants more options. They are forgiving of bugs and glitches, and may actually appreciate them if if they do not completely block game progress. The other type wants games to be fair and predictable. They are more willing to replay the same or similar content without getting bored, but also more likely to complain about glitches, imbalance, and random number generators. They will prefer existing game mechanics to be deep rather than be introduced to new game mechanics.

Designing for Player Motivation

It is important to consider both of these kinds of players in game design. Many games support play styles preferred by both groups. In farming simulators, for example, players for novelty can focus their attention befriending villagers, collecting rare items, etc., while players for sport can focus on becoming millionaires. These differences can often make interesting gaming communities. An adventurer playing for novelty might discover a glitch in a game that is then used by a competitor playing for sport to set a new speed-running record.

Some game mechanics, however, tend to appeal to one side of the spectrum more than the other. Sandbox and open world games tend to attract adventures playing for novelty since they encourage discovery and do not have as clear of goals. Competitive and linear games attract players for sport because they are more controlled, more fair, and more clear about objectives. By considering these two kinds of audiences, we can tailor the details of a game’s design to the things our players most hope to find.

Of course every player is unique, so no classification is perfect. Most adventurers need at least some goals to get started. Most competitors will appreciate the occasional game changer. Nearly every game design will need to account for both motivations, regardless of the expected audience. Many game design decisions are highly controversial because they appeal more to one side of the spectrum than the other, earning game developers both praise and criticism. By knowing our players’ motivations and by designing for the different resulting play styles, we can design games that both can enjoy.

Where are you on the player motivation spectrum, and how has that affected how you play games? Do have any other ways you like classify play styles? I’d love to hear about it in the comments below.

Nebula Gladiator VR

A roommate of mine just got an HTC Vive virtual reality system, and that gave me an idea. One of the struggles with making Nebula Gladiator has been making smooth sword combat. In virtual reality, however, you get full control with how you swing a sword. So I began work on Nebula Gladiator VR. The game is simple: fight hordes of robots by slicing them with your sword. After a couple days of setting up my computer for VR development and playing with the SteamVR library for Unity, I used existing artwork from another project, Nebula Gladiator, to set up a simple arena scene.

The scene spawns a new robot every few seconds around the perimeter. The robots approach the arena, and thanks to BzKovSoft’s Object Slicer, you can split these robots in half with your sword. At this point, the robots are still harmless, so the next step is to introduce threats, but so far, it is very satisfying to swing a sword around and watch robot gore fly around you. The video doesn’t do the experience justice. Already, in this early stage of development, I and my friend testers find ourselves wanting to swing that sword around until we are exhausted.

Yet to come will be robot attacks that lower your health, a high score board, and increasing difficulty with time. Please leave a comment with any feedback. I’d love you hear your thoughts on the project and the demo.

How to model procedurally in Unity3D

Unity3D is not a modelling tool. It is usually easier to design artwork in an animation program like Blender or Maya, and then import them into Unity. However, for some things, especially procedurally generated content, you’ll need to dive into the drawing tools Unity provides in its libraries.

Note: This tutorial assumes you have a basic knowledge of the Unity Editor. If you do not, you should first go through Unity’s beginner tutorial.

First, create a new scene in Unity. Go to GameObject > 3D Object > Cube to add a new object to the scene, and position it at the origin. Then, in the Project window, go to Create > C# Script. Name the SimpleMesh, and then double click it to launch Visual Studio. Now we are ready to start coding.

We’ll begin by creating a Mesh object. This is what hold the shape of our object. We make a mesh by creating a bunch of 3D vertices and then connecting these vertices to make triangles. Unity does not have a built-in way of making pyramids, so we’ll make one with our SimpleMesh script. I’ll show the code and then explain:

using UnityEngine;

public class SimpleMesh : MonoBehaviour {

    void Start () {

        Vector3[] verts = new Vector3[16];
        //base
        verts[0] = new Vector3(-1, 0, -1);
        verts[1] = new Vector3(-1, 0, 1);
        verts[2] = new Vector3(1, 0, 1);
        verts[3] = new Vector3(1, 0, -1);

        //front wall
        verts[4] = new Vector3(-1, 0, -1);
        verts[5] = new Vector3(0, 2, 0);
        verts[6] = new Vector3(1, 0, -1);

        //back wall
        verts[7] = new Vector3(1, 0, 1);
        verts[8] = new Vector3(0, 2, 0);
        verts[9] = new Vector3(-1, 0, 1);

        //left wall
        verts[10] = new Vector3(-1, 0, 1);
        verts[11] = new Vector3(0, 2, 0);
        verts[12] = new Vector3(-1, 0, -1);

        //right wall
        verts[13] = new Vector3(1, 0, -1);
        verts[14] = new Vector3(0, 2, 0);
        verts[15] = new Vector3(1, 0, 1);

        //order the indices of verts in patterns
        //to make triangles
        int[] tris = new int[18] { 3,2,0,2,1,0,4,
                     5,6,7,8,9,10,11,12,13,14,15};

        //add the vertices and triangles to a new mesh
        Mesh mesh = new Mesh();
        mesh.vertices = verts;
        mesh.triangles = tris;

        //Assign the mesh to the MeshFilter component
        GetComponent().mesh = mesh;
    }
}

Everything will happen inside the Start() method so it will happen once when we play the game. This is what the script does:

  1. Create an array of 3D vectors to store our vertices. Our pyramid will have five vertices: the top and each of the four corners. Many of these vertices are duplicated in our array. This is because we want hard edges. Shared vertices mean there will be a smooth edge, like the surface of a sphere. Duplicated vertices mean it will draw a hard edge like a corner. We’ll come back to that later.
  2. Create and array to store triangle information. This may seem like a strange list of numbers, but each corresponds to an index in the triangles array. Every three numbers represent one triangle connecting vertices counter-clockwise. So the first triangle connects vertices 3, 2, and zero, the second connects 2, 1, and zero, and so forth.
  3. Create a new Mesh object. This stores both our vertices and triangles.
  4. Assign the new mesh to the MeshFilter. This component should already be on our object, since we are creating it from a Cube. It will also use the material already assigned to the Cube. The material tells Unity how to draw the shape on the screen based on textures and lighting. Materials can also be generated, but that is outside the scope of this tutorial.

Assign the SimpleMesh script to the cube object. If you press play, you should see something like this:

pyramid

You may need to adjust the camera position or pause the game to get a better view. The shape is right, but it still looks kind of strange. There is nothing to distinguish the edge, and the lighting is weird. This is because we have not assigned normals. Normals are direction vectors that are supposed to point away from the object. There is one for each vertex. When light hits an object, it reflects more light if it hits directly than if it hits at an angle. The normals give Unity a reference to decide what is considered direct.

normal_explanation

Normals are why we duplicated vertices. Unity blends between the normals to get smooth curves, like in the top diagram. At a hard edge, though, where would the normal point? With two vertices, we can have two normals, one pointing away from each wall that meets at that corner. There is no blending because we have two separate surfaces.

Fortunately, for a shape as simple as this, the normals can easily be calculated. Add this inside the Start() method after everything else:

mesh.RecalculateNormals();

That’s it!. Press play and you should see a pyramid that looks something like this:

pyramid2

PyGame Detective Game

Last semester, I took a class learning PyGame. Despite the outdated-looking website, it is actually fairly well maintained. It may not have all the bells and whistles that I am used to in other game engines, PyGame can be a good tool for making smaller 2D games. With the help of PyTMX, I was able to make a quick side-scrolling detective game.

In the game, you are thrown into this village where someone is supposedly plotting a murder. People walk around throughout the day, going house to house and interacting with the neighbors. Your goal is to get the information you need at the end of the day in order to stop the murder from happened. The roles and behaviors of the townspeople are randomized at the start of the game. However, if you fail to stop the murder, you can reset it to the start of the day, where people will act exactly as they did on the last try except where your different decisions might have influenced them. The game was mostly a proof of concept to see if I could make a game all about logical deduction.

detective