Skip to content

Ranged Combat Audio and VFX Feel Pass #140

Description

@PJensen

Ranged Combat Audio and VFX Feel Pass

Goal

Make ranged combat sound and feel more legible by grounding projectile behavior in simple physical intuition.

The immediate issue is that shooting an arrow is far too quiet compared with other combat sounds. Fix that first.

The broader improvement is to make bows, ammunition, and elemental shots feel more distinct through audio, projectile travel timing, pitch, impact feel, and lightweight VFX.

Use this as the guiding model:

kinetic energy = 1/2 * mass * velocity^2

Faster traveling mass hits harder. Heavier projectiles hit harder. Velocity matters more sharply than mass because it is squared.

This should remain a focused ranged-combat feel pass, not a combat rewrite.

Core Defect

Arrow shot audio is too quiet.

Investigate the existing ranged-shot audio path and determine whether the quietness comes from:

  • The source asset itself.
  • Normalization.
  • Runtime gain.
  • Audio mix settings.
  • Distance attenuation.
  • Shared combat audio routing.
  • The sound being technically normalized but perceptually weak.

If the shot is already normalized but still feels quiet, boost it artificially at playback or mix level.

Target outcome: firing an arrow should be clearly audible beside melee, damage, spell, and impact sounds during ordinary combat.

Physical Model

Ranged combat should move toward a simple mass/velocity model.

Bow type primarily contributes launch velocity.

Ammunition type primarily contributes projectile mass and may also modify velocity through shape, quality, or special behavior.

Elemental or special shots may modify mass, velocity, or both if doing so improves readability and feel.

Impact force, sound weight, VFX intensity, and pitch should derive from these values where practical.

The model does not need full simulation accuracy. It only needs to produce more coherent feel:

faster projectile = higher pitch, sharper travel, harder hit
heavier projectile = lower pitch, heavier sound, stronger impact
faster + heavier = severe impact
slower + heavier = chunky, weighty, readable
faster + lighter = sharp, quick, precise
slower + lighter = weak or strange

Damage and Kinetic Energy

Avoid using damage as the primary proxy for projectile speed.

Instead, derive or approximate impact contribution from mass and velocity:

const kineticEnergy = 0.5 * projectileMass * projectileSpeed * projectileSpeed;

If the game already has weapon damage values, do not delete them. Treat kinetic energy as a ranged-combat feel input first, and as a possible damage contributor only if the existing combat model supports that cleanly.

A safe first pass is:

existing damage remains authoritative for combat outcome
mass and velocity drive projectile timing, pitch, launch sound, trail feel, and impact VFX/audio weight

Only change actual damage calculation if the current ranged damage model already has a clear place for projectile physics.

Design Direction

Ranged weapons should not all feel like the same shot with different visuals.

A bow should contribute launch velocity and audio character.

Ammunition should contribute projectile mass, and may also contribute velocity adjustment.

Ammunition should no longer be the only meaningful velocity contributor.

Elemental or special shots may modify mass, velocity, or impact treatment if doing so improves readability.

Preserve the current short bow timing as the anchor. Treat the current ranged projectile timing as approximately the short bow baseline unless the existing code clearly proves otherwise.

Required Changes

1. Fix ranged-shot loudness

Bring the basic arrow shot up to combat-audio parity.

Do not chase perfect waveform equality. Tune for perceived loudness in normal play.

A reasonable first-pass result is that the shot is clearly audible without overwhelming hits, deaths, or spells.

2. Add bow baseline velocity

Add bow-level contribution to projectile velocity or travel time.

Use the timing convention already present in the codebase.

If the code is velocity based, use a shape like:

projectileSpeed = baseProjectileSpeed
  * bowVelocityMultiplier
  * ammoVelocityMultiplier
  * shotVelocityMultiplier;

If the code is travel-time based, derive travel time from speed:

travelTime = distance / projectileSpeed;

If the current implementation uses abstract travel multipliers, keep the existing style but name and tune them as velocity effects where possible.

Keep the short bow close to current behavior.

3. Add projectile mass

Add or infer projectile mass for ammunition or projectile type.

A simple normalized mass model is enough:

standard arrow = 1.00
light arrow = 0.75
heavy arrow = 1.35
bodkin = 1.10
broadhead = 1.25
fire arrow = 1.15
ice arrow = 1.30
shock arrow = 0.90
poison arrow = 1.05

Names and values are illustrative. Match existing item names.

4. Keep ammunition timing modifiers

Do not remove existing ammunition influence.

Instead, move toward this model:

final projectile speed = bow launch velocity * ammunition velocity modifier * optional shot modifier
projectile mass = ammunition/projectile mass * optional shot mass modifier
impact energy = 1/2 * mass * speed^2

The exact math should follow the existing implementation style.

5. Make bows sound different

