More Gaps

This is more concept art for a protagonist in the new project called The Gap. Okapi Boy – I have always loved Okapi’s. They are shy and remained hidden from the world in the deepest parts of the jungle until they were discovered in the 50’s. Beautiful Zebra like patterns on skin like a Deer. This is a deeply peaceful animal with large soulful eyes. He dreams and offers advice but you have to seek him out and finding him is not always easy or straightforward. In The Gap you get the chance to play as the Okapi for part of the story.

Okapi Boy

There used to be a great example of this rare creature in the Melbourne Museum Taxidermy collection (which I used to love but has now sadly been taken off the exhibit floor). You can take a virtual tour of the old “Wild” exhibition here.

I have a LOT more concept art to do as I want to get a very clear picture of my characters before I start modelling.

I also stared working on the programming for the game. One element I want to include in the story is a “mini-game” called Fox and Geese. It’s played on a chess board and was one of the first games I remember my dad teaching me how to play. It’s pretty straightforward and uses a chess board and pawns. Four white pawns are the Geese who can only move forward and diagonally one row at a time. The Fox is a black pawn that can move diagonally one space at a time in any direction. Moves are taken in turn and the aim of the game is for either the Fox to break the line of Geese or the Geese to “capture” the Fox so that he cannot move.

Fox And Geese

It’s early days yet with only the board set up and pawn selection scripts started but it was actually pretty fun setting up the programming that took care of the board. When you learn programming you get to do lots of arrays and nothing screams “ARRAY” like a chess board. So it’s kind of nice to use one of those basic skills that you use in all programming in such a nice simple example. You get to add a little interest to the basic array with the inclusion of alternating colours. Here is the code below:

using UnityEngine;

public class FnG_MakeBoard : MonoBehaviour
{
    public GameObject boardPiece;
    public Vector3[] positions;

    // Start is called before the first frame update
    void Start()
    {
        positions = new Vector3[64];
        float start_x_pos = -1.75f;
        float start_y_pos = -1.75f;
        float rowcount = 0f;
        float linecount = 0f;


        for (int i = 0; i < positions.Length; i++)
        {
            positions[i] = new Vector3(start_x_pos, start_y_pos, 0f);
            start_x_pos += 0.5f;
            rowcount += 1;

            if (rowcount == 8)
            {
                start_x_pos = -1.75f;
                start_y_pos += 0.5f;
                rowcount = 0f;
                linecount++;
            }

            Instantiate(boardPiece, positions[i], Quaternion.identity);
            Color32 myRed = new Color32(185, 48, 48, 255);
            Color32 myGray = new Color32(106, 106, 106, 255);
            if (i % 2 == 0)
            {
                if (linecount % 2 == 0)
                {
                    boardPiece.GetComponent<SpriteRenderer>().color = myGray;
                }
                if (linecount % 2 != 0)
                {
                    boardPiece.GetComponent<SpriteRenderer>().color = myRed;
                }
            }
            if (i % 2 != 0)
            {
                if (linecount % 2 == 0)
                {
                    boardPiece.GetComponent<SpriteRenderer>().color = myRed;
                }
                if (linecount % 2 != 0)
                {
                    boardPiece.GetComponent<SpriteRenderer>().color = myGray;
                }
            }
        }
    }

Unity Code Review and Style Guide

Hi Trixie here. It’s Code Review time! Yay. Time to clean up that code and start really looking at all the crap work you’ve done over the last months and clean that sh!t up!

I’ll post our in-house Style Guide (which of course goes out the window when you are coding in anger) at the bottom of the post. Hopefully someone else will follow it or find it useful.

This is how the code review works:

  • Make a list of all your scripts and the game objects they are attached to.
  • Go through all the variables/functions/iterators and make them follow the standard in the Style Guide (which includes making logical names sensible to humans).
  • Check all your Public references and make Private if you are really not using them.
  • Trawl the console output and clean up the extraneous debugging guff.
  • Start grouping your code into functions that do a similar thing and try and make them standardised.
  • If you are lucky you will find some optimisations in there as well to make your game run faster, better, more efficient, lighter.

Then at least it will be another few months before you muck it up again.

I know there are automated tools to do some of this work but I prefer to work though my own methods. I like to have complete control over the process. My favourite tool for analysis is the Unix Command line (I know weird right?). My workstation is Windows 10 but I have a Cygwin like utility called MobaXterm installed which allows me to interrogate the file system like a Unix machine and use grep and other commands on all the files that make up my scripts.

Basically I want to build a big spreadsheet of information that lists all my scripts and the Game Objects they attach to and the Public interfaces and variables etc.

This is one that I started for Endless Elevator:

Then I start extracting Game Objects and Code loops using the Unix Command Line so I can start to build a picture of what’s going on.

One of the outcomes of this process is that I want to be left with a map of how stuff works that I can connect the dots on in the future. It’s kind of like a Design Document in reverse.

Here are a few examples of the commands I’m using and how the information is extracted:

# grep bool *.cs # Getting out all my bools – I tend to use true or false tests a lot to explicitly define functions and events.

As you can see above the bool names are mostly descriptive and the variable name is mostly in camelCase. Those few like swingme will get updated to swingMe and the overly generic “yes” and “yesNow” (what was I thinking!) will be made more descriptive of what we are really agreeing to in that code.

This command looks at all the sort of functions I am using and where. It’s nice to know which one’s don’t have an Update() function and where all my Collisions and Triggers are.

# egrep “{|}” AI.cs # I use something like this to collect an idea of the complexity of my loops and functions.

# egrep “{|}(|)|if|for|else” AI.cs # This is my favourite type of command. Like the command above I use it for working out the structure of a script. This is way easier than scrolling through lines and lines of code and comment and makes it really easy to spot areas where you have gone loopy crazy pants.

# grep GameObject *.cs # This one makes a good list of all the scripts that I reference another Game Object in. It helps build a visual map of what dependencies there are between objects.

# grep script *.cs # This one does a similar thing in that it grabs all the times that I am calling something from within another script attached to another Game Object..

The command line is also a nice quick way to check how many lines of code you have written.

There are some good Style Guides out there.

I like this one for it’s organised folder structure and naming convention for files: https://github.com/stillwwater/UnityStyleGuide

I like the Microsoft C# one for layout and block style: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/inside-a-program/coding-conventions

I like this for it’s use of camelCase and Capitals and it’s preferred block style: https://github.com/raywenderlich/c-sharp-style-guide

As a basic guide though I always try and mimic the Unity API manual. For example this page for OnCollisionEnter:

// A grenade
// - instantiates an explosion Prefab when hitting a surface
// - then destroys itself
using UnityEngine;
using System.Collections;
 
public class ExampleClass : MonoBehaviour
{
    public Transform explosionPrefab;
    void OnCollisionEnter(Collision collision)
    {
        ContactPoint contact = collision.contacts[0];
        Quaternion rotation = Quaternion.FromToRotation(Vector3.up, contact.normal);
        Vector3 position = contact.point;
        Instantiate(explosionPrefab, position, rotation);
        Destroy(gameObject);
    }
}

The comments are appropriate. The Class name uses a Capital for each word. The curly brackets are on a new line and indented block space. Varables are in camelCase.

Here is our minimal Style Guide. This is the basics of how we roll things:

Thanks for reading. See you all in the New Year… Trixie.