Page 1 of 1

Party Journal Concept

Posted: Fri May 19, 2017 2:04 pm
by xavram
I'm kicking around the idea about adding a Party Journal concept into my framework. Players would be able to add pieces of information that had the following fields.

Owner : Who wrote the entry
Title : Entry Title
Entry : Whatever they want to write
EnteredOn : DateTime from getInfo() call
Private : bool flag on whether the entry is just for THAT player to see or if everyone can see it.

I was figuring I would store each entry in a property that's a json collection of this "JournalEntry" type.

My first thought was that each token would have its own property, for storing their own entries. Then when someone called the "Look at Party Journal" macro, it would get all the entries, from all the player tokens, remove any that were marked Private, and then sort them all by the "EnteredOn" before displaying them back.

This could work, but then I started to worry about adding a potentially huge property field to the player tokens. Would this impact performance when the tokens are moved around? Other issues?

So then I thought about just having one property, on the library token, that ALL the players wrote to. Again, when you wanted to look at the Party Journal, it would grab that property and remove any private entries from it (except for the ones you wrote, of course). The downside to this is if multiple players write entries at the same time, I could get concurrency issues on writing to that property on the library token.

Any thoughts from the experts on what the better way to approach this would be?

Re: Party Journal Concept

Posted: Fri May 19, 2017 4:24 pm
by wolph42
give each player its own lib:token

Re: Party Journal Concept

Posted: Fri May 19, 2017 4:31 pm
by aliasmask
I have a chat that our group uses and logs everyone chat. It saves it to a personal lib token and then at the end of the night it consolidates all the chats in to one chat log. It uses the server time with getInfo so it is a universal in time.

If I were to do it now, with the latest dev I would probably write it to a table instead of a custom lib token. You would need to generate the id number for each entry which could be based on time. Perhaps when the campaign load it creates the seed value which would be subtracted from the time code of each entry. It will essentially organize it by milliseconds which in a 4hr game would be over 14 million for an id value. I'm not sure if that's a problem. You could always divide by 10 or 100 and shouldn't run in to too many problems. In chat dividing by 100 would be more of a problem, but with journal entries not so much.

Re: Party Journal Concept

Posted: Fri May 19, 2017 7:07 pm
by xavram
Hmmm...hadn't thought about a table. Food for thought.

Re: Party Journal Concept

Posted: Fri May 19, 2017 7:14 pm
by xavram
So given that the Ids in the table would be very big numbers and non-sequential (if they're based off of the datetime of the entry), how would you pull ALL the records from the table, in order?

Also, is there a way to return the MAX value of a table?

Re: Party Journal Concept

Posted: Fri May 19, 2017 7:32 pm
by taustinoc
If you want date/time based IDs that sort chronologically, you start with the year, then the month, day, hour and minute:

4:32 PM, May 19, 2107
201705191632

I wouldn't want to bet the rent, though, that it will always been completely unique even if you time it to the second. You'd probably want to add a unique identifier for each player.

Re: Party Journal Concept

Posted: Fri May 19, 2017 8:54 pm
by aliasmask
The code is sequential and is the unix based time stamp. So, for example the timeInMs of 1495240970033 would be GMT: Sat, 20 May 2017 00:42:50.033 GMT and is accurate to 1 1000'th of a second.

I just checked and the highest integer tables accept is 2147483647 which is why I suggested saving a seed value which will represent the start. So, for example if 1495240970033 was my seed value, then all my id entries would start at that number and above, but you only store the difference (currentTime - Seed). Max value would be around 600 hours above the seed.

Re: Party Journal Concept

Posted: Fri May 19, 2017 9:00 pm
by xavram
So, changed up the methodology a little bit, still using a table. Just storing the entries sequentially in the table, not using milliseconds any more. Let me know what you think.

This brings up the Dialog, with all of the player entries. Private entries are not shown unless you're the person who entered it or the DM.

Code: Select all

[h : entryLink = macroLink("Click to add a Journal entry","JournalAdd@Lib:PC_CombatMacros","none","") ]

[h : maxJournal = getTableRoll("Journal")]

[h : entries = ""]
[h, for(x, maxJournal,0,-1), code : {
	[h : tableVal = table("Journal", x)]
	[h : isPrivate = json.get(tableVal, "Private")]
	[h : linkIs = x]
	[h : displayEntry = 1]
	[h, if(isPrivate && getPlayerName() != json.get(tableVal, "Owner") && getPlayerName() != "DM"), code : {
		[h : displayEntry = 0]
	}]	
	[h, if(getPlayerName() == json.get(tableVal, "Owner")), code : {
		[h : linkIs = macroLink(x, "JournalEdit@Lib:PC_CombatMacros", "none", x)]
	}]
	[h, if(displayEntry == 1) : entries = entries + strformat('<tr><td>' + linkIs + '</td><td style="width:130">' + json.get(tableVal, "EnteredOn") + '</td><td style="width:70">' + json.get(tableVal, "Owner") + '</td><td style="width:450">' + json.get(tableVal, "Entry") + '</td></tr>')]
}]

[dialog("Party Journal", "width=700; height=400"): {
<html>
<head>
<title>Party Journal</title>
</head>
<body>
[entryLink]
<table border="1">
<tr><th></th><th>Logged</th><th>Author</th><th>Entry</th></tr>
[entries]
</table>
</body>
</html>
}]
Journal Add macro

Code: Select all

[h:status=input(
"private|0|Private Entry?|CHECK",
"entry| |Journal Entry|TEXT|WIDTH=150"
)]

[h : abort(status)]

[h : clientData = getInfo("client")]
[h : timeStamp = json.get(clientData, "timeDate")]
[h : entry = json.set("", "Owner", getPlayerName(), "EnteredOn", timeStamp, "Entry", entry, "Private", private)]

[h : maxRoll = getTableRoll("Journal")]
[h : maxRoll = maxRoll+1]
[h : setTableRoll("Journal", maxRoll)]
[h : addTableEntry("Journal", maxRoll, maxRoll, entry)]

[h: closeDialog("Party Journal")]
[MACRO("Journal@Lib:PC_CombatMacros"):""]
Journal Edit macro

Code: Select all

[h: x = arg(0)]

[h : tableEntry = table("Journal", x)]

[h : isPrivate = json.get(tableEntry, "Private")]
[h : theEntry = json.get(tableEntry, "Entry")]

[h:status=input(
"private|" + isPrivate + "|Private Entry?|CHECK",
"entry|" + theEntry + "|Journal Entry|TEXT|WIDTH=150"
)]

[h : abort(status)]

[h : entry = json.set("", "Owner", getPlayerName(), "EnteredOn", json.get(tableEntry, "EnteredOn"), "Entry", entry, "Private", private)]

[h : setTableEntry("Journal", x, entry)]

[h: closeDialog("Party Journal")]
[MACRO("Journal@Lib:PC_CombatMacros"):""]
Seems to be working but I have to run this through quite a few more tests to be sure.