It’s been a month since the beginning of the year already! Although I didn’t get much free time other than the weekends it’s still been a quite productive month. Most of the work went into the core architecture implementation. Let’s see some examples of things that got done in January.
Further work on the sim architecture
I actually wrote down some of what I consider to be the most important points of the architecture in the simulation design doc.
I tried to describe the whole thing as a Property-Handler-Element-Entity model. It looks pretty good to me, and for now I think it accurately describes the approach I’m taking with the whole thing.
The documentation is not going to be perfect at this point, rather just sketching out the main points for now, but still it would be great if you let me know when you spot something you think is less clear and could use clarification.
One of the ideas for the Elements is to be able to register new types of Elements from mod scripts and then be able to register Elements of these types. This allows for adding new functionality fairly easily. If you can think of implementing some idea related to simulation mechanics using an Element, you should be able to do it.
There will be a set of pre-made element types for the base game inside the “base” mod, but new element types can be easily created by the other mods later.
One of the problems I ran into with passing the registration data tables around (from registration in some script to the other script where the converter resides) was that lua functions can’t be passed. The simplest solution to this is that any lua functions are simply removed when passed to the converter, and it’s the solution that is currently used. So unless you’re using a generic element registration (without the converter involved at all) you can’t pass lua functions with the lua_exec fields for handlers. One of the things that need to be implemented here as an alternative is the use of interfaces - lua_exec fields should be able to use a reference to an interface, like `call “interface_name” “function_name”. Basing the simulation processing on the Elements
This was a big change that was in plans for a few months, as the specification for the element-based sim was already done, there was just not enough time to actually implement it. Things now work as expected, processing jobs for each tick are based on processing the Elements and the objects that “belong” to them.
Some work went into expanding the Operation class with more possible types of operations. This is still in the works, the goal is to support a dozen types of operations, including simple assignments as well as assignments with preceding math operations (for example “+=” and “=”). On top of that there is also a need for operating with two props on both sides of the equation, for this the syntax for the operation uses additional “$”, for example “+=$” and “=$”.
As the project develops further there will be possibilities for more work on extending the Operations. One idea is to have the possibility for nested operations, though I’m still not convinced it’s necessary. If you wanted to to some crazy nested operations on values just use a lua function for that - unless that operation won’t be performed many times per tick (preferably once a longer while) you should be good to go.
Internally, “raw” setters and getters can now be used, meaning there is less validation performed upon accessing or setting of the prop value. So far it’s about not checking if the given key exists in the database. While not true for all situations where we get or set props (good portion of operations and evals will still default to the regular “non-raw” mode) , this still can mean a performance boost given there will be many such operations performed every tick.
The validation is performed at the time of registration. The keys passed recognized to be passed as prop string identifiers are checked against the list of already registered props. If there is no prop registered under specified name that eval or oper will be deleted and an error will be thrown.
At the end of the month I actually have quite many things in the backlog. It’s nice to know what needs to be done, feels like I’m reaching a point where I don’t have to “invent” everything I want to implement in the context of the whole architecture structure, instead can focus on smaller, more concrete tasks.
For now the most important thing to do before the 0.0.3 release is some basic functionality for the Decisions system and the UI interactions for Decisions, as this serve as a nice proof of concept for one of the core game-play functionalities.