Posted on June 17, 2021
The RecogINATOR lives!
“Wait, what? The RecogINATOR? But… I thought you said the Questinator was going to be the first project?”, I hear none of you asking.
Well, the RecogINATOR! <thundercrash> is actually kind of a step in that direction, so I figured it sort of counts, and I wanted to write it, so… here we go.
So what is the recoginator?
I’ll just refer to it in the lowercase from here on out, as to invoke its full majestic glory too often could cause a rift in spacetime. The recoginator is essentially a tool for taking notes on the people who impressed you with their roleplay, so that you can recognize them for it. In Lusternia there is a command for mechanically doing so, “RECOGNISE <name> <reason>”; however, there is a limit on the number of times you can use it in a 24 hour period which resets at midnight UTC.
The problem of course being: what if you just had a really great RP session with 7 other people? How can you possibly choose only three?! Now you don’t have to. You can add all of them to the recoginator, and have them printed to a nice table you can interact with using the mouse or provided aliases. It will keep track of how many times you’ve recognized that day and stop after three. It will parse the output of “RECOGNISELOG” to see how many you’ve used for the day, adjusting for UTC.
Let’s go over some of the pieces and how I put them together. The full code is available on GitHub for browsing.
First, figure out what you need
I know, easier said than done. But it’s always best to at least sit and think about the various things you’re going to need in order to do what you want to do. In this case at a very high level I decided that I needed:
- Something that lets me take notes on who to recognize
- and can do the recognizing
But that’s not much to go on when it comes time to implement things. Let’s try breaking those down into smaller, individual items.
- The ability to add a person to a queue of recognitions
- The ability to keep a timestamp so we know when it happened
- use UTC, since that is what the server uses
- The ability to remove someone from the list without recognizing them
- The ability to recognize someone from the list for the proper reason, and remove them.
- The ability to track how many recognizes you have done that day
- so you don’t pop more off the list than you can mechanically handle
- The ability to undo the last thing you did
- if you removed one or more items, put them back
- if you added an item, pull it back off
- The ability to save/load the files from the disk
- a backup file, just in case, would probably be a good idea too.
- The ability to display it all nicely
- preferably interactively
- The ability to do it all via alias as well
You may have noticed that they all start with ‘the ability to’ and that’s not by accident. By framing each one as an action, we define what the package is actually doing which gives us individual goals which are, well, actionable. It also gives you some idea of what aliases and interactions you’ll need to provide for the user, and starts you thinking about the steps needed to get there.
I suggest you note down what the items are whether you write them as actions or just items, so that later you can refer to it when you inevitably forget something, or think of something else to add. One or both of these is almost certain to happen.
Then make it
You don’t need to go down the list in order, but you should refer to it frequently as you proceed. I find it’s easiest to start with the data; once I know what I need to do, then I can figure out what information I need in order to do it. In this case for each entry I need the name, the reason, and a timestamp. The first two I’ll get from the user, the last I can generate myself.
In order to make the timestamps UTC I need to figure out the UTC offset of the user. I decided to do this by querying a website for the current UTC time and comparing it to the output of getTime() in Mudlet, then recording the offset. I go ahead and redo it every profile launch in case it changes (due to daylight savings or some such). This is the recoginator.setUTCoffset function.
Once I have this information, I’ll need to be able to get an adjusted time. I use recoginator.timeywimey() to adjust the output of getTime into a UTC time which I then use in the recoginator.add function, etc.
I won’t go over all the individual pieces, but hopefully that gives you an idea of how one piece can lead to the next. Keep working your way through the list and add the things you think of rather than just noting how cool they are and then forgetting them. If you have a piece and you can’t figure out how it fits with the rest, either that piece needs to go, or you need another piece to bridge the gap. Eventually, you’ll have all the pieces you laid out on the list made and you can package them together.
I did want to highlight the use of TableMaker to create the clickable table of entries however. The following five lines create the table and setup its formatting
local printTable = ft.TableMaker:new({allowPopups = true, autoEchoConsole = recoginator.window})
printTable:addColumn({name = "#", width = 3, textColor = "<orange>"})
printTable:addColumn({name = "Server Time", width = 20, textColor = "<orange>", alignment = "left"})
printTable:addColumn({name = " Name", width = 16, textColor = "<turquoise>", alignment = "left"})
printTable:addColumn({name = " Reason", width = (recoginator.width - 44), textColor = "<green>", alignment = "left"})
recoginator.makeRow is then responsible for creating each data row for the table.
-- just the return
return {
{index, commands, hints},
entry.timeStamp,
" " .. entry.name,
" " .. entry.reason
}
The first column in the row is clickable, so it returns a table of arguments for cechoPopup. The next three columns are just text, so it returns the text I want displayed. Makes it very easy to create clickable sheets. Each entry’s index entry is clickable to recognize, with additional options to remove or remove all of that user’s entries in the right click menu. Check here for more information on the TableMaker, but the result in this case looks like this
Relation to the Questinator
Lessons learned in making the interface and aliases for this will help when moving on to the Questinator, as they are both at their hearts note taking and action performing interfaces. It will also be of benefit in some other projects I have on my plate which I’m sure will come up again here once I make some actual progress on them.
Thanks for stopping by, and as always feel free to join me on my Discord or comment here if you have any questions and I’ll answer as quickly as I can.