Dynamic Stat Calculation Guide
Dynamic Stat Calculation Guide
This guide explains how to use the dynamic stat calculation feature to create complex relationships between stats in your game world.
Overview
The dynamic stat calculation feature allows you to write JavaScript code that automatically calculates a stat’s value based on other stats. This enables you to create:
- Derived stats that depend on other stats (e.g., carrying capacity based on strength)
- Compound stats that combine multiple stats (e.g., defense calculated from armor + agility)
- Threshold effects that change based on conditions (e.g., speed penalties when health is below 30%)
- Complex formulas for game mechanics (e.g., damage calculations, regeneration rates)
How It Works
- Each stat can have an optional JavaScript code snippet
- When stats are updated during gameplay, the code is executed in a safe environment
- The code has access to all current stats and must return a number
- The returned number becomes the new value of the stat (constrained by min/max)
Writing Stat Code
Basic Syntax
Your code should be valid JavaScript that returns a number. The code has access to a stats
array containing all stats in the game.
// Example: Return a fixed value
return 50;
Accessing Other Stats
To access other stats, use the stats
array and the find
method to locate stats by name:
// Example: Return the value of another stat
const health = stats.find(s => s.name === 'Health')?.value || 0;
return health;
The ?.
operator safely accesses the value property (returns undefined if the stat isn’t found), and the || 0
provides a default value of 0 if the stat isn’t found.
Stat Properties
Each stat in the stats
array has the following properties:
id
: Unique identifiername
: Display name of the stattype
: Type of stat (‘number’ or ‘list’)description
: Text descriptionmin
: Minimum valuemax
: Maximum valuevalue
: Current valueregen
: Regeneration ratecode
: The code string (you don’t typically need to access this)descriptors
: Array of threshold-based descriptions
Examples
Percentage-Based Stat
Calculate a stat as a percentage of another stat:
// Make Stamina 75% of Health
const health = stats.find(s => s.name === 'Health')?.value || 0;
return health * 0.75;
Average of Multiple Stats
Calculate a stat as the average of multiple other stats:
// Make Defense the average of Strength and Agility
const strength = stats.find(s => s.name === 'Strength')?.value || 0;
const agility = stats.find(s => s.name === 'Agility')?.value || 0;
return (strength + agility) / 2;
Conditional Calculation
Calculate a stat differently based on conditions:
// Make Speed depend on Health
// Full speed when Health > 50, otherwise reduced
const health = stats.find(s => s.name === 'Health')?.value || 0;
const baseSpeed = 100;
if (health > 50) {
return baseSpeed;
} else {
// Reduce speed by up to 50% as health approaches 0
const healthPercent = health / 50;
return baseSpeed * (0.5 + (healthPercent * 0.5));
}
Complex Formula
Use more complex formulas for game mechanics:
// Calculate Damage based on Strength, Weapon Skill, and a random factor
const strength = stats.find(s => s.name === 'Strength')?.value || 0;
const weaponSkill = stats.find(s => s.name === 'Weapon Skill')?.value || 0;
// Base damage from strength
const baseDamage = strength * 0.8;
// Skill multiplier (1.0 to 2.0 based on skill)
const skillMultiplier = 1.0 + (weaponSkill / 100);
// Random factor (±20%)
const randomFactor = 0.8 + (Math.random() * 0.4);
return baseDamage * skillMultiplier * randomFactor;
Diminishing Returns
Implement diminishing returns for stat scaling:
// Calculate Dodge Chance with diminishing returns
const agility = stats.find(s => s.name === 'Agility')?.value || 0;
// Diminishing returns formula
// First 50 points give full value, after that diminishing returns
let dodgeChance = 0;
if (agility <= 50) {
dodgeChance = agility * 0.5; // 0.5% per point
} else {
// First 50 points give 25% dodge
// Additional points give less and less
const baseChance = 25;
const diminishedPoints = agility - 50;
const diminishedChance = 25 * (1 - Math.exp(-diminishedPoints / 50));
dodgeChance = baseChance + diminishedChance;
}
// Cap at 75%
return Math.min(dodgeChance, 75);
Resource Consumption
Calculate resource consumption based on other stats:
// Calculate Hunger Rate based on activity and size
const activityLevel = stats.find(s => s.name === 'Activity')?.value || 0;
const size = stats.find(s => s.name === 'Size')?.value || 0;
// Base consumption rate
const baseRate = 1;
// Activity multiplier (1.0 to 3.0)
const activityMultiplier = 1.0 + (activityLevel / 50);
// Size factor (larger characters consume more)
const sizeFactor = size / 50;
return baseRate * activityMultiplier * sizeFactor;
Best Practices
- Keep it simple: Complex code can be hard to debug and may impact performance
- Handle missing stats: Always use default values (
|| 0
) when accessing stats that might not exist - Stay within min/max: The system will automatically clamp your result to the stat’s min/max range
- Avoid infinite loops: Don’t create circular dependencies between stats
- Test your code: Use the “Test Code” button to validate your code before saving
- Add comments: Document your code for future reference
Limitations
- Code execution has a timeout of 1 second to prevent infinite loops
- Circular dependencies between stats may cause unexpected behavior
Troubleshooting
If your code doesn’t work as expected:
- Check for typos in stat names (they are case-sensitive)
- Ensure your code returns a number
- Verify that all stats you’re referencing actually exist
- Use the “Test Code” button to see any error messages
- Add
console.log()
statements to debug your code (output appears in browser console)
Advanced Examples
Stat Scaling with Level
// Scale Health based on Level and Constitution
const level = stats.find(s => s.name === 'Level')?.value || 1;
const constitution = stats.find(s => s.name === 'Constitution')?.value || 10;
// Base health
const baseHealth = 50;
// Level scaling (10 health per level)
const levelBonus = (level - 1) * 10;
// Constitution scaling (2 health per point)
const constitutionBonus = (constitution - 10) * 2;
return baseHealth + levelBonus + constitutionBonus;
Fatigue System
// Calculate Fatigue based on recent actions and Stamina
const stamina = stats.find(s => s.name === 'Stamina')?.value || 0;
const staminaMax = stats.find(s => s.name === 'Stamina')?.max || 100;
const actions = stats.find(s => s.name === 'Recent Actions')?.value || 0;
// Base fatigue from actions
const actionFatigue = actions * 5;
// Recovery from stamina (higher stamina = less fatigue)
const staminaFactor = 1 - (stamina / staminaMax);
// Final fatigue value (0-100)
return Math.min(actionFatigue * staminaFactor, 100);
Carrying Capacity
// Calculate Carrying Capacity based on Strength
const strength = stats.find(s => s.name === 'Strength')?.value || 0;
// Base capacity
const baseCapacity = 50;
// Linear scaling for first 50 points (2 units per point)
let capacity = baseCapacity;
if (strength <= 50) {
capacity += strength * 2;
} else {
// First 50 points add 100 capacity
// After that, diminishing returns
capacity += 100;
capacity += Math.sqrt(strength - 50) * 10;
}
return capacity;
Magical Power
// Calculate Magical Power based on Intelligence, Wisdom, and current Mana
const intelligence = stats.find(s => s.name === 'Intelligence')?.value || 0;
const wisdom = stats.find(s => s.name === 'Wisdom')?.value || 0;
const mana = stats.find(s => s.name === 'Mana')?.value || 0;
const maxMana = stats.find(s => s.name === 'Mana')?.max || 100;
// Base power from intelligence
const basePower = intelligence * 1.5;
// Wisdom bonus (diminishing returns)
const wisdomBonus = Math.sqrt(wisdom) * 5;
// Mana percentage factor (more effective with higher mana)
const manaFactor = 0.5 + (0.5 * (mana / maxMana));
return (basePower + wisdomBonus) * manaFactor;
Files
Get Formamorph
Formamorph
Every choice transforms your body and shapes your adventure
Status | In development |
Author | FieryLion |
Genre | Interactive Fiction |
Tags | Adult, bbw, belly, Erotic, Female Protagonist, inflation, pregnancy, vore, weight-gain |
More posts
- v1.1.6 & v1.1.7 Dynamic Stat Logic, AI Notes2 days ago
- v1.1.4 & v1.1.5 New Features & Fixes23 days ago
- v 1.1.0 & v1.1.3 Major Improvements!69 days ago
- v1.0.1 & v1.0.2 & v1.0.3 patch75 days ago
- Launch! v1.075 days ago
- Quick Setup Guide: (Free!) OpenRouter Setup76 days ago
Leave a comment
Log in with itch.io to leave a comment.