Jump to content

Enhanced Delay

From OpenBOR
(Redirected from Edelay)

Enhanced Delay - edelay in legacy engine builds, is a model- and entity-level transform for animation timing. It can scale, offset, filter, and cap the delay of each indexed animation member without requiring creators to rewrite the member's own delay value.

Enhanced Delay does not create a second timer. When an entity enters an actively animating position, OpenBOR reads that member's stored delay, applies the model or entity's Enhanced Delay configuration, and uses the result to schedule the next position.

This makes the feature useful for broad timing changes such as:

  • Fast and slow character variants using the same animation data.
  • Haste, slow, weight, transformation, or equipment effects applied to an individual entity.
  • Global animation-pacing adjustments for a model.
  • Protecting short, deliberately timed animation members while scaling longer ones.
  • Enforcing a minimum or maximum duration after scaling.
  • Combining proportional timing changes with a fixed adjustment.

Commands

Enhanced Delay commands expose each part of the calculation independently:

enhanced_delay_multiplier {multiplier}
enhanced_delay_modifier {modifier}
enhanced_delay_cap_min {minimum}
enhanced_delay_cap_max {maximum}
enhanced_delay_range_min {minimum}
enhanced_delay_range_max {maximum}

All six commands belong in a model definition. They may be supplied in any order because each command writes one configuration value.

Command Type Default Purpose
enhanced_delay_multiplier Decimal or percentage 1.0 Multiplies an eligible original delay. Values such as 0.8 and 80% are equivalent.
enhanced_delay_modifier Signed integer 0 Adds a fixed number of logical clock ticks after multiplication.
enhanced_delay_cap_min Signed integer 0 Lowest calculated result permitted before final finite-delay bounds are applied.
enhanced_delay_cap_max Signed integer 2147483647 Highest calculated result permitted before final finite-delay bounds are applied.
enhanced_delay_range_min Signed integer 0 Lowest original delay eligible for adjustment. Values of zero or less impose no lower exclusion.
enhanced_delay_range_max Signed integer 2147483647 Highest original delay eligible for adjustment. Negative values disable Enhanced Delay processing.

Default values leave ordinary delays unchanged. The default cap and range maximum use the signed integer maximum, 2147483647. OpenBOR's finite animation-delay representation extends to 4294967295, so an original value above the default range maximum bypasses Enhanced Delay and remains unchanged.

Basic Example

This configuration reduces eligible animation delays to 80 percent of their original duration:

enhanced_delay_multiplier 80%

This configuration combines scaling with a fixed addition and protects the result with minimum and maximum caps:

enhanced_delay_multiplier 0.75
enhanced_delay_modifier 2
enhanced_delay_cap_min 4
enhanced_delay_cap_max 20

Calculation Order

OpenBOR processes an animation member's delay in this order:

  1. The member's declared delay is converted to logical clock ticks when the animation data is loaded.
  2. The entity enters an actively animating position.
  3. OpenBOR compares the original logical-tick delay with the Enhanced Delay eligibility range.
  4. An in-range value is multiplied by enhanced_delay_multiplier.
  5. enhanced_delay_modifier is added to the product.
  6. enhanced_delay_cap_min is applied.
  7. enhanced_delay_cap_max is applied.
  8. Fractional remainder is discarded and the result is limited to the finite delay range.
  9. OpenBOR converts the resulting relative delay into the absolute time for the next animation position.

The central formula is:

calculated_delay = original_delay * multiplier + modifier

Caps then constrain calculated_delay. The eligibility range is not part of the formula and does not clamp the original value. An out-of-range original delay bypasses the complete calculation and is returned unchanged.

Worked Example

Consider this configuration:

enhanced_delay_multiplier 0.75
enhanced_delay_modifier 2
enhanced_delay_cap_min 4
enhanced_delay_cap_max 20
enhanced_delay_range_min 6
enhanced_delay_range_max 30
Original delay Processing Final delay
5 Below the eligibility range - no calculation. 5
6 6 * 0.75 + 2 = 6.5, then fractional remainder is discarded. 6
20 20 * 0.75 + 2 = 17. 17
30 30 * 0.75 + 2 = 24.5, then maximum cap applies. 20
31 Above the eligibility range - no calculation. 31

