Time Played

Talk about the mods you'd like to see in Daggerfall Unity. Give mod creators some ideas!
Post Reply
User avatar
Corsair
Posts: 26
Joined: Thu Nov 21, 2019 3:00 pm
Location: USA

Time Played

Post by Corsair »

Is it possible to implement a "time played" in the load screen? I'm rather fond of things like Steam's game counter and how Skyrim showed time played per character saves; it's a little thing, but I sure enjoyed seeing how long I'd invested in a character, etc. Even Morrowind has it now, so I'm surprised DFU doesn't... is this an engine limitation or just a matter of future implementation?

User avatar
Ralzar
Posts: 2211
Joined: Mon Oct 07, 2019 4:11 pm
Location: Norway

Re: Time Played

Post by Ralzar »

Hm, maybe as part of the save info? So you can see it in the save/load screen? Could be handy to keep track of where saves are chronologically to eachother.

User avatar
pango
Posts: 3358
Joined: Wed Jul 18, 2018 6:14 pm
Location: France
Contact:

Re: Time Played

Post by pango »

Such info is not currently tracked, so it cannot be displayed, but I see no reason why it couldn't be done.
Currently all what's tracked, as far as I can tell, is the real world time and game time when each save was done.
Even if each character starts at the same game time, it is a poor indicator for time played, because game time flows at different rates when resting, loitering, or fast traveling...

By the way I'm not familiar with other implementations of such statistics, do they count how much time was spent on each character in total, including progress that was never saved or was abandoned, or just the time spent on current character state (what I'd call "current continuous history" of the character)? Or both?

It seems Skyrim and mods are tracking a lot of statistics. I guess that if such stuff is implemented, it should be open to modding...
Mastodon: @pango@fosstodon.org
When a measure becomes a target, it ceases to be a good measure.
-- Charles Goodhart

User avatar
Ralzar
Posts: 2211
Joined: Mon Oct 07, 2019 4:11 pm
Location: Norway

Re: Time Played

Post by Ralzar »

I would imagine it would be time spent on current character state. But now that you bring it up, total time could be fun to know.

User avatar
Corsair
Posts: 26
Joined: Thu Nov 21, 2019 3:00 pm
Location: USA

Re: Time Played

Post by Corsair »

Yeah, I was thinking real world hours played, not in-game, but that sounds cool as well. But it would help with chronological orders as well; sometimes multiple saves at the same guild aren't that helpful.

l3lessed
Posts: 1403
Joined: Mon Aug 12, 2019 4:32 pm
Contact:

Re: Time Played

Post by l3lessed »

Well, thanks to the time I dumped into trying to understand animation timing I 've worked with the coding this would involve. This could be done pretty easily by a decent coder/scripter.

You would create a simple script file to setup, track, assign, and store the time played value.

In the script, you would use the unity "Time.time" function to initiate a timer seperate from the game render engine to track how much time has passed since the beginning of a play session, assign it to a value like "playedTime", hook that to the entity reference needed for the type of time your tracking, so it is stored through play sessions, and then hook that value into the UI through proper coding hook. If you want play session total until the game/engine is closed, this base scripted can be attached to the player entity and everything stored within the script file. If you want to track total time over multiple play sessions, you would need to save the playedTime var outside of the game, in say a text, ini, or pref file, on application quit and then retrieve and update it on engine initiation.

If anyone is interested in hammering this out, here is the unity documentation:
https://docs.unity3d.com/ScriptReferenc ... 1565636508
https://answers.unity.com/questions/877 ... -time.html

Simple code example to build from. From here just decide what time needs to be tracked and set it up. If its played hours total, hook the value to a permanent variable that can be pulled, added to, and resaved. If its a session timer, then initiate the value in the below script file itself, read and write to it, and then when the script/play session is over, it resets.

Code: Select all

 var playedTime : float;
 var timeDisplay : GUIText;
 
 function Start(){	
     //If all we want is individual session play time, this works here as is; will reset every time script is
     //initiated at beginning of play session. However, if we want this total playtime over the whole
     //games install, this needs moved out of here and stored as a private variable that once initiate
     //it will not be reset, so total time can be read, updated, and saved, even between play sessions.
     playedTime = 0.0;
     
     //sets the waittime for the script to be updated. Used to limit script load.
     waitTime = 1f;
     
     //starts the below Coroutine. We use a Coroutine to save on processor cycles and overhead.
     StartCoroutine(TimePlayedCounter());
 }    
 
