Roll20 uses cookies to improve your experience on our site. Cookies enable you to enjoy certain features, social sharing functionality, and tailor message and display ads to your interests on our site and others. They also help us understand how our site is being used. By continuing to use our site, you consent to our use of cookies. Update your cookie preferences .
×

[Script] TimeKeeper

1591019905

Edited 1591732000
I found myself wanting to track time in my game, along with expiries of things like Wild Shape, Invisibility etc . I wrote the following script to solve my problem. I thought I'd share, in case any of you would find it useful. If someone else already wrote a script like this, my apologies :P Also, I'm by no means an expert coder, so apologies for the perhaps less-than-beautiful code. <a href="https://github.com/HappyTapir/TimeKeeper" rel="nofollow">https://github.com/HappyTapir/TimeKeeper</a> The readme contains info on the commands, as well as some suggested macros. The actual script is in the TimeKeeper.js file. Comments and feedback are welcome! Future plans are to add functionality for the players to get time info and expiry info as well, although possibly in more vague terms than exact time. Edit: Here's the readme for some more info: TimeKeeper Roll20 API script which tracks time and expiries. The time and expiries persist and are tracked between sessions. The GM advances the time; there is no automatic advancement of time. The script currently communicates only with the GM.&nbsp; Each expiry added will be listed with a button [x] that can be used to delete the expiry. Useful if a character's concentration fails, or if the expiry being tracked is no longer relevant. Example of TimeKeeper's output: Current commands (version 0.2.1): !tk - shows commands. !tk show - displays current time. !tk set X - sets current time to X minutes. !tk add X - adds X minutes to the current time. Use negative values to subtract time. !tk exp charactername|effect|duration - adds an expiry effect for charactername with a duration in minutes. Example: !tk exp Delgon the Dwarf|Battle Rage|10 will add and track the expiry of the Battle Rage for Delgon the Dwarf. The Battle Rage will expire in 10 minutes from the time it was added. !tk del charactername|effect|remaining - deletes the expiry&nbsp; effect &nbsp;expiring in&nbsp; remaining &nbsp;minutes for charactername. How do I...? How do I set the time to be 1 day, 2 hours and 4 minutes? The script stores the current time in minutes, so in order to set the time, or add time, you have to first calculate how many minutes to add. For example, setting the time to 1 day, 2 hours and 4 minutes would be done with the command&nbsp; !tk set 1564 , where the calculation would have been 1440 + 120 + 4 minutes = 1564.&nbsp; See the macros below for one that will help you easily do this calculation. Suggested Macros These are some convenient macros to utilize the script: Macro Text Purpose and Comments !tk show Displays the current time. !tk add 10 Adds 10 minutes to the current time. !tk exp ?{Character Name}|?{Ability, effect or spell}|?{Duration in minutes} Simple macro to quickly add an expiry. Of course, you could use it to add something like a time when goblins are going to arrive at the PCs' camp. !tk exp @{selected|token_name}|?{Ability, effect or spell}|?{Duration in minutes} This macro is meant to be used as a Token Action. Adds an expiry for the character whose token was selected. /w gm [[?{Days|0}*1440 + ?{Hours|0}*60 + ?{Minutes|0}]] A simple macro to convert times from days, hours and minutes into minutes. I use this to calculate larger time values for adding or setting. Version History 0.1.0 First post to Roll20 forums 0.1.1 Minor formatting changes. No changes in functionality. 0.1.2 Changed method of determining whether commands are sent by GM. 0.1.3 Added handling of incorrect inputs, with feedback in case an invalid time or expiry entry is attempted. 0.2.0 Recoded. Added formatting using the Roll20 default template. Overall output is less verbose and less spammy (hopefully). 0.2.1 Added output of buttons that when clicked delete a certain expiry. Added deletion of expiries before they expire.
1591020476
GiGs
Pro
Sheet Author
API Scripter
Thats a great idea, and looks really simple to use. Nice work.
Thank you for the kind words GiGs, appreciate it :) Updated the script to version 0.1.1. No changes in functionality, just saw that the code was tabbed all over the place, and that the explanatory comments were a bit off. Hopefully fixed both of those issues. If any of you use the script and have comments, suggestions, or questions, I'd be happy to hear from you! <a href="https://github.com/HappyTapir/TimeKeeper" rel="nofollow">https://github.com/HappyTapir/TimeKeeper</a>
1591101082
Bast L.
Pro
API Scripter
Neat script. I tried adding an hour and day add command, but the API is being weird, and I can't save atm to test. Also, not sure if it's any better than what you're doing (I guess someone could have 'GM' in their name), but there's a playerIsGM function for chat messages:&nbsp; <a href="https://wiki.roll20.net/API:Utility_Functions#Player_Is_GM" rel="nofollow">https://wiki.roll20.net/API:Utility_Functions#Player_Is_GM</a>
Bast L. said: Neat script. I tried adding an hour and day add command, but the API is being weird, and I can't save atm to test. Also, not sure if it's any better than what you're doing (I guess someone could have 'GM' in their name), but there's a playerIsGM function for chat messages:&nbsp; <a href="https://wiki.roll20.net/API:Utility_Functions#Player_Is_GM" rel="nofollow">https://wiki.roll20.net/API:Utility_Functions#Player_Is_GM</a> Great, I'll look into using that function instead of the current one. Thanks for the tip! I'll post an update once I've tested it.
1591135169