Eligibility Range

Range tests use the original converted delay, before multiplication, addition, or caps.

  • Both positive boundaries are inclusive. Values equal to range_min or range_max are eligible.
  • range_min only excludes lower values when it is greater than zero. Zero or a negative value means there is no effective lower threshold.
  • Negative range_max values disable Enhanced Delay entirely. They do not mean "no upper limit."
  • Use 4294967295 as the maximum when every possible finite animation delay should be eligible.

The range knows only the stored duration. It does not know the animation name, member position, attack state, collision content, or creator intent. Projects can preserve short attack-active positions by assigning them short delays and placing the range minimum above those values, though Enhanced Delay is selecting by duration rather than by gameplay role.

Scale Only Longer Delays

This example leaves original values below 6 logical ticks unchanged and halves values from 6 through 30:

enhanced_delay_multiplier 0.5
enhanced_delay_range_min 6
enhanced_delay_range_max 30

Original delays above 30 are also unchanged. This can be useful when a project's short active positions and long recovery or idle positions already occupy distinct duration ranges.

Caps

Caps apply only after an eligible delay has been multiplied and modified.

  • cap_min raises a calculated value below the minimum.
  • cap_max lowers a calculated value above the maximum.
  • Keep cap_min less than or equal to cap_max for predictable configuration.
  • Final finite values cannot be below 0 or above 4294967295, regardless of configured caps.
  • Negative calculated results become 0 after cap processing unless a positive minimum cap raises them first.
  • Results at or above 4294967295 become 4294967295.

Fractional results are truncated toward zero after caps. Enhanced Delay does not retain sub-tick timing. For example, 9 * 0.75 = 6.75 becomes 6 when no cap changes it.

Units

The animation member's own delay command supports declared units such as global, centisecond, millisecond, second, minute, and direct. OpenBOR converts that value to logical clock ticks while loading the animation.

Enhanced Delay runs after this conversion:

  • Multiplier is dimensionless.
  • Modifier is a count of logical clock ticks.
  • Both caps are logical-tick values.
  • Both eligibility boundaries are logical-tick values.

This distinction matters when a model uses time-based delay input. For example, with a game speed of 200 logical ticks per second, delay 10 centisecond is stored as 20 logical ticks. Enhanced Delay range values of 10 through 20 include that member because the comparison sees 20, not the source token 10. Modifier value 2 adds two logical ticks, not two centiseconds.

Projects using direct delay input already supply logical ticks, so the source and Enhanced Delay numbers share the same scale.

Runtime Timing

Enhanced Delay is evaluated when OpenBOR schedules the duration of an actively animating position. The relevant order is:

  1. OpenBOR assigns the new indexed animation position.
  2. Enhanced Delay calculates the relative duration.
  3. OpenBOR stores the absolute next-animation timestamp.
  4. Animationscript executes for the entered position.
  5. Later logical updates advance the animation when the stored timestamp is due.

Changing Enhanced Delay settings does not ordinarily rewrite an absolute timestamp that was already scheduled for the current position. Changes made by Animationscript are therefore normally too late to alter the duration of the position that invoked it, though they affect later position entries. If script immediately enters another animation or indexed position, that new entry follows the normal scheduling path and uses the current configuration.

Paused, frozen, or otherwise deferred time may affect when the stored timestamp is reached, but Enhanced Delay itself is not a per-tick callback. Its calculation runs when the relevant animation position is scheduled.

Per-Entity Script Control

Each entity carries a model-data copy used by the calculation. Modern property functions expose every Enhanced Delay field, allowing script to apply timing changes to one entity without editing its animation definitions.

