npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@reldens/modifiers

v0.34.0

Published

Reldens - Modifiers

Readme

Reldens - GitHub - Release

Reldens - Modifiers

About

This package provides a modifiers system originally created for the Reldens project, but designed to be used anywhere.

The package includes:

  • Modifier: Apply and revert value modifications to object properties with conditions and limits
  • Condition: Define conditions that must be met before applying modifiers
  • Calculator: Handle mathematical operations (increase, decrease, multiply, divide, percentages, set values)
  • PropertyManager: Access and modify deep object properties using path notation
  • Constants: Pre-defined operation types, comparison operators, and state constants

Installation

npm install @reldens/modifiers

Quick Start

const { Modifier, ModifierConst } = require('@reldens/modifiers');

// Create a player object
let player = {
    health: 100,
    maxHealth: 150,
    attack: 50
};

// Create a modifier to increase attack by 20
let attackBoost = new Modifier({
    key: 'attack-boost',
    propertyKey: 'attack',
    operation: ModifierConst.OPS.INC,
    value: 20
});

// Apply the modifier
attackBoost.apply(player);
console.log(player.attack); // 70

// Revert the modifier
attackBoost.revert(player);
console.log(player.attack); // 50

Detailed Usage Examples

Modifier Class

The Modifier class is the core component for applying value changes to object properties.

Basic Operations

const { Modifier, ModifierConst } = require('@reldens/modifiers');

let character = {
    strength: 100,
    intelligence: 80,
    gold: 500
};

// Increase (INC)
let strengthBonus = new Modifier({
    key: 'str-bonus',
    propertyKey: 'strength',
    operation: ModifierConst.OPS.INC,
    value: 25
});
strengthBonus.apply(character);
console.log(character.strength); // 125

// Decrease (DEC)
let goldCost = new Modifier({
    key: 'shop-cost',
    propertyKey: 'gold',
    operation: ModifierConst.OPS.DEC,
    value: 150
});
goldCost.apply(character);
console.log(character.gold); // 350

// Multiply (MUL)
let criticalHit = new Modifier({
    key: 'crit-damage',
    propertyKey: 'strength',
    operation: ModifierConst.OPS.MUL,
    value: 2
});
criticalHit.apply(character);
console.log(character.strength); // 250

// Divide (DIV)
let weakness = new Modifier({
    key: 'weakness-debuff',
    propertyKey: 'strength',
    operation: ModifierConst.OPS.DIV,
    value: 2
});
weakness.apply(character);
console.log(character.strength); // 125

Percentage Operations

let stats = { damage: 200, defense: 100 };

// Increase by percentage (INC_P)
let damageIncrease = new Modifier({
    key: 'damage-boost',
    propertyKey: 'damage',
    operation: ModifierConst.OPS.INC_P,
    value: 50 // 50% increase
});
damageIncrease.apply(stats);
console.log(stats.damage); // 300 (200 + 50% of 200)

// Decrease by percentage (DEC_P)
let armorPiercing = new Modifier({
    key: 'armor-pierce',
    propertyKey: 'defense',
    operation: ModifierConst.OPS.DEC_P,
    value: 25 // 25% reduction
});
armorPiercing.apply(stats);
console.log(stats.defense); // 75 (100 - 25% of 100)

Set Operations

let player = { level: 1, status: 'normal' };

// Set numeric value (SET)
let levelUp = new Modifier({
    key: 'level-up',
    propertyKey: 'level',
    operation: ModifierConst.OPS.SET,
    value: 10
});
levelUp.apply(player);
console.log(player.level); // 10

// Set string value (SET with string type)
let statusEffect = new Modifier({
    key: 'poison-status',
    propertyKey: 'status',
    operation: ModifierConst.OPS.SET,
    type: ModifierConst.TYPES.STRING,
    value: 'poisoned'
});
statusEffect.apply(player);
console.log(player.status); // 'poisoned'

Value Limits

let character = { health: 50, maxHealth: 100 };

// Modifier with min/max limits
let healing = new Modifier({
    key: 'healing-potion',
    propertyKey: 'health',
    operation: ModifierConst.OPS.INC,
    value: 80,
    minValue: 0,
    maxValue: 100
});
healing.apply(character);
console.log(character.health); // 100 (capped at maxValue)

// Using property-based limits
let manaRestore = new Modifier({
    key: 'mana-potion',
    propertyKey: 'mana',
    operation: ModifierConst.OPS.INC,
    value: 50,
    maxProperty: 'maxMana' // Use maxMana property as limit
});

Deep Property Access

let character = {
    stats: {
        combat: {
            attack: 100,
            defense: 80
        },
        magic: {
            power: 60
        }
    }
};

