Versions 0.2.3 and 0.2.4 changelogs, character drives and memory optimization


Happy New Year! Today we have new builds for F2P players, the lowest Patreon tiers and the higher Patreon tiers, as usual.

This is version 0.2.3's changelog: Link.

And this is version 0.2.4's changelog: Link.

These updates include new actions for Padmiri, Valtan and Maaterasu, 3 story events, the introduction of character drives and new effects from sex scenes, among other things. In today's post I'll discuss this drives mechanic, as well as some performance issues related to Twine's more obscure aspects.

Character Drives

I want Unholy Arts to be a game where the NPC protagonists evolve along with the story and the events that affect them. There are different degrees of ambition here: you may write a linear story where the characters' psyche evolve with the plot, a story with different branches where the evolution of the characters varies depending on which path is chosen by the reader or player, and finally, you may make a system where the characters' behaviors and the events that make them evolve are the result of emergent gameplay, or a simulation. This last degree is by far the least explored and the most experimental one, and I'd lie if I claimed that I wasn't excited about giving it a try, but in order to shield myself against a scenario where the end result wasn't that interesting, I decided very early in the development of Unholy Arts that the game would aim for a blend of all approaches. This allows me to create something new while minimizing the risk that the "new" part turns out to be underwhelming. Characters' drives is one of the mechanics that I'll use to implement the last form of character evolution.

Character drives are, in short words, stats that represent the goals, views and ambitions of each character. They have an "experience" value and a "level" value. The current drives are "Self-improvement" (character gives high value to improve themself), "Love" (character seeks protecting, pleasuring and being accompanied by their loved ones), "Pleasure" (character seeks pleasure, possibly without regarding the desires of others), "Cooperation", "Domination" (character prefers either cooperation or domination and competition, both as a strategy and as lifestyles) and "Ambition" (the character feels they require to be remarkable and powerful, be it for selfish or selfless reasons).

For each character, these drives determine their prefered strategies, actions and choices, and different experiences will make them change their views in different ways. For instance, a character that is constantly losing battles will see their self-improvement drive grow, representing that they need to increase their efforts to face the challenges they meet, while a character who enjoys sex with a dominant character may see their pleasure drive grow, and their domination drive shrink.

At the moment, the formula used to determine the level is the following one:

Required experience = ( level * 175 ) + ( ( level^2 ) * 15 );

Which was adjusted from the previous:

Required experience = ( level * 200 ) + ( ( level^2 ) * 50 );

Since I felt that the square component was walling level growth too fast.

The current systems that add or decrease drive experience are relatively simple. For instance, the results of a battle won by the aggressor are:

addPointsToDrive(gC(winner).dDomination,10); // Winner gains 10 domination drive experience points
addPointsToDrive(gC(winner).dAmbition,10);
addPointsToDrive(gC(loser).dImprovement,10);

Or, in case the defender wins:

addPointsToDrive(gC(loser).dImprovement,10);
addPointsToDrive(gC(loser).dDomination,-5);
addPointsToDrive(gC(loser).dAmbition,-5);
addPointsToDrive(gC(winner).dDomination,5);
addPointsToDrive(gC(winner).dAmbition,5);

In both cases, if the winning team's included a character that wasn't in a submissive relationship with the team's leader:

addPointsToDrive(gC(cK).dCooperation,10); // All characters in the team gain drive experience points

But how is this translated into different behavior?

At the moment, NPCs' AIs take decisions by evaluating all possible missions, assigning weights to them depending on the circumstances (for example: a character is more likely to train if it's training period, and less likely if their bar stats are getting depleted), and making a weighted random choice among them. Therefore, it's easy to link behavior and drives by including the level in the weight calculations:

// Weight calculation for initiating a challenge (mchoice1) and initiating an assault (mchoice2):
mChoice1.weight += 10 + gC(this.charKey).dAmbition.level * 6 + gC(this.charKey).dImprovement.level * 3;
mChoice2.weight += 10 + gC(this.charKey).dAmbition.level * 3 + gC(this.charKey).dDomination.level * 6;

Up to a certain point, this system serves to generate emergent behavior evolution, which is the goal, but I'm not completely satisfied about the results. A later update may include weight calculation and even prohibition from initiating certain actions depending on the percentage of any given drive level over the total of the character's drives. You may note that the current system already takes these percentages into account in an indirect way, but perhaps that change may emphasize the results.

Performance and optimization

Some time around a month and a half ago I came across a few problems related to the way Twine -the framework on which Unholy Arts is built- manages its stories' memory. A small amount of users were reporting the game crashing, along with error messages mentioning exceeding local memory. If you're having these issues, you have instructions to help you solve them it in the updated readme file. After researching the issue and discussing with Twine developers (mandatory mention for HiEv here, who was particularly helpful), it turns out that Twine games store story variables on the browser's local memory, which is often limited to 5MG. While this isn't an issue for most Twine games, it's problematic for Unholy Arts, as it keeps track of far more data than your typical Choose Your Own Adventure game. All in all, I've had to change some plans for Unholy Arts and I'll have to edit considerable portions of the code, or else the issues previously mentioned will affect an increasing amount of players.

Among the different solutions I'm going to apply over time, there are: moving elements stored in the browser's local memory to a static Twine object called "setup", identify specific story variables that will not be used again and delete them from memory when the player reaches certain parts, and, in some cases, move away from from the typical OOP grammar and use a FP grammar instead, in order to make some objects lighter.

I had initially planned to span large regions when the adventures sections took the protagonists to each tribe, with its inhabitants represented with as much detail as any other character, but character objects are already large enough and I prefer to use whatever memory I may squeeze to add secondary protagonists instead, while the data of generic characters will have very short lifespans. This decision also allows me to avoid sacrificing large degrees of complexity and detail.

Files

Unholy Arts v0.2.3 Free.zip 2.7 MB
Jan 01, 2021

Get Unholy Arts

Download NowName your own price

Leave a comment

Log in with itch.io to leave a comment.