Using custom game time for FactionMember memory durations

Announcements, support questions, and discussion for Love/Hate.
tylerwsavatronix
Posts: 33
Joined: Tue Jul 05, 2016 6:18 pm

Using custom game time for FactionMember memory durations

Post by tylerwsavatronix »

I was reading through the manual, and noticed that short term memory, long term memory, and PAD stabilization (and probably a few other things) use actual time to tick down.

We have our own time concept, basically scale of regular time, but it's variable (for example it can be slower inside buildings than when outside). We also have two different pauses, a full pause which also sets TimeScale to 0, and a game time only pause, which only pauses our custom game time.

Additionally, our game is similar to Harvest Moon/Rune Factory in that things are heavily reliant on the day. In fact if the player stays awake till a certain time, they'll pass out (meaning there's about 6 - 8 hours of every game day that don't actually happen). We use the "day skip" to reset some things, and set up other things.

I'd like to, instead of using real time, use our game time (or more specifically game days) for short term memory and long term memory, and reset the PAD every day. Ideally short term memory would be 1 or 2 game days, and long term memory would be 1 or 2 game weeks.

Given that game time can be paused independently of real time and also can be variably scaled, what would you say the best way to achieve this effect with FactionMembers would be?

Thanks!
User avatar
Tony Li
Posts: 22093
Joined: Thu Jul 18, 2013 1:27 pm

Re: Using custom game time for FactionMember memory durations

Post by Tony Li »

Hi Tyler,

The Greeting Trigger and Gossip Trigger components also use Unity's Time class.

I'll release an update to Love/Hate by the middle of next week that lets you specify a custom time, similar to what the Dialogue System does with its DialogueTime class. The Dialogue System's DialogueTime class, btw, is getting an additional option for custom time that your own code can set. The current version just lets you specify game time (Time.time) or realtime (Time.realtimeSinceStartup). I'll also make sure Love/Hate does the same.
tylerwsavatronix
Posts: 33
Joined: Tue Jul 05, 2016 6:18 pm

Re: Using custom game time for FactionMember memory durations

Post by tylerwsavatronix »

Thanks! That'll be very useful!
User avatar
Tony Li
Posts: 22093
Joined: Thu Jul 18, 2013 1:27 pm

Re: Using custom game time for FactionMember memory durations

Post by Tony Li »

Love/Hate 1.83 is now on the Asset Store with support for custom time. (See the GameTime class.)
tylerwsavatronix
Posts: 33
Joined: Tue Jul 05, 2016 6:18 pm

Re: Using custom game time for FactionMember memory durations

Post by tylerwsavatronix »

Thanks!

It's been a couple months, but I'm about to start actively integrating Love/Hate with our game. Had to focus on some other areas and some heavy refactoring the last couple of months >.<

Lots of interesting stuff, and an actual game that we can show off is starting to take form!

http://www.savatronix.com/dev-blog
User avatar
Tony Li
Posts: 22093
Joined: Thu Jul 18, 2013 1:27 pm

Re: Using custom game time for FactionMember memory durations

Post by Tony Li »

Thanks for sharing your blog link! I tip my hat to you for having the discipline to make sure your first milestone is code complete before getting too involved in content creation. So many unfortunate projects get deep into content creation before they realize they have a technical/coding issue that requires major overhauls. I'm looking forward to reading more blog posts on Lost Haven!
tylerwsavatronix
Posts: 33
Joined: Tue Jul 05, 2016 6:18 pm

Re: Using custom game time for FactionMember memory durations

Post by tylerwsavatronix »

Tony Li wrote:Thanks for sharing your blog link! I tip my hat to you for having the discipline to make sure your first milestone is code complete before getting too involved in content creation. So many unfortunate projects get deep into content creation before they realize they have a technical/coding issue that requires major overhauls. I'm looking forward to reading more blog posts on Lost Haven!
It probably helps a lot in that space that I come from the Enterprise/Business development world, heh.
tylerwsavatronix
Posts: 33
Joined: Tue Jul 05, 2016 6:18 pm

Re: Using custom game time for FactionMember memory durations

Post by tylerwsavatronix »

After beginning on the integration, I realized custom time probably won't actually work out, particularly around long and short term memory. I'm also not all that sure what else, under the hood, is affected by the time.

