Making a Point and Click Adventure in Arcweave and Godot — Part 3: Logic and State
How the Arcweave plugin transfers story variables and logic into the Godot game engine
A logical gap
This series begins with our first efforts to make a game written in Arcweave and developed in Godot. In the second part, we talk about our quest for a visual and friendly way of marking each dialogue’s starting element, so the player’s actions lead to game responses.
What happens with dialogue including dynamic content, though? What if the dialogue flow changes, depending on the game state (i.e. the value of a variable)?
In other words, how do we get the story logic across to the game engine?
Arcweave applies logic in two ways: in branches and within elements. In both cases, we control logic with arcscript, the app’s simple scripting language.
Logic in branches
Arcweave has an object called branch, which evaluates conditions and diverts or stops the flow according to the result. For a branch to work, it must have an “if” condition. It may optionally have “else if” conditions and one “else” condition.
Logic inside element content
Besides branches, Arcweave also accepts logic within an element’s content. This can mean variable checks and assignments, as in this example:
Or it can mean checks triggering the rendering of different content:
Transferring content and logic alike
The Story class
In the first part of this article series, we mentioned the problem of transferring the logic and how it resulted in the evolution of the Arcweave plugin for Godot. It is now time to get into the specifics of that.
The Arcweave plugin has a Story
class, of which the methods allow direct access to the story variables, the current element, its content (static or dynamic), its attached components, and its valid options (again, as a result of in-branch logic).
var story = Story.new()
story.get_state()
story.get_current_element()
story.get_current_element().components
story.get_current_content()
story.get_current_options()
Evaluating arcscript expressions
We said the get_current_options()
method returns valid options, because options dependent on game state will only appear if a branch condition is true
.
In the same way, the get_current_content()
method returns the current element's content, after evaluating whatever arcscript expressions it may contain.
So, the plugin saves us from the headache of parsing and evaluating Arcweave’s scripts and functions. Each of the above methods simply returns what we want.
Accessing story variables directly
The get_state()
method returns all the story variables and their current values. These exist in the state_export.gd
, one of the two files exported from Arcweave (the other being data_export.gd
, which roughly said contains the project's whole content).
A note on dialogue flow
In the previous article, we described the process of getting a dialogue tree’s starting element. To run a dialogue, we set the relevant element as current:
story.set_current_element(element_id)
… and then fetch its content and components, using the methods mentioned further above.
The element’s content gets rendered according to the directives set by its metadata. (More on how our game’s components work as meta-data carriers, in the next installment of this series.) You can find a detailed analysis of the dialogue routine on the game’s repository.
Dialogue bottlenecks: an application of logic
Our game includes an NPC. Every time you talk to him, you pick up the conversation from where you have left it (which is a standard for adventure games and what you would expect from any reasonable game world).
Obviously, this requires the application of logic. The dialogue tree includes variable assignments and checks. Each time your dialogue with the NPC reaches a milestone, a variable’s value increments. The next time you make conversation, a branch sends you to that milestone and you continue from there.
Due to the fact that those milestones also work as bottlenecks for the dialogue tree (thus gathering branching flows back to one node), we used that name.
Our bottlenecks are also used to create loops in dialogue options. After the player picks a dialogue option and the flow follows the branch of its respective response, it can then send the flow back to that same bottleneck, for the player to pick another option (with the previously followed choice still present or now omitted).
In a nutshell, the game developer does not need to do extra work to transfer the logic and content from the Arcweave project to the game. The plugin does all the necessary evaluations and offers the results on a plate, for the dev to use as they wish.
In the 4th and final part of this series, we will discuss how Arcweave’s components serve as our game’s metadata carriers.
Until then, you can find our plugin for Godot at its repository (with documentation) or the Godot Asset Library.
Play our point and click adventure demo Regrets on its itch.io page and download its source from its own repository.
For a simpler demo, why not try our Play Mode at Godot, which implements Arcweave’s play mode in a simple Godot project.
Finally, watch our Arcweave Integrations Series on YouTube, for a taste of how the plugin works.
And, of course, always… Let the games begin!