How to best organize bool variables and code modularity in general?

Hi there!

I’m making my first “serious” attempt to make a game in Unity. Along the way, i’m learning how to improve my basic C# programming skills, getting to know the particular ways in which Unity behaves, etc.

I’ve managed to create a isKinematic movement for my player, also my own physics collision system for static colliders (checking what’s below and above the player, to the sides, etc) and moving platforms (i can stay on the platform and move and even jump quite well).

It has taken my a lot of time to do this, about 4 weeks since I started working on my free time after work and weekends, but i’m happy to have kept progressing little by little by solving unforeseen challenges (for me they are =)).

So now comes the question:
My player script starts getting longer and longer. There i have the movement and collision system, and it’s there were i check if the raycasts have hit any other object by asking their tag (i’m not using onTrigger functions as I prefer to go for preventive physics) and how the player should act.

As you may imagine, or maybe it’s my lack of expertise in programming, i have LOTS of bools for any given situation. Some examples:

  • if player is not grounded and hits something when start jumping.
  • the same for when the player is going down on his jump.
  • check if I hit a static collider with the head and if it’s so do not jump the maxJumpHeigh but only a portion.
  • if it’s not grounded and i hitted a moving platform while the platform is going up.
  • the same for when is going down.
  • etc, etc, etc.

When i have a bug or wrong behaviour with movement or collisions, i need to go through all these bools, and each small change it’s painful as there are many bool combinations i must take into account.

  • So, is there a way to keep the bools organized, kind of a bool manager in a separate script?
  • Do you also use so many bools in your code, or i’m I doing something wrong? Is this the price one must have to pay to have a solid movement and collision system and be able to handle the most complex gameplay combinations?
  • If I create so many scripts to make things more modular, won’t it be too painful and too verbose to refer to so many bools (and variables in general) in the shape of thisClassScript.thisMethod.thisVariable?

I’ve never used any game manager and to be honest I don’t know where and how to start using it. I keep reading about the topic and also the dangers of using global static variables, (there should be only a few in the total code to follow encapsulation or proper OOP methodology they say)… i’ve never used delegates or virtual functions either yet (maybe I’m having the need but I haven’t realize it yet!)… i’m wondering if things are getting more complicated because I actually yet don’t understand fully how OOP works and all the possible solutions C# offers.

Any advice for the bools organization, links you think can clear out my existencial doubts (some of those are too complex for beginners) will be more than welcome. =)

Hey @stalyan77

What you’re talking about is a very common problem, and a popular solution is to employ a state machine:

http://gameprogrammingpatterns.com/state.html

A state machine will use polymorphism to avoid crazy conditional statements, and help you compartmentalize your logic.

You’re definitely on the right track with your follow up research. You’ve found that bools are good for local logic but get unwieldy when used for the interaction of more than a few objects. Static game manager classes are typically discouraged but can actually be perfectly viable in smaller games. If you are just making a small prototype to test your programming knowledge and to develop your skills you might actually want to start there, if only to learn more about static classes and how they work. Ultimately though, for a larger project you want something that allows your various objects to communicate in a decoupled fashion. In other words, in a way that allows you to change or delete the objects without disrupting the state of all the other objects in your game.

A common way of doing this is an event manager. Unity has a very good tutorial on the basics here. The principle of the system is that you have an intermediate static class that stores events, essentially collections of functions that are run when the event is called. In this way any number of objects can register functions for an event that a specific object (or objects) then calls, making it as though that object were calling all those functions itself. The power of the system is that if you should change the object to no longer call the event, say to have another object call it, or to remove one of the functions being called, only one object needs to be edited. This ‘decoupling’ prevents the huge amount of clutter that the bool and static class system present and offers a level of flexibility that is very helpful in the development process.

There is another advantage of more advanced event handler examples which is that they can take parameters for the functions in the event from the object that is calling the event. This can be very useful for passing information between scripts without having those scripts needing to know about each other. You can find many different event managers online but here is a basic example of one that takes 0-2 parameters:

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

public static class EventManager {

    public enum EVNT { MyEvent1, MyEvent2, MyEvent3 };
    private static Dictionary<EVNT, Delegate> eventTable = new Dictionary<EVNT, Delegate>();


    public static void AddHandler(EVNT evnt, Action action)
    {
        if (!eventTable.ContainsKey(evnt)) eventTable[evnt] = action;
        else eventTable[evnt] = (Action)eventTable[evnt] + action;
    }

	public static void AddHandler<T>(EVNT evnt, Action<T> action)
    {
        if (!eventTable.ContainsKey(evnt)) eventTable[evnt] = action;
        else eventTable[evnt] = (Action<T>)eventTable[evnt] + action;
    }

    public static void AddHandler<T, U>(EVNT evnt, Action<T, U> action)
    {
        if (!eventTable.ContainsKey(evnt)) eventTable[evnt] = action;
        else eventTable[evnt] = (Action<T, U>)eventTable[evnt] + action;
    }

    public static void Broadcast(EVNT evnt)
    {
        Delegate d;
        if (eventTable.TryGetValue(evnt, out d))
        {
            Action action = d as Action;
            if (action != null) action();
        }
    }

    public static void Broadcast<T>(EVNT evnt, T param)
    {
        Delegate d;
        if (eventTable.TryGetValue(evnt, out d))
        {
            Action<T> action = d as Action<T>;
            if (action != null) action(param);
        }
    }

    public static void Broadcast<T, U>(EVNT evnt, T param, U param2)
    {
        Delegate d;
        if (eventTable.TryGetValue(evnt, out d))
        {
            Action<T, U> action = d as Action<T, U>;
            if (action != null) action(param, param2);
        }
    }
}

