1
\$\begingroup\$

So, the question is a bit broad, but I need to clarify my ideas about how to use proficiently such tools.

Background: I am writing a simple demo that basically does what simcity does: it start a game, create a player entity, a city entity, set up the various electricity/gas/water services and generic bozo that will be part of the population of the city. On top of that, the game spawn X competitors, each with a city on their own, so there is a sense of urgency in having the city up and running, and have it running properly.

This is by no mean a sim city clone; I am just using it to learn further the various aspects of a game, and since I know sim city in and out, and there is virtually no specific material for such games (because all love to do either 2d games, FPS, RPG or RTS, even in training material), it seems the best way to learn something related to the real world.

Now, done with the background and back to the question.

The demo start when you create a new game, spawn all the needed entity, and tehn goes on by cycles; where one cycle can be either 1 min, 5 min, 1 hour...whatever time you deem correct. When a cycle pass. I need to be sure that

  • The player expenses are deducted by the bank account
  • UI is updated
  • AI players has their expenses subtracted and cash updated
  • AI entities behave coherently, either driving around the city or going back home (imagine a night-day cycle).

In the beginning I just told myself that I could use a coroutine; where I loop into it, until each entity (AI, Player, AI citizens), are done with their workload, and when all 3 are done, I change a bool to set the coroutine bool to false, so a new cycle can start.

public class EntityCitizen()
{
    public bool runCitizenloop()
    {
        //do your things here
        return true;
    }
}

public class EntityPlayer()
{
    public bool runPlayerloop()
    {
        //do your things here
        return true;
    }
}

public class EntityAIPlayer()
{
    public bool runAIloop()
    {
        //do your things here
        return true;
    }
}

public class GameManager()
{ 

    private cycle = 0;

    public Awake()
    {
         StartCoroutine("cycleloop", 10f);
    }

    IEnumerator cycleloop(float cyclelenght)
    {
        while (!EntityAIPlayer.runAILoop() && !EntityPlayer.runPlayerLoop() && !EntityCitizen.runCitizenLoop())
        {
            // wait until all is done
            yield return void;

        }
        Debug.Log("A cycle has passed");
        cycle += 1;
    }
}

This feel somehow off to me, so before code a mess, I thought that it is better to think further about it. I realized that C# has delegates and events; which I could use to trigger the other way around, activities and updates on the various agents; every time that a cycle in the coroutine is done.

But even in this way, I see that something is off; the whole game cycle revolve around each entity completing their actions, and this means that somehow, they have to execute at the same time in parallel (so use coroutines), and also they have to happen in sequence (since an AI mayor can't have more turns than a player, just because he is faster).

What would be the correct way to lay down the overall architecture, to guarantee that each entity is finishing their workload, before that a new cycle may start?

I thought of coroutine for each entity, with events that fire once they are done, which trigger the new cycle in the main coroutine. Would that be correct or am I missing something?

\$\endgroup\$
  • 1
    \$\begingroup\$ "they have to execute at the same time in parallel (so use coroutines)" just to caution against a common misconception about coroutines: they're not running "parallel" per se, but sequentially on the main thread, the same as Update. They're useful for managing execution over time, but if you're specifically trying to spread the work between threads, coroutines aren't the answer. \$\endgroup\$ – DMGregory Feb 21 '16 at 13:07
  • \$\begingroup\$ Then the approach with coroutine is not working. I may try creating different threads; syncing them with the main thread in the coroutine. From what I read, it seems that Unity has issues with multithreading, only if you use the main classes from the Unity namespace; so everything has to run on the main loop. Will investigate further in that direction. \$\endgroup\$ – rataplan Feb 21 '16 at 23:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.