Edited 1591135583
The script now has a more robust method of determining that the command is actually sent by the GM (using the playerIsGM(playerid) function). Thanks Bast L. for the tip! This is my first Roll20 API script, so I'm very thankful for useful advice. Updated script (version 0.1.2) at&nbsp; <a href="https://github.com/HappyTapir/TimeKeeper" rel="nofollow">https://github.com/HappyTapir/TimeKeeper</a> As for your other idea Bast L., I'm thinking days, hours and minutes could be passed to the script in the form of separated values (1|4|30) or a string with suffixes (1d4h30m). The latter strikes me as easier to type. Thoughts?
1591148458

Edited 1591148874
Bast L.
Pro
API Scripter
Hmm, I went lazy style (just repeated stuff with replace), but I think, if I got to using this (which could actually be pretty good; in my PF2 game, we're always talking about how long it's been since x), I'd end up making a template with some buttons to interface, so the lazy style kinda works for that. Set time might be a multiple query macro, but otherwise the buttons would be -1/+1/? where ? also does a query for minutes (or hours, or days, depending which was clicked). I started writing the template, but then I thought about mangling the script into a PF2 calendar, which is what I'm working on now (good chance of never finishing :). Here's what I had earlier though: this.ShowCommands = function () { //Whisper a list of commands that TimeKeeper will accept var commandString = ""; commandString = "&lt;ul&gt;"; commandString = commandString + "&lt;li&gt;&lt;b&gt;!tk&lt;/b&gt; - displays this information.&lt;/li&gt;"; commandString = commandString + "&lt;li&gt;&lt;b&gt;!tk show&lt;/b&gt; - displays current time.&lt;/li&gt;"; commandString = commandString + "&lt;li&gt;&lt;b&gt;!tk set &lt;i&gt;X&lt;/i&gt;&lt;/b&gt; - sets current time to &lt;i&gt;X&lt;/i&gt; minutes.&lt;/li&gt;"; commandString = commandString + "&lt;li&gt;&lt;b&gt;!tk add &lt;i&gt;X&lt;/i&gt;&lt;/b&gt; - adds &lt;i&gt;X&lt;/i&gt; minutes to the current time. Use negative values to subtract time.&lt;/li&gt;"; commandString = commandString + "&lt;li&gt;&lt;b&gt;!tk addHour &lt;i&gt;X&lt;/i&gt;&lt;/b&gt; - adds &lt;i&gt;X&lt;/i&gt; hours to the current time. Use negative values to subtract time.&lt;/li&gt;"; commandString = commandString + "&lt;li&gt;&lt;b&gt;!tk addDay &lt;i&gt;X&lt;/i&gt;&lt;/b&gt; - adds &lt;i&gt;X&lt;/i&gt; days to the current time. Use negative values to subtract time.&lt;/li&gt;"; commandString = commandString + "&lt;li&gt;&lt;b&gt;!tk exp &lt;i&gt;name&lt;/i&gt;|&lt;i&gt;effect&lt;/i&gt;|&lt;i&gt;duration&lt;/i&gt;&lt;/b&gt; - adds an expiry &lt;i&gt;effect&lt;/i&gt; for character &lt;i&gt;name&lt;/i&gt;, with &lt;i&gt;duration&lt;/i&gt; in minutes.&lt;/li&gt;"; commandString = commandString + "&lt;/ul&gt;"; sendChat(this.ChatName, "/w gm " + commandString); } //Adjust the time by hours, then whisper current time and current expiries to the GM if (msg.content.indexOf(" addHour ") !== -1) { msgArray = msg.content.split(" ", 3); timeKeeper.AddSubtractTime(Number(msgArray[2].toLowerCase())*60); timeKeeper.ShowTime(state.TimeKeeperGlobals.CurrentTime); timeKeeper.CheckAllExpiries(); } //Adjust the time by days, then whisper current time and current expiries to the GM if (msg.content.indexOf(" addDay ") !== -1) { msgArray = msg.content.split(" ", 3); timeKeeper.AddSubtractTime(Number(msgArray[2].toLowerCase())*1440); timeKeeper.ShowTime(state.TimeKeeperGlobals.CurrentTime); timeKeeper.CheckAllExpiries(); } Maybe not so clean with the repetition, but better to repeat the commands than the AddSubtractTime? Crude example to illustrate. It would have other commands for minutes, days, and the other TK functionality. The plus and minus each change it by 1, and the ? calls a query macro, which I didn't bother writing, but would be something like !tk addHour ?{hours}: Which is just: &amp;{template:default} {{name=Time Keeper}} {{Hour [+](!tk addHour 1) [ - ](!tk addHour -1) [?](!&amp;#13;#addHours) }} edit: Of course, with the buttons, you could just have it pass the minutes, such as 60 for each hour, 1440 for each day, so maybe the other commands aren't really useful.&nbsp;
1591211665

Edited 1591211872
Interesting and looks a lot nicer than my solution. I do think keeping time calculations client-side would be nice, so if someone talented in writing macros could figure out a way to do the math with a macro that would be great. I've been using&nbsp; /w gm [[?{Days|0}*1440 + ?{Hours|0}*60 + ?{Minutes|0}]]&nbsp; in a macro to calculate times for me, but of course using it to set or add time with TimeKeeper would mean handling inline rolls in the script code, which I simply haven't added yet. Updated the script to v 0.1.3, basically just adding slightly more robust handling of incorrect input.&nbsp; <a href="https://github.com/HappyTapir/TimeKeeper" rel="nofollow">https://github.com/HappyTapir/TimeKeeper</a>
1591463453

Edited 1591463800
Updated to version 0.2.0 <a href="https://github.com/HappyTapir/TimeKeeper" rel="nofollow">https://github.com/HappyTapir/TimeKeeper</a> I just updated the script. More a cosmetic change than anything, but some better handling of incorrect input was added, as well some re-coding to make the code easier to change for future updates. I can also recommend using the @{selected|token_name} instead of @{selected|character_name}. Makes for less verbose output. Of course, you don't have to use a token action macro at all. I use the below macro most of the time. Equally fast I think. !tk exp ?{Character Name}|?{Ability, effect or spell}|?{Duration in minutes} Current example output of TimeKeeper 0.2.0
Updated to version 0.2.1 <a href="https://github.com/HappyTapir/TimeKeeper" rel="nofollow">https://github.com/HappyTapir/TimeKeeper</a> Added the function to delete expiries before their time is up. This should be useful to account for spellcaster loss of concentration, or when an event being tracked is no longer relevant. Please see the updated first post for more details. Example of current output: Not as clean-looking as the previous version, but I think the added functionality might be worth it. I haven't found a way to format text with any precision using the default template. Pressing an X button will delete the associated expiry. Please make sure to not adjust the time before trying to delete an expiry - it shouldn't break anything, but it won't work. As always, happy to receive any feedback!