Creating a game analyzer?!

Good Evening,

so after alot of playing stonehearth I would appriciate it to have something like an analizer running in the background, which basically logs everything of the game. For example how much citizens you have lost over time, how much raids have been happened over time, jobs/levels of the citizens over time and much more. I do :two_hearts: graphs 8-). Then for instance you could excract from those graphs where and with which action did I get lots of provit etc…

But the big questionmark which pops up: Where do I start ?

My first idea was to create a third party application which you have to inject into the game but its probably against the TOS, so I would not get that much support on this website and the distribution would also be denied.

So now I am thinking about to use the events which gets raised by a certain action, basically I would have a lot of events to chose from because of its ECS architecture ?! (my guess). So maybe I can then create a new system and register it to the certain events which I want to receive and forward this data?

At the end there are some questions which I want to ask before i will dive into this topic and will spend alot of time creating this:
Do I have access to those events ? How would I find all of the events which gets raised?

I would be thankful, if someone could answer my question or leave a comment

LifeArtist

1 Like

i certainly won’t be of any help answering your question, since i know nothing at all about code, but maybe @RepeatPan or @Drotten can help you out…

I suppose since Decoda has access to the lua state, you could get it too on some level, but a third party application like those Dwarf Fortress tools should not be necessary and I would advise against it, not just for ToS reasons.

I think you’ve got the right idea, however. You can create a mod which then listens to certain events, or overrides/hijacks certain lua functions/components if push comes to shove (~monkey patching), but that’s not really recommended.

Here’s some keywords for stuff that you might want to search for:

  • Events are listened to by calling radiant.events.listen and triggered by radiant.events.trigger/radiant.events.trigger_async. Generally, search for the listen bit, or just radiant.events to get most of them. Keep in mind that SH is split between client and server state; most events happen on the server side, but there’s a few (especially anything involving GUI or user actions) happening on the client.
  • Raids and such are parts of the campaigns, which are part of the game master. I believe, but am not sure, that there’s events fired whenever an encounter starts. You could try to listen to that event, and then see if it’s a raid encounter to log an event in your code.
  • I would recommend using SH’s serialization to store your data. You can create a service (as a controller), that is able to log things and keeps it as a lua table (that contains the events). Bonus: You can display the stats directly in the GUI within the game. Bonus bonus: You could offer some API that allows people to plug into it. Technically, if you’re doing this well enough, you could have achievements and achievement rewards, while even allowing other mods to add their own achievements.
  • Should you wish to export this data to another application or so, you can always export your lua table. For example, send it to the GUI, display it in a <textarea> as JSON and have the 3rd party application import it. That way, you can also offer web services and cloud and what not.
6 Likes

@8BitCrab Anyway thanks for tagging :slight_smile:.

@RepeatPan What a great and detailed explanation 8-). So my first move is now diving into moddingand after that applying what you have mentioned.

Okay so after looking into the rayyas smod file I was even more able to understand the concept of the game. But one thing was still unclear:

the line player_service_trace = player_service:trace('rayyas children ui change') as far what I am understanding that this says player_service please watch “rayyas children ui change” event.
And then if this event happens check_override_ui(player_service:get_data().players) gets called.

But how does the game knows what the ‘rayysas children ui change’ event is and how it gets its fired ?

Or does it means trace the new event which I will define now (). But still, how would this event get called. I didn’t find any lua script inside the rayyas ui smod which would have fired the event.

Traces are not events. Events in SH are based on a publisher/subscriber model with a context object. You can subscribe to events with a specified name that are fired on a specified object; there’s a few events that operate on radiant and stonehearth because they’re kind of global, some that operate on services, others that operate on components and a few that operate on entities. But that’s just a selection, you could technically subscribe and fire on almost anything I believe.

Traces operate on objects, be that a service/controller, a C++ element/component, or a datastore. There’s a bunch of different traces used. Traces are another form of event subscription, but you’re actually getting it wrong; what you’ve read is the description of the trace, not the name. You could put “I like big bottoms and I cannot tell not the truth” in there and it would work just the same. If anybody looks at the list of active traces they’re going to be a bit confused, however.

You’re tracing the player_service, with the reason/description of “rayyas children ui change”. Basically, whenever something changes on the service - this is dependant of the trace you’re doing, as there are so many different reasons or traces - give me a call. It’s a different form of event subscription that is less centralised and more object-based; it’s mostly used with C++ data that cannot be accessed in lua as easily, or which wouldn’t be worth it because there’s no knowing when (or if) somebody is listening to it.

I don’t know the full code, but usually, the traces follow Javascript’s idea of promises pretty close. I wouldn’t call traces events, even if they kind of are. Events in SH for me are the radiant.events things, traces are traces.

Most importantly, where you can see most events pretty clearly - because there’s a trigger somewhere - traces are mostly engine-based and therefore not obvious. In the case of a service/controller I can only guess, my best guess would be that it’s fired upon changing the datastore, or maybe some sort of invalidation.

In any case, you’re looking at it at the wrong direction. The trace is listened to because of rayya’s UI, that’s what this trace listener’s task is. The trace itself is executed by the player service in stonehearth.smod; but I think even there it’s indirectly done by the engine.

1 Like

Okay that cleared things up in addition to your reply while investigating the folder hierarchy and some tech setups I have also found a pretty nice documentation, which is located: here : stonehearth\stonehearth\docs\reference\ai\event.markdown (don’t ask me why it is inside the ai folder). So this letter enumerates some basic events which get triggered during the game + explains the events with a few lines + explains events in general. :+1:.

So for instance the event hourly which gets triggered every game hour is indeed very interesting for plotting over time :wink: Or the event level_up … :blush:

Like in any other language I like to have a response of what I am doing right now and was wondering if it is able to print out some debug text on the screen because I didn’t really find something useful. I have found the console js files but don’t now how I can call a js function through lua. :thinking:

Good night.