void set_entity_animation_multiplier(void entity, void multiplier)
{
    void model_data = get_entity_property(
        entity,
        ENTITY_PROPERTY_MODEL_DATA
    );

    set_model_property(
        model_data,
        MODEL_PROPERTY_ENHANCED_DELAY_MULTIPLIER,
        multiplier
    );
}

Calling this helper with 0.75 accelerates eligible future position durations for that entity, 1.5 slows them, and 1.0 restores the neutral multiplier. The existing modifier, caps, and range continue to participate.

Corresponding model-property constants are:

  • MODEL_PROPERTY_ENHANCED_DELAY_MULTIPLIER
  • MODEL_PROPERTY_ENHANCED_DELAY_MODIFIER
  • MODEL_PROPERTY_ENHANCED_DELAY_CAP_MIN
  • MODEL_PROPERTY_ENHANCED_DELAY_CAP_MAX
  • MODEL_PROPERTY_ENHANCED_DELAY_RANGE_MIN
  • MODEL_PROPERTY_ENHANCED_DELAY_RANGE_MAX

Use ENTITY_PROPERTY_MODEL_DATA when the adjustment should belong to the current entity copy. Mutating the shared cached model instead may affect other entities or later spawns according to which model object was changed.

Remember that changing a property does not ordinarily reschedule the current position's existing timestamp. Apply a temporary status before entering the positions it should affect, or explicitly enter the desired animation state after updating the configuration.

Infinite Delays

OpenBOR encodes infinite animation delay as a behavior flag separate from the finite value bits. Enhanced Delay preserves all behavior flags while operating on the finite portion.

An infinite delay therefore remains infinite regardless of multiplier, modifier, range, or caps. Enhanced Delay cannot convert it into a finite duration. The animation needs an outside state or animation change to leave a position whose delay is infinite.

Practical Patterns

Pattern Configuration idea
Faster model variant Use a multiplier below 1.0 to shorten eligible durations throughout the model.
Slower or heavier variant Use a multiplier above 1.0, with a maximum cap to prevent unusually long members from growing without bound.
Haste or slow status Change the multiplier on the entity's model-data copy, then restore 1.0 when the status ends.
Fixed startup tax Use a positive modifier to add the same logical-tick amount to every eligible duration.
Recovery reduction Use a negative modifier or multiplier below 1.0, with a minimum cap to keep eligible members from collapsing to zero.
Preserve short active positions Put the range minimum above the deliberately short values, provided duration reliably identifies those positions in the project's animation design.
Timing normalization Use minimum and maximum caps to keep transformed results inside a desired band.
Combined curve Use both multiplier and modifier to provide proportional scaling plus a fixed offset.

Common Mistakes

  • Treating Enhanced Delay values as centiseconds or milliseconds instead of logical ticks.
  • Expecting the eligibility range to clamp results rather than filter original delays.
  • Testing range boundaries against the calculated result instead of the original stored delay.
  • Assuming range boundaries are exclusive.
  • Using a negative range_max to mean unlimited when it actually disables Enhanced Delay.
  • Forgetting that the default cap and range maximum are 2147483647, below the full finite-delay maximum.
  • Expecting fractional logical ticks to survive the calculation.
  • Configuring cap_min above cap_max.
  • Omitting arguments from the legacy edelay line.
  • Assuming legacy mode is stored and selects a different runtime formula.
  • Mixing legacy and modern commands without accounting for source-order overwrites.
  • Changing the configuration after the current position's timestamp is already scheduled and expecting retroactive timing.
  • Expecting Enhanced Delay to make an infinite delay finite.
  • Assuming the range identifies animation purpose rather than only original duration.
Feature Scope Role
delay One indexed animation member. Supplies that member's original duration and input unit.
Enhanced Delay / edelay Model or individual entity model-data copy. Transforms eligible original durations when animation positions are scheduled.
Animationscript One entity entering an indexed animation position. Executes creator code after the position's normal next-animation timestamp has been scheduled.
Updateentityscript One entity during each eligible logical update. Can manage dynamic timing state before later animation processing in the same logical tick.

See Also