Different bow types should have distinct audio feel.

Use the smallest viable mechanism already supported by the audio path:

  • Different sound variant.
  • Different gain.
  • Different playback rate or pitch.
  • Different layered release/body sound if layering already exists.

Do not introduce a new audio engine.

Suggested tuning direction:

short bow: baseline velocity, light/familiar release
long bow: higher velocity, cleaner snap, slightly higher tension
heavy bow: lower-to-medium velocity but higher projectile mass support, louder body, lower release
war bow: high velocity and high energy, loudest release, severe impact

6. Tie pitch to velocity and mass

Where supported, projectile physics should influence shot pitch.

Velocity should push pitch upward.

Mass should push pitch downward.

Keep the effect subtle.

Example shape:

function pitchFromProjectile(speedRatio, massRatio) {
  const velocityLift = speedRatio * 0.15;
  const massDrop = (massRatio - 1) * 0.10;
  return clamp(0.85 + velocityLift - massDrop, 0.80, 1.20);
}

This is a readability cue, not a cartoon pitch effect.

7. Use kinetic energy for impact feel

Use kinetic energy or a normalized energy ratio to tune impact audio and VFX.

Example:

const kineticEnergy = 0.5 * mass * speed * speed;
const energyRatio = kineticEnergy / baselineShortBowEnergy;

Use energyRatio for presentation tuning:

higher energy = louder impact, stronger hit cue, brighter/longer burst if appropriate
lower energy = smaller impact, lighter sound, shorter cue

Avoid letting high-energy VFX become noisy. Ranged combat should become clearer, not busier.

8. Consider elemental mass/velocity traits

Elemental shots should have physical-feeling tradeoffs.

Suggested first-pass direction:

plain: baseline mass and velocity
fire: slightly heavier or slower, fuller impact
ice: heavier and slower, chunky impact
shock: lighter and faster, sharper/higher pitch
poison: slightly heavier or draggy, softer/weirder impact

Do not force symmetry. Tune by feel.

9. Add lightweight ranged VFX support

Only add VFX changes that directly improve ranged readability.

Good candidates:

  • Clearer launch cue.
  • More readable projectile trail.
  • Trail length or persistence derived from velocity.
  • Impact intensity derived from kinetic energy.
  • Slightly different trail treatment by ammo or element.
  • Stronger impact cue for heavier/slower shots.
  • Tighter cue for faster/lighter shots.

Do not expand this into a general rendering cleanup.

Implementation Order

  1. Find the current ranged attack flow.
  2. Find projectile timing/speed calculation.
  3. Find ranged-shot audio playback.
  4. Fix arrow loudness first.
  5. Anchor current timing as short bow timing.
  6. Add bow baseline velocity contribution.
  7. Add or infer projectile mass from ammunition/projectile type.
  8. Preserve ammunition velocity contribution.
  9. Compute normalized kinetic energy for ranged feel tuning.
  10. Add optional elemental/special-shot mass or velocity contribution only if it fits the existing data path.
  11. Add bow-specific audio tuning.
  12. Add pitch variation from velocity and mass.
  13. Add impact audio/VFX variation from kinetic energy.
  14. Add small ranged VFX readability improvements.
  15. Update or add deterministic tests for changed projectile timing and energy calculation.

Acceptance Criteria

Arrow firing is clearly audible during ordinary combat.

Arrow firing is roughly aligned with other combat sounds by perceived loudness.

If the source sound is already normalized, runtime gain or mix tuning compensates for weak perceived loudness.

Short bow projectile timing remains close to the current baseline.

Bow type contributes baseline projectile velocity or equivalent travel timing.

Ammunition contributes projectile mass.

Ammunition may still modify projectile velocity.

Projectile impact feel derives from normalized kinetic energy where practical.

At least two bow types produce different projectile timing or energy profiles.

At least two ammunition types produce different mass or energy profiles.

Elemental or special shots may modify mass, velocity, or impact feel where supported.

Bow shots differ audibly through sound variant, gain, pitch, playback rate, impact sound, or a combination of these.

Projectile velocity and mass influence pitch where technically supported.

Ranged VFX changes make projectiles easier to read without creating visual noise.

Existing tests pass.

Non-Goals

Do not rewrite ranged combat.

Do not rebalance unrelated weapons.

Do not introduce a new audio engine.

Do not perform a broad rendering or VFX cleanup.

Do not make short bow feel materially different from the current baseline.

Do not force kinetic energy to become final damage unless the existing combat model has a clean place for it.

Final Intent

A new bow or ammunition type should be felt immediately.

The player should hear the shot, sense the velocity and mass of the projectile, and read the impact difference between ordinary, heavy, fast, and elemental ranged attacks. 🏹

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

ENHANCEMENTNew feature or requestGAMEPLAYLooking at the whole picture. The feel.

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions