Explaining: Status effects
Added 2021-10-21 04:56:51 +0000 UTCThis is one of those 'behind the scenes' thingies that also explains a few features of the Twine story engine, you might find this useful if you ever develop your own games or use Twine. It's a long block of text and also talks about status effects in another game.
One thing I'm always keeping an eye out for is performance. Any combat system needs snappy turns and responsiveness. A tedious change that helped quite a bit in Slime Dungeon was changing status effects to purely rely on a turncounter rather than also asking if the status in question is applied/active.
What I mean is, before that change, the game asked 'is this target Blinded? And if so, how long?', and then afterwards, it only asked 'How long is this target blinded?', with a simple integer number. 0 meant no blind at all ('blinded for 0 turns'), 1 to 5 meant that many turns of blind, and infinite... Was -1.
However, it always kept tracking that single digit number for every status effect, and there were dozens, and there were like 5 or 6 entities on screen at a time... Imagine about 50 statuses * 6 entities means 300 variables being tracked at a time.
Over a third of Beth's information is tracked as these kinds of variables, which are literally just 0's. Here's what it looks like
"blindCounter": 0, "poisonCounter": 0, "silenceCounter": 0,
"slowCounter": 0, "frozenCounter": 0, "burningCounter": 0,
"isPetrified": false, "isMini": false, "isOiled": false,
"isJelly": false, "isBerserked": false, "isCharmed": false,
"isConfused": false, "paralyzeCounter": 0, "boundCounter": 0,
"sleepCounter": 0, "isFrogged": false, "isCursed": false,
"isZombied": false, "isInanimated": false, "inanimateDesc": "Wuff!",
"doomCounter": 0, "bleedCounter": 0, "blightCounter": 0,
"meltCounter": 0, "isBlobbed": false, "isRubbered": false,
"floatCounter": 0, "boostCounter": 0, "isSaved": false,
"isAtkDown": false, "hasteCounter": 0, "regenCounter": 0,
"shineCounter": 0, "invisCounter": 0, "isDefDown": false,
"defUpCounter": 0, "atkUpCounter": 0,
"isGrappled": false, "grappler": "none",
"despairCounter": 0,"flyingCounter": 0, "enthrallCounter": 0,
"amplifyCounter": 0, "amplifyElem": "none",
"contagionCounter": 0, "contagionEffect": "none",
"venomCounter": 0, "multiCounter": 0, "multiWhat": "none",
"isRevenged": false, "revengeMulti": 1, "revengeAlias": "none",
"bimboCounter": 0, "spliceCounter": 0, "spliceAnimal": "none",
"fearCounter": 0, "mergeCounter": 0, "rootCounter": 0,
So my new status tracking system is even simpler... There aren't even any 0s. Numbers are only tracked if the status is applied. So the game asks, 'How long is this guy blinded for?' and the response is 'UNDEFINED, don't even know what blind IS'
The thing is, that's still good enough to count as not being blind!
There's no real bad trade-off associated with doing it this way, it just gets me nothing but upsides. Additionally, I am streamlining how indefinite vs temp status effects are handled. Previously, temp debuffs had a -1 to 5 value, and indefinite ones like Petrified were true or false. However, now the indefinite ones will be represented as a number, which means I'll be able to use a more efficient system for applying debuffs as part of item/attack chances.
What I mean is, Slime Dungeon's Bandit Blade and similar weapons used an exploit to apply the status effect. There's no manually typed up code saying 'if bandit blade then apply poison, if silent saber then apply silence', instead each item has an associated effect with it, or not. If it does, then this effect name, be it 'poison' or 'silence' is then fed into a string of text, and then that string of text is forced to print. And the forced print forces a command to run (say, '<<set $atktarget.silenceCounter to 4>>'), which also references the amount of turns associated with this item's effect.
So that previous command is built by doing this
<<print '<<set $atktarget.' + X + 'Counter to ' + Y + '>>'>>
Where X is the effect and Y is the duration. I used the same exploit to create the equipment/inventory list for the game. But anyway, as indefinite statuses used true/false instead of numbers, you can imagine that it required conditionals to check if it's that kind of status. So for indefinites, the 'formula' was different:
<<print '<<set $atktarget.is' + X + ' to true'>>'>>
Where X is 'petrified' or whatever.
Instead, by streamlining the names and numbers of these statuses in the code, they won't require exemptions. It will also be easier to handle them in general as I was inconsistent in using their tenses in the code, because Petrify status is .isPetrified whereas Mini status is .isMini and Jelly is .isJelly, which is just not fun.
As you can tell, I really, really like status effects. They're my favorite aspect of RPGs. If I could have infinitely many, I would LOL
So I'm going to introduce some status effects for this other thing I'm working on, on the side. This is my sci-fi game idea, working title is Sonderweg. I have a lot of stuff typed up for it, I'm just organizing it at the moment. The rest relates to this other game IDEA (I've only got art for it atm), so feel free to skip, nothing more Slime Dungeon related.
The higher-damage ELEM debuffs below are less likely to hit, and last for less turns, as well as associated with rarer items/damage types.
By which I mean CHARGED, CHILLED, WARMED, EXPOSED, SOAKED.
You'll notice that CHILLED -> WARMED -> CHILLED and so on is a pretty good combo. Few things resist Thermal Shock very well.
The POWER variant of each of these AMMO buffs, has an unlimited duration but will delete any other existing elemental change buffs. It will also overwrite base element.
Enflamed, Energized, Envenomed, and Enzymed are the most common AMMO buffs, but Encrustred is also somewhat present. The other ammo buffs are purely for posterity (enriched, ensouled), and rarely used.
This gives THERM/ELEC/BIO/CORRO more prevalance, as I expect them to be quite common elements. I would consider Envenomed and Enflamed to be early/low-tier ammo buffs, whereas Energized and Enzymed are stronger and more mid-early game.
ENERGIZED can inflict Slowed, Paralyzed, Charged, which of course vary drastically in severity. This lends more to ELEC's luck factor, something I want heavily associated with that elem.
The PROOFS are added by Barriers. Barriers are consumable items that shield 1 or multiple targets. A Barrier used on all party members only lasts 1 turn (use if anticipating an AOE attack), whereas a Barrier on 1 target will last 3 to 5 turns or so.
Thermo Barrier - Adds Fireproof
Cryo Barrier - Adds Frostproof
Temp Barrier - Adds both Frostproof and Fireproof
Kino Barrier - Adds Bulletproof
Generally Frostproof is rare and not needed, it's included for posterity. The Proofs protect against the most common elems (Thermal, Electric, Kinetic), thus adding variety/balance to elem use. Late game foes might use these commonly.
Their codes ingame
.chilled
.warmed
.oiled
.charged
.soaked
.exposed
.bandaged
.spent
.disarmed
.jammed
.overheated
.enflamed
.energized
.envenomed
.encrusted
.enzymed
.enriched
.ensouled
.enervated
.emped
.irradiated
.fireproofed
.shockproofed
.bulletproofed
.frostproofed
<<nobr>>
<<if $status.fireproofed is not undefined>>
<<message "<img src='icons/fireproofed.png'>" btn>>
Fireproofed
- 50% THERM damage taken
Lasts until expired.
<</message>>
<</if>>
<<if $status.bulletproofed is not undefined>>
<<message "<img src='icons/bulletproofed.png'>" btn>>
Bulletproofed
- 50% KINE damage taken
Lasts until expired.
<</message>>
<</if>>
<<if $status.shockproofed is not undefined>>
<<message "<img src='icons/shockproofed.png'>" btn>>
Shockproofed
- 50% ELEC damage taken
Lasts until expired.
<</message>>
<</if>>
<<if $status.frostproofed is not undefined>>
<<message "<img src='icons/frostproofed.png'>" btn>>
Frostproofed
- 50% CRYO damage taken
Lasts until expired.
<</message>>
<</if>>
<<if $status.chilled is not undefined>>
<<message "<img src='icons/chilled.png'>" btn>>
Chilled
+ 50% THERM damage taken
+ 25% ELEC damage taken
- 25% CORRO damage taken
- 25% CRYO damage taken
Lasts until exploited or expired.
<</message>>
<</if>>
<<if $status.warmed is not undefined>>
<<message "<img src='icons/warmed.png'>" btn>>
Warmed
+ 50% CRYO damage taken
+ 25% CORRO damage taken
- 25% ELEC damage taken
- 25% THERM damage taken
Lasts until exploited or expired.
<</message>>
<</if>>
<<if $status.oiled is not undefined>>
<<message "<img src='icons/oiled.png'>" btn>>
Oiled
+ 100% THERM damage taken
- 25% CORRO damage taken
- 25% CRYO damage taken
- 25% ELEC damage taken
Lasts until exploited or expired.
<</message>>
<</if>>
<<if $status.charged is not undefined>>
<<message "<img src='icons/charged.png'>" btn>>
Charged
+ 75% ELEC damage taken
- 25% THERM damage taken
- 25% CRYO damage taken
Lasts until exploited or expired.
<</message>>
<</if>>
<<if $status.soaked is not undefined>>
<<message "<img src='icons/soaked.png'>" btn>>
Soaked
+ 50% ELEC damage taken
+ 25% CRYO damage taken
- 25% THERM damage taken
- 25% CORRO damage taken
Lasts until exploited or expired.
<</message>>
<</if>>
<<if $status.exposed is not undefined>>
<<message "<img src='icons/exposed.png'>" btn>>
Exposed
+ 25% ALL damage taken
Associated with Acid
Lasts until exploited or expired.
<</message>>
<</if>>
<<if $status.enflamed is not undefined>>
<<message "<img src='icons/enflamed.png'>" btn>>
Enflamed
Adds THERM element to attacks in addition to existing elements
The more existing elements, the less it will contribute
25% chance to cause Ignited or Warmed
Lasts until expired.
<</message>>
<</if>>
<<if $status.energized is not undefined>>
<<message "<img src='icons/energized.png'>" btn>>
Energized
Adds ELEC element to attacks in addition to existing elements
The more existing elements, the less it will contribute
25% chance to cause Paralyzed or Slowed or Charged
Lasts until expired.
<</message>>
<</if>>
<<if $status.envenomed is not undefined>>
<<message "<img src='icons/envenomed.png'>" btn>>
Envenomed
Adds BIO element to attacks in addition to existing elements
The more existing elements, the less it will contribute
25% chance to cause Sickened or Poisoned
Lasts until expired.
<</message>>
<</if>>
<<if $status.encrusted is not undefined>>
<<message "<img src='icons/encrusted.png'>" btn>>
Encrusted
Adds CRYO element to attacks in addition to existing elements
The more existing elements, the less it will contribute
25% chance to cause Slowed or Frozen or Chilled
Lasts until expired.
<</message>>
<</if>>
<<if $status.enzymed is not undefined>>
<<message "<img src='icons/enzymed.png'>" btn>>
Enzymed
Adds CORRO element to attacks in addition to existing elements
The more existing elements, the less it will contribute
25% chance to cause Exposed
Lasts until expired.
<</message>>
<</if>>
<<if $status.ensouled is not undefined>>
<<message "<img src='icons/ensouled.png'>" btn>>
Ensouled
Adds PSY element to attacks in addition to existing elements
The more existing elements, the less it will contribute
25% chance to cause Stunned
Lasts until expired.
<</message>>
<</if>>
<<if $status.enriched is not undefined>>
<<message "<img src='icons/enriched.png'>" btn>>
Enriched
Adds RAD element to attacks in addition to existing elements
The more existing elements, the less it will contribute
25% chance to cause Irradiated or Blinded
Lasts until expired.
<</message>>
<</if>>
<<if $status.enervated is not undefined>>
<<message "<img src='icons/enervated.png'>" btn>>
Enervated
Enervated - Either deletes existing ammo buff or add Atomic. Not sure
Adds ATOM element to attacks in addition to existing elements
The more existing elements, the less it will contribute
Lasts until expired.
<</message>>
<</if>>
<<if $status.bandaged is not undefined>>
<<message "<img src='icons/bandaged.png'>" btn>>
Bandaged
Prevents further healing via First Aid
Lasts until properly healed (by Item or Rest), or expired.
<</message>>
<</if>>
<<if $status.spent is not undefined>>
<<message "<img src='icons/spent.png'>" btn>>
Spent
Out of ammo. Any gun-based attacks won't work
Lasts until reloaded or the end of battle.
<</message>>
<</if>>
<<if $status.jammed is not undefined>>
<<message "<img src='icons/jammed.png'>" btn>>
Jammed
Out of order. Any gun-based attacks won't work. ~Repair must happen before Reload~
Lasts until repaired or the end of battle.
<</message>>
<</if>>
<<if $status.overheated is not undefined>>
<<message "<img src='icons/overheated.png'>" btn>>
Overheated
Too hot to shoot. Any gun-based attacks won't work for the duration
Lasts until expired, usually 2 or 3 turns.
<</message>>
<</if>>
<<if $status.disarmed is not undefined>>
<<message "<img src='icons/disarmed.png'>" btn>>
Disarmed
Weapon is lost or stolen. Can't attack until weapon is retrieved.
Lasts until resolved or the end of battle
<</message>>
<</if>>
<<if $status.irradiated is not undefined>>
<<message "β’οΈ<img src='icons/irradiated.png'>" btn>>
Irradiated
Organics take BIO damage each turn, Inorganics instead take ELEC damage
Lasts until expired
<</message>>
<</if>>
<<if $status.emped is not undefined>>
<<message "π<img src='icons/emped.png'>" btn>>
EMPed
Sent to back of turn queue, now certain Actions are disabled and Accuracy is halved. Only affects Inorganics
Lasts until expired
<</message>>
<</if>>
^ As Inorganics are immune to certain debuffs, this major debuff can hit them as an exchange. Represents general havoc to the system.
Other statuses...
Overwatch
Guard
Immunity
π€’ Sickened - Take extra bio damage from all sources
<</nobr>>