Search Unity

Question Techniques for simulating a system that relies on time passing when fast forwarding

Discussion in 'Scripting' started by PaperMouseGames, Jun 16, 2020.

  1. PaperMouseGames

    PaperMouseGames

    Joined:
    Jul 31, 2018
    Posts:
    434
    Hi there! So I'm working on a system for my RPG where you will be able to assign a party member to a training station and train them.

    The game uses an active 24 hour clock similar to games like Stardew Valley or Skyrim where the minutes are ticking away.

    So what's happening now is that as the NPC trains at the training station I am slowly increasing the NPC's strength in the Update method.

    I also have another system that makes it so that when the NPC gets hungry, they go eat for a few minutes and then return to their station. So the strength increase is paused while the NPC goes to get some food, and keeps going when they return to the training station.

    All of that works well, but when the player goes to sleep and moves time forward X amount of hours, I have no way of calculating just how much training the NPC did. I can't really use the update method for this calculation anymore since I'm now moving forward by chunks of time (i.e. I'm setting the clock forward by the amount of hours X rather than waiting for it to update naturally).

    The simplest solution I can think of would be to figure out how much the NPC can train in 1 uninterrupted hour and just multiply that by the amount of hours passed.

    The problem that brings up is that it means that the NPC is more efficient when the player is not playing (e.g. when the player sleeps) so that's not ideal, because it means that the player is incentive to just "fast-forward" time to get the most out of the training.

    I could add a penalty to the training that gets done when time is "fast-forwarding" so that it's something like 75% of the usual training effectiveness, but I'm just curious if anyone has any more interesting solutions to something like this.
     
  2. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,187
    I don't really understand when you talk about "fast forwarding". If you have a time stamp and you calculate the difference between that time stamp and what the new time is, you should be able to get the value of what the npc should have.

    Why would there be a difference in the training amount? What do you mean by "fast forwarding"?

    Idle games most likely work on a similar concept, possibly getting their time from a server, but even if it's a device time, and it's say 8pm, then if they close the app and open it again at 10pm, you calculate 2 hours of whatever is suppose to happen. If the user changes the time to 10pm, then if it's a single player game where there is no impact on you (ie, you aren't giving them free stuff they would normally pay for) then that may not matter, let them fast forward.
     
    PaperMouseGames likes this.
  3. raarc

    raarc

    Joined:
    Jun 15, 2020
    Posts:
    535
    I first want to say that I am also interested in this kind of mechanic for my game, so I would also like to hear other people's opinions.

    What I would add is that an incentive to prevent the player from sleeping through is that then the player character will be weak since he didn't train. You can also add calculations taking into account that the npc also has to sleep, and spending resources like food which the player is not gathering if he is just sleeping.
     
    PaperMouseGames likes this.
  4. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,909
    Presumably you have some training rate. For example, the NPC gains some amount strength every X seconds. So you would say the NPC has a training rate of N strength per second. Therefore to calculate the amount of strength the NPC gains you just need to multiply N by the time that has passed, and add it to the NPC's current strength:
    NPC.strength = NPC.trainingRate * timeElapsed


    It seems to me that the only difference between your Update method training and when the player "goes to sleep" is the amount of time that has elapsed. So you should just be able to plug in the player's sleep time as the elapsed time for the NPC training instead of Time.deltaTime.
     
    PaperMouseGames likes this.
  5. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    You could probably process a large number of smaller time chunks for the NPC very quickly as long as you're not doing graphics or physics for each one (not sure what's in your NPC's update function, but it's probably a lot faster than everything UnityEngine does behind the scenes every frame).

    Alternately, instead of assuming that your NPC is only doing one activity each Update, you can calculate how long it should be before the NPC has to stop and do something else, and if that's less than the amount of time that passed, allocate just that amount of time to the current activity and then re-evaluate with the remaining amount of time and the next activity the NPC should do.

    Or you can just fudge things like you already described. I seem to recall reading that Stardew Valley had a bug for quite a while where when the player was sleeping, stuff on the farm experienced 100 minutes of time per hour of sleep (i.e. some time conversion that was used only while the player was sleeping accidentally multiplied by 100 instead of 60) and most players didn't really notice.
     
    PaperMouseGames likes this.
  6. PaperMouseGames

    PaperMouseGames

    Joined:
    Jul 31, 2018
    Posts:
    434
    Thanks to everyone who already replied! Already getting some ideas to start experimenting.

    Just to clarify, the system I have for moving forward hours (as i, when the player sleeps) works like Stardew Valley or waiting in Skyrim, where you hit a button and it goes from being, say 10pm, to something like 6am

    I tried making it so that when the player sleeps, the NPC simply trains for X uninterrupted hours where X is the amount of hours the player slept. But like I mentioned, this bring sup the issue, that the NPC is more efficient when the player "isn't looking" so to speak, since the NPC doesn't walk to go get food, or take any kind of breaks.

    It's sounding like the best solution to that might be to just go with a simple penalty to offset that. On the player end it might not even be noticeable as Antistone mentioned, since there is a bit of RNG (e.g. strength isn't going up by 10 point per hours but rather something like 8-12 points per hour to simulate breaks).

    I would still love to know if there is a way to properly simulate those food breaks in the background out of curiosity, so if anyone has ideas on how you would simulate events that normally involve gameObjects moving around, playing animations, and then going back to what they were doing all in the background (i.e. not with graphics or relying on animation times), please feel free to chime in.

    Ultimately though, I'm not really working on a complex stimulation game so it's likely outside the scope of what I'm doing.