SOCCOBAN – GENERIC NFTS Games Jam [Part Two]

NFTS

This Part Two, it should be clarified, is actually a few half days mashed together. Christmas puddings, long cold winter trains and many a gifted ale may have prevented me from knuckling down to do a full report this past festive week. But don’t worry, here’s a summary of what I’ve managed to achieve so far…

 The Setup
Technically I already knew that I’d be making the game in Unity3D in C#. It’s a comfortable place for me to start and there’s still so much more for me to learn! So to begin with I defined a few familiar key verbs, nouns and phrases that I wanted my audience to be able to act out in a football game.
Passing, Tackling, Kick Off, Throw Ins, Save, Tactics, Offside, Formation, Corner Kick, Goalkick, Penalty, In Off The Post, Foul, Sending Off, Possession
Looking at the Overall Experience I wanted to make, I also did a wee brainstorm.
Shot Power, Leaderboard, Home/Away Kits, Shirt Selection, Stamina, Player Marker, Stadium, Practice Mode, Challenge Mode, Career Mode, Player Choice, Controller Swap, Score, Crowd, Advertisement Boards, Match Options, Match Length, Teams – Rank and Collective Skill, League Table
I decided to focus on the mechanics first, and worry about the desired features of the OE later. In five days I will be lucky to even get them up and running!
Mechanically I started with the core concept of possession. A whole game of football could be played without a single pass really; I thought that perhaps a successful tackle can be seen simply as the exchange of possession from one team (Getting the ball into a goal area being the final objective of the game).  This gave me somewhere to start with the design of the code for individual avatars (players) – I quickly mocked up the below model for possession exchange.

Calvin and Hobbes both very happy with the tackling system I created on the first day!

Using OnTriggerEnter() it was easy enough to make a player in possession lose the ball if an opponent moves into their associated collider.

I thought about how to make sure that the ball would not flit between opposing players during contact, which led to the idea of a “dazed” status that a recently tackled player would adopt. During that state they would be unable to move or gain possession on the ball.

Simple beginnings yes… and at this stage I hadn’t even designed a concept of ‘time’ in this world of leatherbound pigs bladders! But it paved the road for the next step of designing the player script architecture.

I refreshed my understanding of Interfaces and created a seperate C# script defining necesary functions that my PlayerBallController script would need to include. These were things like public interface IRunner(), public interface IPasser(), public interface ITackler(), public interface ILosePossession() etc. After adding the interfaces to the class definition of PlayerBallController I created some other functions that would call the interface-defined functions when needed. A few examples:

    public void CheckPossession()
    {
        if(pState == PossState.InPoss)
        {
            Dribble();
        }
        else if (pState == PossState.NoPoss)
        {
            Run();
        }
    }
    
    public void MoveBallToFeet()
    {
        ball.gameObject.transform.position = feetMarker.transform.position;
    }
    
    public void KickBall(KickType kType)
    {
        switch (kType)
        {
            case KickType.Pass:
                Pass ();
                break;
            
            case KickType.Shoot:
                Shoot ();
                break;
        }
    }

Dribble() Run() Pass() Shoot() are all required by the interface defintitions. I didn’t know how I these functions would act, however at this stage I didn’t need to : the structure was at least taking a nice form.

By now I’d also began to think about the OE and how I’d actually enjoy augmenting the tactical element of the game. It hit me that I could make a turn-based football game with one-off challenges (individual set pieces, phases of play,  skill shots etc) that someone playing the game would be ranked on based on how many win/fail conditions they activate.

http://soccersweep.com/wp-content/uploads/2013/12/tactics-board1-620x350.jpg

This new direction meant I immediately had some classic aesthetics to draw from (i.e. the tactical field-of-play board with it’s arrows, circles and crosses) and was more akin to the Football Manager than my initial sources. It goes against my original desire to make a pure backyard kickaround game, but I feel that this is something I can revisit after pursuing a genuninely interesting idea – making a football puzzle-game. Thinking I could take this challenge on I went about cannibalising my concept.

From this perspective the game needed to have a overarching turn manager and a way of communicating tactical decisions made by the player of the game to that manager. I remembered this exceptionally useful Notification Center C# script from Alan Thorn’s resource list (http://wiki.unity3d.com/index.php?title=CSharpNotificationCenter) that allows for ONESHOT messages to be sent to any other scripts. Its use is beyond the above

For example; I want to tell a player in possession to shoot i.e. call the Shoot()  function, but only when I have clicked an ACTOUTINSTRUCTIONS button. This would be simple to do with a OnMouseDown() function. But now let’s say that the ACTOUTINSTRUCTIONS has to trigger all of the other additional moves that other players will make. OnMouseDown() now needs to communicate with many players and their functions. Using bools and a forever-listening Update() is a painful waste of time, but the NotificationCenter() script allows us to add a simple line of code to send a global message to any designated listeners.

    
    public void Pass()
    {
        pState = PossState.NoPoss;

        Hashtable playDir = new Hashtable();                 
        playDir[0] = FindPlayerDirection();                          
        NotificationCenter.DefaultCenter.PostNotification(this, "ApplyForceToBall", playDir);

    }

“ApplyForceToBall” is the name of a function in the listening script which will be called when it receives a posted notification. The code lower down the page shows the AddObserver function being called in the Start() method. And that’s all that’s needed to accept a message! Such an elegant solution to calling oneshot functions!

What’s more, the above line of code in red shows that you can (but don’t necessarily have to) send a Hashtable containing any data you want with the message, and any listeners will be able to access an instance of that data! For example a snapshot of the player’s direction, or perhaps their stamina, that is passed through to ApplyForceToBall().

Interestingly I found that Unity was kicking up a lot of errors about sending this data… and it turned out that a function called by the notification, such as ApplyForceToBall(),  can only accept an argument of type Notification. For some reason I couldn’t access this type, even though it was public in the NotificationCenter script! This cause you issues too? Well my solution was to reference NotificationCenter.Notification as the argument type. This worked, woop! Then converting the Notification format into a useable form requires you to access the Hashtable type using DictionaryEntry.

void Start () 
    {
        NotificationCenter.DefaultCenter.AddObserver(this, "ApplyForceToBall");
    }
    
void ApplyForceToBall(NotificationCenter.Notification vector)
    {
        Vector3 dir = Vector3.zero;
        foreach (DictionaryEntry entry in vector.data)
        {
            dir = (Vector3)entry.Value;
        }
        gameObject.rigidbody.AddForce(dir);
        print ("Ball receives a force of " + dir);
    }

Check out this link to learn more about DictionaryEntry and Hashtables. By the way if my Hashtable contained more than one keypair I’d make the dir variable an array.

Okay I’m going to stop with this post and come back for another check up later tonight! More to come from the design and aesthetics front, including a look at Editors, OnValidate() and Unity’s new UI system! 😀

~Peace

Leave a Reply

Your email address will not be published. Required fields are marked *