Making a Point and Click Adventure in Arcweave and Godot — Part 4: Metadata
How we use Arcweave’s components to transfer information to the game engine
In this project, we wanted to demonstrate the flexibility of Arcweave’s components, so we used them in two different ways:
- to get the starting element of any dialogue and
- to pass metadata during an element’s rendering.
We describe the first use in this series’ 2nd article. The second use is what we will be going through in this article.
Necessary metadata
Besides the elements’ content and arcscript’s logic, there is also the need to transfer other pieces of information to the game engine. For example:
- “the speaker of this line is Andreas.”
- “the player and the NPC talk simultaneously.”
- “this content must be displayed as a title.”
- “the game ends here.”
- “there is a short pause here.”
- “after saying this line, the player exits the recently clicked door.”
- “play a sound effect here.”
- “add this item to the inventory.”
We call these pieces of information metadata, since they are neither content nor game state. Needless to say, they are still very important.
To manage those, we associate them with custom-made types of components.
Components
The component class
The Arcweave plugin includes classes for the main Arcweave items: elements, boards, and components. Each of them gives us easy access to its members.
In the case of the component class, its variables and methods allow easy access to a component’s ID, name, cover, and list of attributes. For example, the following method looks up an attribute by name and returns it as a Dictionary:
get_attribute_by_name(name)
Since our game uses components a lot — to signify dialogue speakers, verb/object combinations, and other metadata — it calls get_attribute_by_name
all the time.
Component types
In Arcweave, we can create components for any reusable entity, like characters, items, locations, spells… Anything our game needs.
In our game, to stay consistent and meaningful, we divided those components to specific types, so the game can tell what to do with each one. To assign types to a component, we created an attribute called type
, which consistently appears in all our components.
The other consistent attribute in our game’s components is its object name or objectName
. For example, our game contains 2 components of the type character
, which are the player (objectName
: you
) and Andreas, the NPC (objectName
: andreas
). It also contains various components of the type item
, like the Amstrad computer (objectName
: amstrad
), the adventure game scripts (objectName
: gameScripts
), or the generic, fallback object mentioned in the 2nd part of this article series (objectName
: generic
).
Furthermore, we have components that affect the dialogue flow, under the type dialogueFlow
, like pause
or overlapNext
.
Finally, we also made an animation
type, but didn't get around to using it; we decided to keep things simple regarding production and not bother with animating the player for anything other than walking.
You can see a full list of our components, their types, and object names, in our game’s repository.
Getting components at runtime
The routine
As the game follows the Arcweave project’s flow, it renders one element after another, waiting for the user’s input (if there are options) or a timer’s timeout (if there are not) in between. When it reaches an element (the “current element”), not only does it get its content (as we discussed in the previous part of this series), but it also iterates the attached components and classifies them, based on their type. Depending on the types of components found, the game runs various routines.
For example, the routines for dialogueFlow
components are executed before the handling of the current content. This way, a pause
or overlapNext
component are taken into consideration, changing the default behaviour of rendering the content. In the case of pause
, a short pause is inserted before the content's rendering, while in that of overlapNext
, the content is not rendered but stored, to be displayed simultaneously with that of the next element.
You can study the whole function render_element()
, which is responsible for diverting to component classification and handling of the various routines, in the readme file of the project's git repository. For the sake of this article, though, we can go through the simple example of rendering a title.
Rendering content as a title: an example
Our game’s default behaviour of rendering an element’s content is to pair it with one (or more) speaker component(s), so it be delivered as dialogue lines of one or more characters.
An exception to that is the use of the title
component (type
: dialogueFlow
, objectName
: title
). If the current element has such a component attached to it, the game renders the line as a title, with a bigger font and centered on the screen.
Conclusion & takeaways
Compared to other systems we have worked with, Arcweave’s components offer an easy and visual way to assign metadata to the story’s current content.
The need for component “types” seems to be screaming for implementation of component templates and/or classes, in Arcweave. Our team is aware of this need for quite a while and its implementation is in the top 5 of our priorities’ list.
Another need is for better management of that long list of global variables.
One solution could be to implement a folder system (e.g. create a separate folder for all inventory-related variables — like i_amstrad
, i_magazines
, and i_gameScripts
—and another one for dialogue, topic-related variables—like t_amstrad
, t_magazines
, and t_gameScripts
). Another solution could be creating component variables, so e.g. the Amstrad component would then have amstrad.topic
and amstrad.inventory
to deal with. This is another issue our team is looking forward to solve in the near future.
Despite the above inconveniences, the overall feeling is that Arcweave served us really well in the creation of a short point and click game, not only as far as the dialogue trees go, but covering every aspect of the game’s puzzles and logic.
The Godot plugin took all the weight of dialogue and logic-handling off the developer’s shoulders, while the web API (mentioned in this series’s first part) made it extremely easy to fetch story updates into the engine.
Well, this is the last part of this series of articles. Congratulations for making it all the way to here! We hope our short demo has whetted your appetite to write your own amazing games! Go ahead — try the new Arcweave plugin for Godot and let us know what you think!
And if you are not a Godot person, stay put: new plugins are coming this year, for Unity and Unreal!
Hmm… We’d better start writing demos for those babies, as well…
You can find the Arcweave 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!