UniverCity is an isometric university management game.
Instead of quietly working on this I thought I'd post what I have done currently and what is left to do.
What started out as trying to work out a system for "Student random events" (e.g. simple things like dropping trash to larger events) ended up becoming a redesign on the way students idle (which is what they do when not in a lesson). As some may have noticed the previous system ended up with some silly issues popping up e.g. students staying in the toilets and just switching stalls or repeatedly queuing for the snack stop.
[h1]The previous system[/h1]
The previous system worked by every 20-55 seconds the student that was not in a lesson would leave their current room and select a new room to go to. Select the task was done by building a list of every room marked with a "can_idle" flag and that had space. It then computed a "bias score" for every room, this was based on the stats of the student and used to weight students towards certain tasks.
[img]https://steamcdn-a.akamaihd.net/steamcommunity/public/images/clans/32385635/3515b9b7cb774f656a5f7bff985544002beacce0.png[/img]
The list of rooms was then sorted based on the bias score and in the cases where two rooms had the same score their distance from the player was used instead. And then a task was selected from the list semi-randomly, looking at this code now it somewhat undid a lot of the previous work in the cases of small universities.
[img]https://steamcdn-a.akamaihd.net/steamcommunity/public/images/clans/32385635/a1052f58351d00a4fad3c424319cd311defd63ef.png[/img]
Once inside a room that rooms script took over until the next time a task was to be selected. Buildings and Gardens for example would try and find a seat and if not they would randomly pick a free spot to stand on.
[h1]The planned system[/h1]
The new system is planned to work more globally than the previous system. Instead of selecting a random room instead an action would be selected instead e.g. sitting, chatting or getting something to eat. Each task can be ordered by priority and given a random chance of being selected, they can also have a list of rules that decide when it is valid to select this task.
[img]https://steamcdn-a.akamaihd.net/steamcommunity/public/images/clans/32385635/a821d2f2c45df244141c3f848676a31472bd7d41.png[/img]
To make this work (And what took up a bit of time) I needed some way to evaluate these rules quickly (they'll be run often) and store these variables efficiently in memory. I ended up writing a small parser (using the rust library [url=https://crates.io/crates/combine]combine[/url]) that compiled down to a simple set of instructions that could quickly be run to return a boolean. For the variables I ended up creating a new component type for the ECS I was using that could be variable sized and then creating a list of variables based on the ones referenced in the rules. As part of this I moved all stats (like hunger) into this variable system and updated all the code around that. The whole compiler/bytecode thing may have been overkill but it was fun to write at least.
Once that was hooked up it was then a matter of making it so the scripts could actually run and control entities. This has taken a lot of work due to pretty much everything assuming that a student is always in a room (be it for a lesson or idling) which needed to change. A lot of that involved splitting the `RoomOwned` component into a "Controlled" component that allowed entities to be released from both rooms and idling, the other part was fixing entity methods that assumed that the entity was in a room (mainly the "release" methods).
[img]https://steamcdn-a.akamaihd.net/steamcommunity/public/images/clans/32385635/7681a1aa134e7ddd6586f76012ca79512ad89cea.png[/img]
Next up was making these scripts able to control the client-side of things (multiplayer and singleplayer as they both use a server). This required having the client know which script to call, instead of sending the name of the script which could waste a lot of network bandwidth I went with sending a 16 bit value that points to an offset in the list of choices, assuming both sides have the same mods loaded (in the same order) this should always be fine (And I don't think we would need more than 65536 idle options anyway).
The last thing to implement is saving (which whilst writing this I realized even the saving for rooms is flawed), again the saving system assumes a lot about rooms and needs a bit of a rethink.
Once that is done I should be able to start re-implementing the previous idle tasks with this new system and throw in some new ones (and improvements to the old ones). As for random events I'm still undecided whether they should just be low chance idle tasks or a separate system that interrupts whatever the student is currently doing.
This is taking some time as its only me working on this and I'm not the fastest programmer out there. Sorry about that but I'm hoping this wont take much longer so I can move on to the next thing.