It is very straightforward to use. Create an event in the EVNT enum then use EventManager.AddHandler(EventManager.EVNT.MyEvent, MyFunction); to register a function named MyFunction to be run when MyEvent is called. Finally use EventManager.Broadcast(EventManager.EVNT.MyEvent); to call the event. If you have a function with an int parameter it would be EventManager.AddHandler<int>(EventManager.EVNT.MyEvent, MyFunction); and EventManager.Broadcast<int>(EventManager.EVNT.MyEvent, 42);

I know that can look a bit intimidating for someone new to C# but it’s not too bad when it’s broken down. The events are defined in the enum EVNT { MyEvent1, MyEvent2, MyEvent3 }; which is basically just a universal label all the objects can use. The event table static Dictionary<EVNT, Delegate> eventTable is what stores the delegates (a variable that holds a function or functions) that get run when the event is called. The AddHandler function AddHandler<T>(EVNT evnt, Action<T> action) takes any type (represented by T here) and has parameters of an EVNT enum and an Action (a type of delegate) with a parameter of type T. This function just sets the delegate as that EVNT’s eventTable delegate or adds to it. Finally in Broadcast<T>(EVNT evnt, T param) the EVNT is looked for in the eventTable and if it’s there the delegate is run with the parameter T.

I think what you need to learn next are enums. Enums are basically named int values and they are fantastic for state behaviours.

So you can do something like this:

public enum States
{
    InAir,
    JustLanded,
    JustJumped,
    OnGround,
}

public States CurrentState;

public void Start()
{
    CurrentState = States.OnGround;
}

And then just change the value to the appropriate one.

Also, there are a few in there that seem superfluous. Ask yourself this: When I define a bool, will I use it in more than one function? If not, it likely does not need to be a class variable, and can just be defined in the function. You can also inline them if they’re only calculated and used once per frame. For example, instead of doing this:

private bool value;

void function()
{
    value = /*calculation*/;
    if(value)
    {
        ...
    }
}

You can do this:

if(/*calculation*/)
{
     ...
}

To do justice to your kind answers I’ve first tried to assimilate, at least up to my partial current knowlege and understanding, all the amazing knowledge you shared here before attempting a reply.

What you’re talking about is a very
common problem, and a popular solution
is to employ a state machine:

State · Design Patterns Revisited · Game Programming Patterns

I knew this site but hadn’t happened to read about FSMs, and as I was reading the examples of the Heroine, I felt much identified with it as it’s my current struggle. Even there were some things I didn’t catch fully as the examples are in C++, i grasped most of it. I was specially attracted by the last part about Concurrent, Hierachical State Machines and Pushdown Automata and I will investigate more about this topics.. Many thanks for sharing @VesubianPrime.

Ultimately though, for a larger project you want something that allows your various objects to communicate in a decoupled fashion. In other words, in a way that allows you to change or delete the objects without disrupting the state of all the other objects in your game. A common way of doing this is an event manager. Unity has a very good tutorial on the basics here.

I had once seen this video but didn’t fully grasped it. I also have been stumbling a lot about this “decoupling” thing when reading articles and to be honest i didn’t know what exactly was about. Now after reading about FSM and trying to understand better what the video says, I have things clearer (I guess =))

About the video, one of the interesting things is the remark and straightforward advice about using events over delegates if you have more classes that “do something”.

I also think that now the term “decoupling” is much clearer to me. So by “subscribing” and “unsubscribing” functions to events, you separate the functions themselves from the “call to action” to say so, correct me if i’m wrong. I like this concept and how it can relate to what is said in the FSMs link about encapsulating all the functionality in the same class instead of setting variables in other classes… (that’s what i need to achieve in my code now).

When I first read about the advanced event handle template you shared -without watching the video about events- I could barely understand anything…
So I watched the video first, and one thing that called my attention was that the event delegate and event itself must be void and accept no parameters… don’t know if this is a limitation of events or just the video example, i’ll investigate.
I went back to the code you posted and read it three times carefully, also your explanations, and I think i’ve grasped it a little bit better now.
**Correct me if I’m wrong, this advanced event handler has the advantage over regular events in that:

  • it accepts parameters and types.
  • there’s no need to unsubscribe so you reduce the danger of memory leaks and the worryness of having to explicitly unsuscribe under circunstances that you may not know until further in the development process.**

thanks @cjdev this sheds a bunch of light to my learning path ahead.

About enums, i guess you are right @FortisVenaliter, much of the problem is that i throw bools into the cookpot to solve problems along the way, then i find edge cases and I need to dismiss some bools and throw in others… so i’ll take a look back into my code and see if there are bools that cannot be more encapsulated.

  1. I’ll first think about enums and
    if it fits the needs of my game.
  2. I want to definitely try to go from
    theory to practice with FSMs and
    Events or event handlers. I’ll keep
    investigating and when I feel more
    confident i’ll give it a serious
    try.

I’m grateful guys, you’ve put me on the right track, I needed this feedback to keep going. =)

I know this thread is pretty old, but this was exactly what I needed to read. I have the same problems with a gang of bools sitting around and everyone’s answer was super informative and helpful. State Machines, Event Systems, Delegates, and decoupling.

It’s amazing these concepts aren’t discuss more in Unity tutorials. Instead everyone asks and teaches how to make complicated stuff before focusing on these core fundamental skills.

Thanks again everyone! <3 <3 @stalyan77 @cjdev @VesuvianPrime @FortisVenaliter