// Modify nested property using path notation
let magicBoost = new Modifier({
    key: 'magic-boost',
    propertyKey: 'stats/magic/power',
    operation: ModifierConst.OPS.INC,
    value: 25
});
magicBoost.apply(character);
console.log(character.stats.magic.power); // 85

Condition Class

Conditions allow you to control when modifiers should be applied.

Basic Conditions

const { Condition, ModifierConst } = require('@reldens/modifiers');

let player = { level: 15, health: 80, maxHealth: 100 };

// Create conditions
let levelCondition = new Condition({
    key: 'min-level',
    propertyKey: 'level',
    conditional: ModifierConst.COMPARE.GE, // Greater or equal
    value: 10
});

let healthCondition = new Condition({
    key: 'low-health',
    propertyKey: 'health',
    conditional: ModifierConst.COMPARE.LT, // Less than
    value: 90
});

// Test conditions
console.log(levelCondition.isValidOn(player)); // true (15 >= 10)
console.log(healthCondition.isValidOn(player)); // true (80 < 90)

Available Comparison Operators

// All available comparison operators
let conditions = {
    equals: ModifierConst.COMPARE.EQ,        // ===
    notEquals: ModifierConst.COMPARE.NE,     // !==
    lessThan: ModifierConst.COMPARE.LT,      // <
    greaterThan: ModifierConst.COMPARE.GT,   // >
    lessOrEqual: ModifierConst.COMPARE.LE,   // <=
    greaterOrEqual: ModifierConst.COMPARE.GE // >=
};

Modifiers with Conditions

let player = { level: 5, experience: 1200, strength: 50 };

// Create condition
let experienceCondition = new Condition({
    key: 'exp-check',
    propertyKey: 'experience',
    conditional: ModifierConst.COMPARE.GE,
    value: 1000
});

// Create modifier with condition
let experienceBonus = new Modifier({
    key: 'exp-strength-bonus',
    propertyKey: 'strength',
    operation: ModifierConst.OPS.INC,
    value: 10,
    conditions: [experienceCondition]
});

// This will apply because experience >= 1000
experienceBonus.apply(player);
console.log(player.strength); // 60

// Change experience and test again
player.experience = 500;
let newBonus = new Modifier({
    key: 'another-bonus',
    propertyKey: 'strength',
    operation: ModifierConst.OPS.INC,
    value: 20,
    conditions: [experienceCondition]
});

// This won't apply because experience < 1000
newBonus.apply(player);
console.log(player.strength); // Still 60

PropertyManager Class

The PropertyManager handles deep property access using path notation.

const { PropertyManager } = require('@reldens/modifiers');

let propertyManager = new PropertyManager();

let gameObject = {
    player: {
        inventory: {
            weapons: {
                sword: { damage: 50, durability: 100 }
            }
        }
    }
};

// Get deep property value
let swordDamage = propertyManager.getPropertyValue(gameObject, 'player/inventory/weapons/sword/damage');
console.log(swordDamage); // 50

// Set deep property value
propertyManager.setOwnerProperty(gameObject, 'player/inventory/weapons/sword/damage', 65);
console.log(gameObject.player.inventory.weapons.sword.damage); // 65

Calculator Class

The Calculator class handles mathematical operations and can be used independently.

const { Calculator, ModifierConst } = require('@reldens/modifiers');

let calculator = new Calculator();

// Basic operations
console.log(calculator.calculateNewValue(100, ModifierConst.OPS.INC, 25, false)); // 125
console.log(calculator.calculateNewValue(100, ModifierConst.OPS.DEC, 30, false)); // 70
console.log(calculator.calculateNewValue(50, ModifierConst.OPS.MUL, 3, false)); // 150
console.log(calculator.calculateNewValue(60, ModifierConst.OPS.DIV, 2, false)); // 30

// Percentage operations
console.log(calculator.calculateNewValue(200, ModifierConst.OPS.INC_P, 50, false)); // 300
console.log(calculator.calculateNewValue(100, ModifierConst.OPS.DEC_P, 25, false)); // 75

// Revert operations (using revert = true)
console.log(calculator.calculateNewValue(125, ModifierConst.OPS.INC, 25, true)); // 100
console.log(calculator.calculateNewValue(70, ModifierConst.OPS.DEC, 30, true)); // 100

Real-World Examples

RPG Character System

const { Modifier, Condition, ModifierConst } = require('@reldens/modifiers');

// Character data
let character = {
    level: 20,
    class: 'warrior',
    stats: {
        strength: 100,
        agility: 60,
        intelligence: 40
    },
    equipment: {
        weapon: null,
        armor: null
    }
};

// Equipment modifiers
let magicSword = new Modifier({
    key: 'magic-sword',
    propertyKey: 'stats/strength',
    operation: ModifierConst.OPS.INC,
    value: 35
});

