Question

I'm making a text-based RPG, and I'd really like to emulate time.
I could just make some time pass between each time the player types something, but id like it to be better than that if possible. I was wondering if multithreading would be a good way to do this.

I was thinking maybe just have a second, really simple thread in the background that just has a loop, looping every 1000ms. For every pass though its loop the world time would increase by 1 sec and the player would regenerate a bit of health and mana.

Is this something that multithreading could do, or is there some stuff i don't know about that would make this not work? (I'd prefer not to spend a bunch of time struggling to learn this if its not going to help me with this project.)

Was it helpful?

Solution

Yes, mutlithreading could certainly do this, but be weary that threading is usually more complicated than the alternative (which would be the main thread polling various update events as part of its main loop, which should be running at least once every 100ms or so anyway).

In your case, if the clock thread follows pretty strict rules, you'll probably be "ok."

  1. The clock thread is the only thread allowed to set/modify the time variables.
  2. The main/ui thread is only allowed to read the time.
  3. You must still use a system time function, since the thread sleep functions cannot be trusted for accuracy (depending on system activity, the thread's update loop may not run until some milliseconds after you requested it run).

If you implement it like that, then you won't even need to familiarize yourself with mutexes in order to get the thread up and running safely, and your time will be accurate.

But! Here's some food for thought: what if you want to bind in-game triggers at specific times of the day? For example, a message that would be posted to the user "The sun has set" or similar. The code needed to do that will need to be running on the main thread anyway (unless you want to implement cross-thread message communication queues!), and will probably look an awful lot like basic periodic-check-and-update-clock code. So at that point you would be better off just keeping a simple unified thread model anyway.

OTHER TIPS

I usually use a class named Simulation to step forward time. I don't have it in C++ but I've done threading in Java that is stepping time forward and activating events according to schedule (or a random event at a planned time). You can take this and translate to C++ or use to see how an object-oriented implementation is.

package adventure;

public class Simulation extends Thread {

    private PriorityQueue prioQueue;

    Simulation() {
        prioQueue = new PriorityQueue();
        start();
    }

    public void wakeMeAfter(Wakeable SleepingObject, double time) {
        prioQueue.enqueue(SleepingObject, System.currentTimeMillis() + time);
    }

    public void run() {
        while (true) {
            try {
                sleep(5); 

                if (prioQueue.getFirstTime() <= System.currentTimeMillis()) {
                    ((Wakeable) prioQueue.getFirst()).wakeup();
                    prioQueue.dequeue();
                }

            } catch (InterruptedException e) {

            }

        }
    }

}

To use it, you just instantiate it and add your objects:

 `      Simulation sim = new Simulation();

        // Load images to be used as appearance-parameter for persons
        Image studAppearance = loadPicture("Person.gif");

        // --- Add new persons here ---
        new WalkingPerson(sim, this, "Peter", studAppearance);

I'm going to assume that your program currently spends the majority of its time waiting for user input - which blocks your main thread irregularly and for a relatively long period of time, preventing you from having short time-dependant updates. And that you want to avoid complicated solutions (threading).

If you want to access the time in the main thread, accessing it without a separate thread is relatively easy (look at the example).

If you don't need to do anything in the background while waiting for user input, couldn't you write a function to calculate the new value, based on the amount of time that has passed while waiting? You can have some variable LastSystemTimeObserved that gets updated every time you need to use one of your time-dependant variables - calling some function that calculates the variable's changed value based on how much time has passed since it was last called, instead of recalculating values every second.

If you do make a separate thread, be sure that you properly protect any variables that are accessed by both threads.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top