IEnumerator TimePlayedCounter()
{
	//use Time.time to ensure play time recorded is not affected by frame rate render speeds.
	playedTime += Time.time;
	
	//turn the time into a display text
	timeDisplay.text = Mathf.RoundToInt(playedTime).ToString();
	
 	//wait this many seconds before updating playtime script and value.
	yield return new WaitForSeconds(waitTime);
 }
My Daggerfall Mod Github: l3lessed DFU Mod Github

My Beth Mods: l3lessed Nexus Page

Daggerfall Unity mods: Combat Overhaul Mod

Enjoy the free work I'm doing? Consider lending your support.

User avatar
Corsair
Posts: 26
Joined: Thu Nov 21, 2019 3:00 pm
Location: USA

Re: Time Played

Post by Corsair »

Glad to see it can be done! *fingers crossed that it tempts someone to make it*

User avatar
pango
Posts: 3358
Joined: Wed Jul 18, 2018 6:14 pm
Location: France
Contact:

Re: Time Played

Post by pango »

You probably want to sum up Time.unscaledDeltaTime, because time scale is sometimes changed (for example during Tedious Travel).

But it could even be made to have no runtime cost and have the same precision as system time (even if running a coroutine every second should be very cheap already):

Set playTime to 0 when you start a character, or read it from gamesave when reloading a game.
Then store current system time when player gets control back.
The live playTime from now on is playTime + current system time - recorded system time; That's what you can display, and use when writing gamesaves.

And if you want to track total time spent on character, use the exact same algorithm but store playTime in a separate per-character file instead of gamesaves. You'll probably need to update that file in other additional places (when dying, before reloading, exiting game, or just periodically if you expect the game to be stopped more violently...)
Mastodon: @pango@fosstodon.org
When a measure becomes a target, it ceases to be a good measure.
-- Charles Goodhart

l3lessed
Posts: 1403
Joined: Mon Aug 12, 2019 4:32 pm
Contact:

Re: Time Played

Post by l3lessed »

Well, if the person is wanted it like steam, play time is recorded from the moment the game is launched until it ends; at least I thought that. If that is the case, this needs to be ran from the moment the game main menu starts to when the exe ends. So, just needs initialized with the start instead of on a character load.

Also, if the player wants live feedback/updates of total play time, no matter where they are in the game, wouldn't a Coroutine be needed, as the current method using save files would only update on saves and loads, right? If the player doesn't want a live UI update for this, then yes, recording it on save and load would be the most efficient way. Could also increase efficiency by tying it into an inventory UI component so it only gets called when the player opens a UI object that reads it out. Just depends on when they want to see the numbers.

Anyways, nice eye on the time. Here, I updated the below script little more based on the above discussion.

Code: Select all

var playedTime : float;
 var timeDisplay : GUIText;
 
 function Start(){	
     //If all we want is individual session play time, this works here as is; will reset every time script is
     //initiated at beginning of play session.
     playedTime = 0.0;

   //records the total time of all play sessions. Needs stored as a private var outside script if wish
   //to record total time played between each session. If not, this will work to record session play time.
   //would need to reference an outside stored value if you wanted total play time.
    totalTime = 0;
     
     //sets the waittime for the script to be updated. Used to limit script load.
     waitTime = 1f;
     
     //starts the below Coroutine. We use a Coroutine to save on processor cycles and overhead.
     //Coroutine is only needed if we want live UI feedback on this. If not, should be hooked to a
     //trigger event, like on load, on save, opening a UI interface, ect.
     StartCoroutine(TimePlayedCounter());
 }    
 
IEnumerator TimePlayedCounter()
{
	//use Time.unscaledDeltaTime; separate from timescale.
	playedTime += Time.unscaledDeltaTime;
	
	//total time played. This equation will work for either a session total time or a total time played.
	//ensure the above totalTime var is set based on which one you wish to record.
        totalTime = playedTime + (Time.unscaledDeltaTime - totalTime);
	
	//turn the time into a display text
	timeDisplay.text = Mathf.RoundToInt(totalTime).ToString();
	
 	//wait this many seconds before updating playtime script and value.
	yield return new WaitForSeconds(waitTime);
 }
My Daggerfall Mod Github: l3lessed DFU Mod Github

My Beth Mods: l3lessed Nexus Page

Daggerfall Unity mods: Combat Overhaul Mod

Enjoy the free work I'm doing? Consider lending your support.

Post Reply