XaiJu
Muffin Projects
Muffin Projects

boosty


Techlog #2. Experimental. Practical Example. Quests [en]

Let's analyze a code example related to the quest system in the game.
Here is the main class designed to initialize an instance of the class in our game. Let's go through the fields in the first block and their purpose:
id - a unique identifier. Specifically, I need it to be able to find the instance quickly if there is an urgent need.
name - the name displayed in the quest window for the player.
description - the description displayed there.
steps - a list of steps for the quest. In the game, you may have noticed that quests can have multiple steps.
reward - a list of rewards. By default, it is an empty list.
availability - a string with a boolean expression to check the availability of the quest.

I arrived at this solution not immediately, but when I encountered the need to make changes between updates. I had to fix names, quest availability, and rewards manually by finding the instance in the store module and rewriting the necessary fields. I decided that I didn't want to deal with this hassle, and the only value I wanted to remain permanently valid was its "done" flag. In other words, it indicates whether the quest is completed or not.

Let's go through the other methods of the class:
Most field names sound and look self-explanatory. If you are familiar with classes to some extent, you should understand that getters and setters are standard things for a class. That's why I initialized them for the fields where I might potentially make mistakes. For example, I could make a typo in the name or change my mind about the rewards for this quest.

The class structure for quest steps looks almost identical. They are essentially smaller quests.

Here's how an instance is created:
I came up with a pattern using labels to declare similar variables. The idea is that they are reinitialized every time the game is launched or loaded, allowing me to easily correct any previous errors.
You may notice a few other methods like set_variable and is_quest_done. These are small utility functions.
The idea is not to overwrite the instance completely if it has already been declared before and not to overwrite its "done" value, which is crucial for the game.

I couldn't come up with a smarter way than storing functions as strings for the reward and availability fields. The reason is that after completing a quest, I want a series of functions to be executed, which will provide rewards to my character, such as stat upgrades, completion of other quests, adding new steps, or anything else my imagination allows.
The eval function is a standard practice in almost every programming language. It converts your string into executable code. If I simply wrote the functions there, the list would contain the results of their execution, which would make no sense at all.

The same situation applies to availability. Why is it even necessary? Often, I want a quest to become available only after the player fulfills certain conditions. Once all conditions are satisfied, the player will finally receive the quest.

is_quest_done is a simple method to check whether the quest is currently in the player's active quests and if it has been completed. In the above code example, it is used so that when a player enters a new version of the game, they will immediately receive this quest if it is available to them because it wasn't even declared in earlier versions of the game.

What does label_translation[key_name] mean? The thing is, RenPy doesn't allow you to add translations using standard methods for strings declared within Python code. That's why I create a separate dictionary for translations of such strings.
It looks something like this:
Each character in the game has their own similar dictionary of values. Afterward, they are all combined into one and declared right after the game starts.
All variables in the game are organized into separate labels and ultimately end up in key labels for RenPy, such as "after_load" and "start."

Techlog #2. Experimental. Practical Example. Quests [en] Techlog #2. Experimental. Practical Example. Quests [en] Techlog #2. Experimental. Practical Example. Quests [en] Techlog #2. Experimental. Practical Example. Quests [en] Techlog #2. Experimental. Practical Example. Quests [en] Techlog #2. Experimental. Practical Example. Quests [en] Techlog #2. Experimental. Practical Example. Quests [en]

More Creators