Displaying care stats, Server side care system

Displaying care stats, Server side care system

Today I have a few things I need to do around lunch time but when I left off I had a fairly solid foundation of the UI to start working on the care system. I didn't wire up the slime's data quite yet. I'm not sure that I will start on the detail view today, but I want to get the bars at least displaying their respective data.

I also plan to get the client calling the server for care actions. I will make the basic care system functions for the server (sans inventory and all the extra checks for now, just to get the client and server talking) and, yeah... hopefully my caffeine kicks in soon because I am struggling to write this.

Alright, I have hooked up the UI to the slime data, now I need to contemplate how the data is going to flow. When the player presses the button it should send an RPC to the server asking if the action would be viable, but to send the RPC the button press has to travel to the connection handler.

I could add the connection handler to a group, then get the tree and get the nodes in the connection handler group but that would be a lot of steps per button press, which isn't much to worry about really since it's not like this will happen every frame but my brain wants efficient code. I can use signals, hooking up a bunch of signals for each UI, which would be a max of 6 UI instances... not too much RAM required to track them...

I could also do me a get_parent() chain but I hate those because I might change the hierarchy and break it.

I suppose I could just locate the Connection Handler by getting nodes in group from the root of the tree on ready for the UI and store it per UI node. Yeah, I like that best. As far as my thinking goes right now it is the most efficient.

Or I could just... have a Singleton that references the connection handler and not have to get the thing every time. Yes, singleton. This is best and I shall think no more on the subject because I have spent enough time on it.

I somehow forgot that there would be more UI work required for this part. I think what I will do is scaffold the connection and get the functions on the server working, then come back and add the UI and extra steps on the client. This will make testing easier.

Starting on the communication code

So the player clicks an item to give to the slime, the client asks the server if this is successful.

Now to handle the server's part in this...

Something like this

The server will check first if the connection ID has a player associated, if not it will return a failure. If all is well it will pass on the data to the player node, which is the next stop in the source for me.

The player passes it to the Slime

Now the player has checks set up, it can check it's inventory for the item in question. I will add that bit when I add inventory, which should be pretty soon... maybe this week. If the slime is under the player's care then we pass on the feed data.

I try to avoid naming certain things the same on the client and server, to avoid accidentally writing server code on the client side and visa-versa. It's happened before.

So now I am on to the Slime node which will handle checking if the slime can handle any more food or drink, seeing if the slime likes or dislikes the item, etc. Then updating the data accordingly and sending it back through the comm_node to the player's client. For now there's not much to check but I will scaffold out the checks like I did in the player.

The slime handles food and drink.

Now the slime here is the last stop server side for this call, if it makes it all the way here we know the item is either infinite or in inventory, we know the player exists and is logged in, we know the player has authority to interact in this way with the slime.

Now we just check if there's room in the slime's ... stomach(?) for the food or drink in question, if not we return a NotX RPC to the client so the client can play an animation and let the player know they can't do this. Otherwise we increment the value up to potential max in a clamp to prevent over-feeding, etc.

If this were a normal food item we would also check the slime preferences regarding the food item and we would have to do a lookup on the food item in the DB (once I get inventory and items in) and figure out the flavors, mass increase and any other special effects the items might have. Items will also have scripts.

All that is left on the server side for now, however is to call the OnFeed() and OnDrink() hooks of all the attached scripts. Which should happen BEFORE we return data to the client.

Actually I think I should have a set of functions to handle changes in slime stats that will send any other stat changes to the client when they occur, so we don't have old data on the client if a food item increases fun or something else.

However, it's lunch time now. I will have to do this later after some other things I have to get done today.

Welp, so much for them phone calls. Federal holiday. Hah, shows how much attention I pay to calendars.

The client side, updating the slime and the UI

Surprised that worked, actually. Glad it did.

With that I can actually have a single function on the server side send back any updated care data in a dictionary, rather than having a different RPC for each stat.

Feeding and Watering functions are... functional.
Modified handler.

I figure it will be a lot easier to handle the care data this way, I can set up one RPC to handle all failed care functions as well, rather than 2 for each.

Like dis.

Starting on the body part script hook handlers for feeding and hydrating, from my understanding dicts are passed by reference so I can just pass the care_data dict to each hook and have it modified therein.

Now the question is do I want the modifiers to be... separate calculations added together or cumulative? Cumulative would mean if several body parts add bonus mass on feeding we would end up with a much larger amount of mass modification at the end. Separate calculations would require making a deep copy of the original data to send over with the modifiable data then we could simply add the modified values together.

Hmm... I like cumulative myself so that's what we're doing. Big numbers.

Script handler, should work... hopefully.

Here's hoping it does pass dicts by ref.

Now the server should process the scripts for body parts and handle the OnFed() and OnDrink() hooks. The hooks themselves are responsible for changing the data.

I should probably have care_data be called modified_data and also pass in what has been modified and how... Hmm, it would seem my brain is too tired to hold all this right now. I might need to write it out. It's currently 4:11 pm and one of them dreary, cold, rainy days so I am a little out of it.

There should be a modified dict which only contains what has changed and by how much.

Also, there should be the original slime_data value before modification.

I should write a helper function on the part script template to modify each stat, it should handle positive and negative modifiers the same way with clamped outcomes.

Wow, hard to focus right now. Alright, maybe best leave this for tomorrow. I am bound to make a huge mess if I try to do this while I can't hold it in my head correctly.

I can at least plan it out.

  1. Feed Request comes in
  2. All checks are passed, we are now applying the modifiers.
  3. modified_stats['hunger'] = Food Satiety Value (10, in the case of rice ball)
  4. Run the body part scripts, passing the slime_stats (hopefully a ref) and the modified_stats dicts to OnFed(slime_stats, modified_stats) hook
  5. In OnFed() check the Modifier for the related stat (hunger)
  6. Apply any modifications to the modified_stats dict using the helper functions (mostly to prevent misspelled strings from breaking scripts and causing crashes.
  7. Once all body part scripts have run, clamp the values between 0 and max_X, apply all changes to slime_stats.

I should probably run scripts in a Try/Catch style, to prevent crashes and output some data on where things break. Given that these things are hotloading and can be changed at any time.

I have done essentially what I wanted to by handling it like:

I have yet to test it though. Probably going to break somewhere.

Yeah, that care_data['thirst'] line up there, I just realized is detrimental. Removed it.

Fixed some... issues.
Handles scripts with less potential crashes, still can crash.

I need to figure out how to throw an error rather than crash if a function has typos or something.

Anyway, it's 5 now. I got this stuff working (I think, I need to actually write a server-side script to test with) and I am glad I didn't bugger off for the day. Though I never really can walk away from a problem, can I?

Tomorrow I will have to make them calls so I will probably lose an hour or more of work time but I plan to set up the helper functions for the server body part scripts. I would like to write the rest of the scaffolding for client-server care handling if I can as well.

If I still have time after that I will get on to the next thing. Probably adding an inventory UI. Then the Detailed stat window after that if I still have time left.

At some point while adding the UI I will start on the server Tick, this is a large part of the care functionality. It may take a week on it's own to properly implement though. We'll see.

Once the UI is all in place I will start adding some form of animations I think, happy and sad to start out, then things like eat, drink, etc. Then I can handle the care failure on the client side and show an animation where the slime turns from the food or something.