The main reason it won't work though is that in our game, things like memory loss for rumors should happen when one game day transitions to the next. It's not a straight 24 hours; the player can stay up too X time (2, 3, 4 am, whatever we set it) before being forced unconscious and the transition happening (that is the transition only happens when the player character falls unconscious, willingly or otherwise).

Since the player can go to bed either before or after midnight, we wouldn't want NPCs to suddenly forget older rumors right at the stroke of midnight (which is what would happen if we set short and long term memory to the exact amount of seconds in a day). That could lead to some rather odd dialogue and AI decision making down the road.

Is there instead a way to manage that process manually?

In theory I'd like to write code to specify an arbitrary number of our game days for the memories to last, and during the nightly transition clear out expired memories.
User avatar
Tony Li
Posts: 22093
Joined: Thu Jul 18, 2013 1:27 pm

Re: Using custom game time for FactionMember memory durations

Post by Tony Li »

Hi,
tylerwsavatronix wrote:In theory I'd like to write code to specify an arbitrary number of our game days for the memories to last, and during the nightly transition clear out expired memories.
Try this:

1. Set GameTime.mode to GameTimeMode.Manual. GameTime affects three things:
  • The memory cleanup frequency (which we'll address below),
  • StabilizePAD, and
  • The minimum duration between fires of GreetingTrigger, GossipTrigger, and AuraTrigger.
You can control GameTime by setting GameTime.time. (GameTime.deltaTime and GameTime.isPaused are also settable if you want to use them for anything.)

If you're using GreetingTrigger et al., you can write your own subclass of AbstractGreetingTrigger to check the minimum duration your own way, and then call TryGreet.

StabilizePAD uses GameTime.deltaTime. If you're using StabilizePAD, you can set this as appropriate for your setup.

2. On your FactionMember, disable automatic cleanup by calling FactionMember.StopMemoryCleanup() after enabling the FactionMember. In the next release, if memoryCleanupFrequency is 0, it won't run automatic cleanup at all. For example, a script with this method should do it:

Code: Select all

IEnumerator OnEnable() {
    yield return null; // Wait 1 frame for FactionMember.OnEnable to finish.
    GetComponent<FactionMember>().StopMemoryCleanup();
}
3. Add a script that implements the IRememberDeedEventHandler event method. In the method, set Rumor.shortTermExpiration and Rumor.longTermExpiration to the days at which they should expire out of short-term and long-term memory. Something like:

Code: Select all

void OnRememberDeed(Rumor rumor) {
    rumor.shortTermExpiration = GameTime.time + 2; // In short-term for 2 days.
    rumor.longTermExpiration = GameTime.time + 7; // And long-term for 7 days.
}
You actually may not need to do this, depending on your needs. You can use the inspector to set FactionMember.shortTermMemoryDuration and longTermMemoryDuration to, say, 2 and 7 respectively, and let Love/Hate handle it automatically. However, if you do this, keep in mind that it will scale the actual expiration time by the change in affinity to the actor. So if the deed results in a 50% change in affinity to the actor, the expirations will be 1 day and 3.5 days. This allows less impactful memories to expire faster.

4. At the end of each day, increment GameTime.time, and call FactionMember.CleanMemory():

Code: Select all

void GoToNextDay() {
    GameTime.time += 1;
    foreach (var factionMember in FindObjectsOfType<FactionMember>()) {
        factionMember.CleanMemory();
    }
}
tylerwsavatronix
Posts: 33
Joined: Tue Jul 05, 2016 6:18 pm

Re: Using custom game time for FactionMember memory durations

Post by tylerwsavatronix »

Thanks Tony,

It sounds like #2 is only a temporary measure until the next release; do you have a rough ETA on that (If it's in the next few weeks then I can probably wait on that step specifically).

For Gossip and Aura I'm assuming we'll need to take similar steps as with Greeting (implement an AbstractXTrigger), is that accurate?

I think we are going to use StabalizePAD (at least initially, need to see it in action and do some prototyping of our personalities and see them in action). I haven't looked too much into it, but it looks like if we'll just need to set the ChangeRate for each one and treat it as days.

Question though, if we were to say, set changerate to .5 (since it looks like that's a float) yet increment GameTime by 1, would it run twice (which would be desired in our case)? If I understand StabalizePAD correctly it slowly, over time, seeks to stabalize back to target values, but doesn't do it all in one go.
Post Reply