Modding Discoveries (part 2)...

I spent a great deal of my free time this weekend working on parsing discovery mod files. Still, though I wrote quite a bit of code, I'm not completely done with this. One of the drawbacks of using JSON for modding files is that it doesn't support any kind of scripting logic so I have been working on implementing my own. I'm trying to keep things as simple as possible just so that people that are not familiar with programming do not have a hard time understanding the code. And because I don't have much else to talk about I'm going to take the opportunity to describe the components of a discovery mod in more detail:

A discovery has these main properties:

Effects: A discovery can have effects both when it's gained and when it is lost. So for example, the Boat Making discovery will give access to shipbuilding knowledge to a human group. This in turns is what allows groups to form migration routes through bodies of water. In the modding script, such an effect would be described as follows: "gainEffects": "'group_gains_knowledge: this, shipbuilding_knowledge'"

A discovery can have effects both when it's gained and when it is lost. So for example, the Boat Making discovery will give access to shipbuilding knowledge to a human group. This in turns is what allows groups to form migration routes through bodies of water. In the modding script, such an effect would be described as follows:

Conditions : For a human group to have access to a discovery they must satisfy a set of conditions. Using the above example, to make the discovery of Boat Making, a group must satisfy two conditions: neighboring at least one terrain cell containing a 'Sea' biome, and not having access to shipbuilding knowledge beforehand. Additionally, to hold the discovery (that is, to avoid losing it) the group must satisfy the condition of currently having access to shipbuilding knowledge. Here is how these conditions would be defined in the mod file: "gainConditions": "'[NOT]group_has_knowledge: this, shipbuilding_knowledge' , 'cell_is_sea: neighbor'" "holdConditions": "'group_has_knowledge: this, shipbuilding_knowledge'"

: For a human group to have access to a discovery they must satisfy a set of conditions. Using the above example, to make the discovery of Boat Making, a group must satisfy two conditions: neighboring at least one terrain cell containing a 'Sea' biome, and not having access to shipbuilding knowledge beforehand. Additionally, to hold the discovery (that is, to avoid losing it) the group must satisfy the condition of currently having access to shipbuilding knowledge. Here is how these conditions would be defined in the mod file:

Event Time-to-trigger and Factors : For a discovery to actually be made, a random amount of time in days must happen within the simulation since the conditions for acquiring the discovery have been fulfilled. Apart from that, different factors can influence this amount of time by reducing it. Continuing with the above example, when a group meets the conditions to discover Boat Making, from 1 to 91,250,000 days (250,000 years) must pass first. This time is can be reduced by how much access the group has to sea biomes around and within the cell. This is described in the mod as this: "eventTimeToTrigger": 91250000, "eventTimeToTriggerFactors":"'[INV]neighborhood_sea_presence'"

: For a discovery to actually be made, a random amount of time in days must happen within the simulation since the conditions for acquiring the discovery have been fulfilled. Apart from that, different factors can influence this amount of time by reducing it. Continuing with the above example, when a group meets the conditions to discover Boat Making, from 1 to 91,250,000 days (250,000 years) must pass first. This time is can be reduced by how much access the group has to sea biomes around and within the cell. This is described in the mod as this:

In the above examples there a two instances of Operands that need to be parsed by the game engine before being implemented: [NOT] and [INV]. [NOT] reverses a condition, so that the statement within the condition must fail for the actual condition to pass. [INV] is a factor-only operand that reverses the factor value. So if the original factor value is'x', the modified factor value will be '1-x'.

Operands can be combined together to form complex statements like in the following one:

'[NOT](<condition1>[OR]([NOT]<condition2>)[OR]<condition3>)'

... which is the main reason I have been slow to implement a set of regular expressions (sequences of characters that aide an algorithm in parsing pieces of text) that can handle all the possibilities. Nonetheless I have progressed quite a bit and I'm pretty sure I'll be done with parsing discovery mod files next weekend. With that I'll be able to start working on making those modded discoveries be used within the simulation.

NOTE: For those who are familiar with programming languages you might find the "scripting" elements quite a bit impractical. But like I said, my goal is to make the language accessible to non-programmers and actually limit how much can be done with it (I don't want it to be easy to 'break' the simulation by allowing very complex logical statements or maths within a mod file). That said, I'm open to criticisms and suggestions on the design.