The Server Tick

The Server Tick

Now that I can track the ticks in the database and have the ability to change config from the web administration I can start working on the tick itself. Which is, at it's heart, no more than a simple timer that fires a bunch of functions when it times out, then starts over.

So, to perform the tick, first thing I need to be able to do is read and write to the API's tick tracker endpoint. I also have to hash and redact the server passwords from the other endpoints I wrote as that would be a bad time if people could get their hands on those. They would also need the server's API login, on top of those passwords but yeah, not great to have them out there in plain text.

Right now that is not a big concern but there is an issue for it. The first thing I did was reverse the relationship on the tracker -> gameserver foreign key, now the game server tracks it's tracker rather than the other way around. Makes it easier to get the tracker by it's ID in the API, less work for the API and the DB. As well as less functions for me to write.

Now on boot, the server should get it's tick tracker ID, then we just send a get request to figure out when the last tick was handled, then apply all ticks that would have occurred since then for all active slimes. Finally, we look at the current time on the server and use that to get an offset to start the tick timer so the next time it goes off is at the top of the following hour and then make a PUT request with the datetime rounded to the top of that hour.

To start I suppose I should get my fetching done, then my catch up and sync. I know the catch up process will be more complex than it might appear, there's a lot of data being processed through the API in this situation and I might want to write a few new endpoints to make this less troubling. Perhaps fetching all slimes that are active as one chunk, creating the nodes as they would be in the server normally so we can run all their relevant scripts... then compiling the modified slimes into one big chunk of json and sending that back to the API to process, rather than firing a GET and a PUT for every single active slime... as that would be incredibly inefficient.

That also raises a question about how I should handle the active slimes no currently logged in. As far as I can think this particular game server should only be responsible for the saving and loading of players, slimes and apartments. It could feasibly handle working on all active slimes, but I would want it to do it in a non-blocking way... so that means either asyncronously or spooling up a thread or subprocess to handle it. Can't have the server hiccuping every hour when it has to deal with all this data.

I could set up a sub-server that has the one single job of updating all offline slimes with each tick, send an RPC over to it whenever a tick happens and just let it do all of that without having to worry too much about the main game server having any issues. This does mean setting up another socket, though it's not like that's a big deal nowadays.

This also brings up one more thing in regards to the interserver connections and their security. As it stands the game server will listen on a port for the login server. Feasibly anything with a similar configuration and protocol could just pop on in and say it's the login server. The server passwords that were mentioned a while back in this post are part of the solution to that, setting up a key exchange that has the login server asking for a key, then if it is verified sending it's key to the game server and if it all checks out initiating the connection proper.

It occurs to me I did not make an issue for this, I should do that now.

Lots of technical debts to pay.

Alright, I need to start trying to get a hold of some people. Once that's done hopefully I will have a bit before lunch to get started on this.

It seems I spend a lot of time on hold or leaving messages in voicemail these days. Was it always like this? I don't remember it being like this when I was younger.

Anyway, can't make any more calls today, gotta keep the lines open to get this crap sorted. That means I am back to work. I'll just have to put this thing out of my mind for now and focus.

Right then, where was I? Making the gameserver aware of it's tick tracker.

Simply need to send a GET request to the server with the tracker ID, the ID should now come with the server info when we start our connection and all I have to do is store it from there.

Reading last tick.

There we are, the last tick was yesterday at 11am EST when I set up the model for the tick tracker.

Now I have to do me some math to figure out how many ticks should have occurred between then and now, which will take a little work unless the way datetime is handled in GDScript has changed. Nope.

Time
Inherits: Object A singleton for working with time data. Description: The Time singleton allows converting time between various formats and also getting time information from the system. This class…

Looks like I will need a func for that.

I know there is probably a bug here, I need to test to make sure.

It may have more ticks than is accurate depending on how the math is handled on the hours.

This code assumes that the hours value could be negative and if so, adding it to the ticks should subtract the difference. It is 11 now, so exactly 24 ticks and the value was right, now if I set the last tick to 12 yesterday instead I expect to see 23 but it might not be correct.

We are good.

Alright, now that we have this I can go through and process the ticks. But first I want to get my tick synced to the server's clock. This means figuring out how many minutes are left in the hour and setting the first tick to be that long. Then setting the tick back to one hour intervals once the first tick has processed.

Synchronized.

If the server config is set to sync the tick to the hour it will happen here, otherwise it will set up the tick to fire every tick_secs. I will keep the offline tick processing to 1 per hour, however. If I have a tick every minute or something and the server is down for 10 hours then everything will be drained and it will be a bad time.

Now that I have my offline ticks and my sync I can focus on what happens when they are fired.

So, that can be handled a few ways I can think of. I could get all nodes in groups that need to process ticks, I can have a signal that all nodes that need to be aware of can hook up to or I can be an idiot and directly search for nodes with a handle_tick() function.

I think the signal way would be most efficient, depending on how groups are stored. If groups are stored on the tree like I suspect it wouldn't really make much difference either way and I would be able to look at the Server Tick node and see everything it should be effecting at a glance rather than hunting down all the nodes with a signal hooked up.

Let me see how groups are stored before I decide.

From what I can see I believe I was right in assuming the groups are stored in the scene tree. Group it is.

So there's about 8 minutes to the next tick, I figure I will sit and wait for it to happen. Just to make sure it's firing on the hour.

Or not.

I thought that might happen.

I changed the way the RPC nodes loaded yesterday to prevent the sockets from opening before they were ready. Apparently the ClientLogin node isn't instantiating correctly.

Yep, the ClientLogin was looking for the GameLogin, which is not instanced until after the ClientLogin. Fixed that, login is working again. Unfortunately the tick happened before I got logged in so the slimes didn't get pinged from the tick. I will have to modify the timer in the remote and get it firing more rapidly for testing anyway. For now though it's lunch time.

Alright, in the time it took for lunch and taking the dog out there was another tick.

Looks good to me.

Now that ticks are being processed and sending the new data to the clients, I have 2 things I think I should do next.

One is setting up the tick handling for offline but active slimes, which also handles ticks since the last start on all active slimes.

The other is setting up a dev console so I can send debug commands to the server, triggering ticks and such at will.

Perhaps the offline ticks wont occur until login, this will significantly lighten the load on the server. To do this I would need the slimes to be aware of their last tick rather than the server's tick tracker. However knowing how long the server was down for can be used for other things so I will keep that.

Yeah, I can use the last time the server had a tick to prevent the player from having to pay for server downtime.

Now I just need to make sure the values get clamped, don't want negatives.

Alright, clamped up.

Now I guess the next thing to do really is start on making myself a debug console sort of thing so I can talk to the server and trigger functions at will from in the client.

Step one to debug is

Chat

It's nearly 5 now but I figured I would put a window together at least.

I will need a command to reload config and a command to fire a tick, probably going to be the first thing I do tomorrow.

I will also find out if my offline tick processing is working correctly tomorrow. Could do it now but eh, I got 10 mins til clock out. Gonna push my changes and save my docs.

Alright, all changed pushed @ 4:59PM

Clockin' out.