let agilityBoots = new Modifier({
    key: 'agility-boots',
    propertyKey: 'stats/agility',
    operation: ModifierConst.OPS.INC_P,
    value: 25 // 25% increase
});

// Class-specific bonuses with conditions
let warriorCondition = new Condition({
    key: 'warrior-class',
    propertyKey: 'class',
    conditional: ModifierConst.COMPARE.EQ,
    type: ModifierConst.TYPES.STRING,
    value: 'warrior'
});

let classBonus = new Modifier({
    key: 'warrior-strength-bonus',
    propertyKey: 'stats/strength',
    operation: ModifierConst.OPS.INC_P,
    value: 20,
    conditions: [warriorCondition]
});

// Apply equipment
magicSword.apply(character);
agilityBoots.apply(character);
classBonus.apply(character);

console.log('Final stats:', character.stats);
// strength: 162 (100 + 35 + 20% of 135)
// agility: 75 (60 + 25% of 60)
// intelligence: 40 (unchanged)

Temporary Buff System

// Buff system with time limits and conditions
let player = { health: 200, maxHealth: 300, mana: 50 };

// Health condition for mana regeneration
let lowManaCondition = new Condition({
    key: 'low-mana',
    propertyKey: 'mana',
    conditional: ModifierConst.COMPARE.LT,
    value: 100
});

// Conditional mana regeneration
let manaRegen = new Modifier({
    key: 'mana-regen-buff',
    propertyKey: 'mana',
    operation: ModifierConst.OPS.INC,
    value: 25,
    maxProperty: 'maxMana',
    conditions: [lowManaCondition]
});

// Apply buff (will work because mana < 100)
manaRegen.apply(player);
console.log(player.mana); // 75

// Try to apply again (still works because mana < 100)
manaRegen.apply(player);
console.log(player.mana); // 100

// Try once more (won't work because mana >= 100)
let player2 = { ...player };
manaRegen.apply(player2);
console.log(player2.mana); // Still 100 (condition not met)

Constants Reference

Operations (ModifierConst.OPS)

  • INC (1): Increase value
  • DEC (2): Decrease value
  • DIV (3): Divide value
  • MUL (4): Multiply value
  • INC_P (5): Increase by percentage
  • DEC_P (6): Decrease by percentage
  • SET (7): Set absolute value
  • METHOD (8): Call custom method
  • SET_N (9): Set value (alternative)

Comparison Operators (ModifierConst.COMPARE)

  • EQ: Equal to (===)
  • NE: Not equal to (!==)
  • LT: Less than (<)
  • GT: Greater than (>)
  • LE: Less than or equal (<=)
  • GE: Greater than or equal (>=)

Data Types (ModifierConst.TYPES)

  • INT: Integer type
  • STRING: String type

Modifier States

  • MOD_MISSING_KEY: Missing key parameter
  • MOD_MISSING_PROPERTY_KEY: Missing propertyKey parameter
  • MOD_MISSING_OPERATION: Missing operation parameter
  • MOD_MISSING_VALUE: Missing value parameter
  • MOD_READY: Modifier ready to apply
  • MOD_APPLIED: Modifier successfully applied
  • MOD_REVERTED: Modifier successfully reverted
  • MOD_UNDEFINED_TARGET: No target object specified
  • MOD_INVALID_CONDITIONS: Conditions not met
  • MOD_MISSING_CONDITION_INSTANCE: Invalid condition instance
  • MOD_MODIFIER_ERROR: General modifier error

Advanced Features

Base Property Operations

Use different properties for calculation and application:

let character = {
    currentHealth: 50,
    baseHealth: 100,
    maxHealth: 120
};

// Calculate from baseHealth but apply to currentHealth
let healing = new Modifier({
    key: 'healing-spell',
    propertyKey: 'currentHealth',
    basePropertyKey: 'baseHealth',
    operation: ModifierConst.OPS.INC_P,
    value: 30 // 30% of baseHealth
});

// Use baseHealth for calculation, apply to currentHealth
healing.apply(character, true, false);
console.log(character.currentHealth); // 80 (50 + 30% of 100)

Custom Method Operations

class CustomModifier extends Modifier
{
    customCalculation(modifier, currentValue)
    {
        // Custom logic here
        return Math.floor(currentValue * 1.5) + 10;
    }
}

let customMod = new CustomModifier({
    key: 'custom-boost',
    propertyKey: 'attack',
    operation: ModifierConst.OPS.METHOD,
    value: 'customCalculation'
});

Error Handling

The package includes comprehensive error handling and state management:

let invalidModifier = new Modifier({
    // Missing required parameters
    key: 'invalid'
});

console.log(invalidModifier.state); // Will show error state code

Need something specific?

Request a feature here: https://www.reldens.com/features-request

Documentation

https://www.reldens.com/documentation/modifiers


Reldens

By DwDeveloper