A couple of entries ago I presented my first version of the encounter screen. As the team of explorers wanders around in the map, the stored encounters will get shuffled, and the first one whose condition gets triggered will present itself. Here’s the somewhat updated screen:

I was checking out the moddability of this game by changing most pictures to manga/anime aesthetics, and I realized that I liked it more this way. With a simple change of directory names, all names and pictures could get swapped to American ones. In any case, this screen presents what encounter has been triggered. The description gives a brief overview of the situation. The rest of the text informs that this encounter, at least the psychological part of it, will test each team member’s self-regulation (which is one of the psychological dimensions, the grouping of a few psychological criteria).
Yes, I know that there’s a lot of black space. Don’t know what to do about that.
Once you click the round button on the lower right, you are shown the results of the psychological test:

A brief text indicates the reason of this psychological test; in this introductory event/encounter to a narrative line called “The Verdant Assembly,” the characters test their self-regulation against the overwhelmingly lush and alien surroundings. For each character, the average value for that psychological dimension gets tested against a series of performance thresholds in the TOML files. The highest threshold they pass, they get that reward (or punishment). In game terms, an Encounter is associated with a series of Outcomes. Here’s how the outcomes for this encounter look like in the raw TOML file:
# Possible placeholders:
#
# {CHARACTER_NAME}
# {CHARACTER_FIRST_NAME}
[[outcomes]]
identifier = 1
outcome_type = “PsychologicalTest”
description = “Overwhelmed by the alien nature of this plant-based world.”
consequences_identifier = 1
[[outcomes]]
identifier = 2
outcome_type = “PsychologicalTest”
description = “{CHARACTER_FIRST_NAME} becomes fascinated by the plant-based entities, leading to increased motivation and a desire to learn from them.”
consequences_identifier = 2
They are self-explanatory. The most important part is that they link to another store of game entities, the Consequences. I intended to unify the concept of game consequences to a single block of game logic that could be applied to psychological tests and, in the future, to team struggles. The TOML file of related consequences is the following:
[[consequences]]
identifier = 1
illness_identifiers = []
injury_identifiers = []
mental_status_effect_identifiers = [1, 2]
character_trait_identifiers = [1]
add_features_identifiers = []
remove_features_identifiers = []
[[consequences]]
identifier = 2
illness_identifiers = []
injury_identifiers = []
mental_status_effect_identifiers = [3]
character_trait_identifiers = []
add_features_identifiers = []
remove_features_identifiers = []
It is quite inexpressive in its contents because it only links to other entities through their identifiers. However, the outcome of each psychological test and team struggle could have any of the following consequences (or all of them):
- The team member(s) involved receives one or many illnesses. Illnesses reduce the team member’s health every turn until they run out or are cured.
- Receives one or many injuries. Instant reduction of health, and the permanent ones even reduce max health.
- Receives one or many mental statuses (like Confused or Discouraged). They increase or reduce the value for associated psychological criteria.
- Receives one or many character traits (like Terrified of Octopi, or Botanist). These help or hinder during team struggles.
- The exploration zone the team is exploring either gains or loses features. For example, if some outcome enrages the natives, the exploration zone could gain the feature Enraged Natives, which would present more combat-oriented encounters in the future.
The consequences are already being applied in the code (which was some heavy amount of code, well-tested thanks to test-driven development), and once I get around to implementing team struggles, their consequences will work seamlessly with the code already written.
In the near future I’m going to focus on making sure that encounters can be blocked by other encounters or even their outcomes, if necessary. For example, if during a team struggle the team screws up bad enough to unleash something dangerous, that should cut off access to more positive branches of that same narrative.
A detail about Rust’s fastidious nature: this is a programming language built upon security and protection against the nastiest bugs from the C++ era. As far as I can tell, in Rust it’s impossible to corrupt some memory allocation that it wasn’t supposed to touch. That forces you to change your approach to programming in quite a few ways, but not because Rust is annoying for no reason, but because in other languages you were doing dangerous things. In my code, I was passing around a SharedGameResources entity that had access to “specs” Entity-Component System (that’s a whole thing; if you are interested, google it) as well as the stores of data loaded from TOML files. At one point I had to borrow that SharedGameResources entity both as immutable (just to read from the stores) as well as mutable (to write the results in the components). That’s impossible. Although it forced me to rewrite some basic architectural code, it illuminated the point that stores of game systems (like the “databases” of mental status effects or of character traits) are separate to the Entity-Component System, which handles a lot of mutation. In the end, Rust’s compiler steers you towards proper architecture, because you simply can’t run your program otherwise.
Pingback: Interdimensional Prophets (Game Dev) #4 – The Domains of the Emperor Owl
Pingback: Interdimensional Prophets (Game Dev) #6 – The Domains of the Emperor Owl