Damage Indicator

by Dummiez

Shows fancy, reactive floating damage numbers when entities get hit. Easily configurable/mod compatible.

Utilities
10 days ago
2.0
705
Combat Enemies

Changelog

Version: 1.3.1
Date: 15. 05. 2026
  Translations:
    - Added Polish (pl), German (de) and Simplified Chinese (zh-CN) translations.
Version: 1.3.0
Date: 12. 05. 2026
  Features:
    - Added a server-override damage indicator setting, for servers that want consistent damage indicators across all players in-game. Uses '/damage-indicators-override' command to generate a 'server settings' string.
    - Re-added more font options in the Rendered font settings.
  Optimizations:
    - Reworked the connected-group merge sweep to scan state.active in a single downward pass instead of restarting from the top after every successful merge. Repeats only when bounding-box expansion from earlier merges, with the typical case finishing in one pass. Cuts worst-case behavior from O(cluster_size * active_count) to bounded by transitive-closure depth. Most noticeable during heavy combat (biter waves, asteroid groups) where many same-type indicators consolidate at once.
    - Cached per-player single-element viewer lists in get_viewers. Reduces GC pressure at high damage-event rates in single-player and servers.
    - Stable singleton viewer lists also let same_player_list short-circuit via reference equality on consecutive hits from the same viewer, skipping per-text-update element-by-element comparisons.
Version: 1.2.3
Date: 09. 05. 2026
  Bugfixes:
    - Fixed a follow-up data-final-fixes crash where mods that index projectile target_effects by hardcoded position would get a nil index after our marker insertion.
Version: 1.2.2
Date: 09. 05. 2026
  Bugfixes:
    - Fixed a data-final-fixes issue for mods that adjust `.action.action_delivery` on projectile prototypes, now preserves the original action shape.
Version: 1.2.1
Date: 08. 05. 2026
  Features:
    - Added dynamic grouping of damage indicators for dense-heavy similar entities. Also supports naming variants (also configurable in settings).
    - Added debugging display indicator option in per-player runtime for testing purposes.
  Bugfixes:
    - Fixed instances where enemies would display killing-blow indicators while still alive, and would end up creating multiple instances of damage indicators (now has a slight delay check).
Version: 1.2.0
Date: 06. 05. 2026
  Features:
    - Moved color settings to per-player runtime: Color mode, Blend combined damage colors, Damage color intensity, Color intensity cap, and the eight per-damage-type colors (physical, impact, explosion, fire, laser, electric, acid, poison). Each player can now pick their own color scheme, intensity behavior, and ramp cap.
    - Moved text-formatting settings to per-player runtime: Compact damage numbers, Number separator, Show reduced damage, Show grouped label count, Text template, and Killing blow marker. Each player can now choose their own display preferences without changing global startup settings.
    - Moved visual and animation settings to per-player runtime: Animation lifetime, Animation speed, Drift distance, Drift style, Shadow style, Enable alt mode toggle, and Mark killing blow. Each player can now tune their own pop / drift / shadow style without affecting others.
    - Added projectile-aware drift origin so AoE damage from projectiles (rockets, artillery, grenades) drifts away from the actual impact point rather than the player or turret that fired the shot.
    - Added 'Show Alt Mode toggle' setting to enable quick show/hide of display indicators (disabled by default).
  Changes:
    - Indicator text format is now baked at creation from the closest viewer's preferences and stays stable across the indicator's life, so the display doesn't shift if the closest player changes mid-fight.
    - Low-damage text is now slightly larger (~20% lift at the floor) while keeping the same maximum size for sustained or large hits.
    - Adjusted some startup value settings for optimizations. You may need to reset settings in order to see new changes.
    - Adjusted animations for damage indicators (improved fade out easing transitions, delays for easier visibility).
    - Optimizations for display indicator grouping (cleared out unused variables, improved caching).
    - Visual settings are baked at indicator creation from the closest viewer's preferences and stay locked for the indicator's life. New indicators reflect changes immediately; in-flight indicators keep their original look until they fade.
    - Killing-blow detection still happens universally (so grouping and recent-indicator decisions stay consistent), but the closest viewer's "Mark killing blow" toggle decides whether the marker, color lock, and emphasis pulse are applied.
    - Color settings are baked at indicator creation from the closest viewer's preferences and stay locked for the indicator's life. The blend accumulators (color_blend_total/r/g/b) keep using a stable settings reference so combined damage indicators don't drift in hue when the closest player or their preferences change mid-fight.
    - Remote API get_damage_type_color() now resolves type colors against vanilla defaults when called without a player context. Mod-registered custom_damage_colors still take priority and are unchanged.
  Scripting:
    - Settings cache split: STARTUP keeps truly-global values, per-player text settings live in viewer_utils' player cache and invalidate on settings change / player leave.
    - Added scripts/aoe_origins.lua and a data-final-fixes patch that inserts script trigger markers into projectile prototypes to recover AoE impact positions at runtime.
    - AoE origin cache is stored in the save and synchronized across multiplayer peers; per-surface entries are pruned after 4 ticks and capped at 64 entries.
    - data-final-fixes patcher is fully idempotent and shallow-copies action sequences before inserting markers, so repeated invocations or shared prototype references from other mods are not mutated.
    - Removed conditional script.on_event(defines.events.on_tick, ...) registration. The on_tick callback now performs an early-return when there are no active indicators, no pending external damage reductions, and no tracked fight history.
    - update_tick_handler is retained as a no-op stub so existing init wiring in damage_tracking and indicator_renderer continues to work without changes.
    - get_viewers now returns the closest viewer's text settings and player index alongside the viewer list and highest scale, so per-user preferences resolve cheaply per damage event.
    - get_viewers now returns the closest viewer's visual settings alongside text settings and player index. Visual settings include lifetime, animation_speed, drift_distance, drift_style, shadow_style, resolved shadow_offsets profile reference, alt_mode, and killing_blow_enabled.
    - settings_cache exposes resolve_shadow_profile so per-player caches can resolve the profile once at build time.
    - Threaded color_settings through color_utils: color_for_damage_type, color_for_damage_type_name, adjust_damage_color, and append_damage_color_blend now take an explicit color_settings argument. A nil argument falls back to color_utils.DEFAULT_COLOR_SETTINGS so callers without a player context still work.
    - settings_cache exposes VANILLA_DAMAGE_COLORS, VANILLA_DAMAGE_TYPES, and normalize_setting_color so per-player caches build deterministic color tables.
    - get_viewers now returns a sixth element (closest viewer's color_settings) before player_index. Visual+text+color are all baked onto each indicator at creation alongside the existing visual_settings reference.
  Bugfixes:
    - Fixed a multiplayer join failure ("mod event handlers are not identical") that could occur when the host's saved tick-handler registration state did not match what a joining client resolved during load. The on_tick handler is now registered unconditionally and gates work via an early return, so event registration is stable across save/load and across all peers.
Version: 1.1.0
Date: 03. 05. 2026
  Features:
    - Added whitelist for entity types for group display indicators (replaces original asteroids filter with full customization).
    - Added blacklist for entity names from generating damage indicators with wildcard support for partial matching. 
  Scripting:
    - Refactored control.lua into focused modules for startup settings, color handling, text formatting, viewer filtering, entity helpers, damage tracking, indicator rendering, and grouping.
    - Moved grouped-indicator member tracking, merging, and nearby-group lookup into scripts/grouping.lua.
    - Moved render-object caching, indicator creation, text refreshes, entity detaching, and animation into scripts/indicator_renderer.lua.
    - Moved recent-hit keys, first-damage tracking, and external damage-reduction reports into scripts/damage_tracking.lua.
Version: 1.0.6
Date: 03. 05. 2026
  Features:
    - Added startup color settings for vanilla damage types.
    - Added Number separator startup setting for full damage numbers: None, Commas, or Points.
    - Added grouped damage indicators for nearby 1x1 player-built entities with the same internal name.
    - Added Group similar distance startup setting; set to 0 to disable grouped indicators.
    - Added chain-based grouping so damaged entities can join a group if they are near any existing group member, not just the label center.
    - Added automatic merging for compatible grouped indicators when separate groups later connect.
    - Added grouped entity count text, such as [3x Wall], using a smaller rich-text font.
    - Added Show grouped label count startup toggle, enabled by default.
    - Added asteroid grouping support for identical asteroid entity names.
    - Added optional damage-weighted color blending for combined damage indicators.
  Bugfixes:
    - Fixed blended indicator colors only becoming visible during fade-out; color changes now update during active attacks.
    - Fixed grouped labels staying separate after nearby chains connected by merging compatible active groups.
    - Improved cleanup for grouped indicators with multiple recent entity keys.
    - Removed duplicate value in the rounding-threshold setting's allowed values list.
    - Reset the per-tick viewport cache on save load so stale entries can't carry across sessions.
  Optimizations:
    - Reduced render-object clutter by collapsing nearby repeated 1x1 building and asteroid damage into shared labels.
    - Added group bounding-box checks before scanning member positions during chain matching and group merging.
    - Kept color/render updates cached while allowing RGB changes to push immediately when blended colors change.
    - Skipped registering the on_player_changed_position handler entirely when viewport culling is disabled.
    - Eliminated redundant text-format work in batched flushes when there is no damage reduction.
    - Avoided recomputing one-tile groupable status twice per damage event for new indicators.
    - Removed a small per-indicator allocation by inlining the spawn-offset randomization.
    - Added a fast path in viewer-set unioning for the common single-player case.
  Changes:
    - Replaced the rounding-threshold startup setting with a Compact damage numbers toggle.
    - Capped stored group positions to the 100 most recent positions while keeping the displayed group count unlimited.
    - Killing-blow indicators now scale text size based on how long the entity took damage. Tracking is per-entity-key so it spans across short fade gaps between indicators.
    - Grouped indicators now average their display position across all grouped entity positions.
    - Combined indicators now preserve first-hit color by default, or use blended color when the new blend setting is enabled.
    - Grouped indicator matching now uses member-position chains for better clustering across wall lines, dense 1x1 building groups, and asteroid fields.
    - Hardened the external-damage-reduction remote interface against out-of-range tick values from buggy callers.
    - Restricted /damage-indicators-clear to admins on multiplayer (single-player host is always admin).
    - clear_indicators now also clears pending external damage-reduction reports.
Version: 1.0.5
Date: 03. 05. 2026
  Features:
    - Added modded damage color table, Modcalls still have priority.
  Optimizations:
    - Disabled the on_tick handler while there are no active indicators or pending external damage-reduction reports.
    - Reduced small color-table allocations in damage-ramp and damage-intensity color calculations.
    - Expanded the render font startup setting with additional built-in Factorio font types.
Version: 1.0.4
Date: 03. 05. 2026
  Bugfixes:
    - Fully isolated killing-blow indicators. Once an indicator has the killing-blow marker, it is detached from the recent-hit map immediately, so any follow-up damage events on the same entity (which can happen if a damage-reduction mod such as Stable Foundations restores health after our event fires, or if the engine queues additional same-tick hits after final_health hits zero) spawn a new indicator instead of mutating the existing one. Fixes the visual bug where a killing-blow number could shift color during fade-out.
    - Note: when a damage-reduction mod prevents a kill that we already detected via final_health<=0, the original indicator keeps its "!" and locked color through fade-out, and a new indicator appears for the follow-up hit. If you find the occasional false "!" misleading in those cases, the Mark killing blow startup setting can be disabled.
Version: 1.0.3
Date: 01. 05. 2026
  Bugfixes:
    - Locked the indicator color once the killing blow has landed, so subsequent same-tick post-kill damage events and corpse/position-key collisions no longer cause the color to drift during fade-out.
  Changes:
    - Tuned drift easing back to ease-out quad for a smoother, less floaty motion than 1.0.2's ease-out cubic. Movement still starts slightly earlier (0.13 progress) than 1.0.0's 0.18, so the indicator doesn't sit perfectly still after spawning. The "poppy" feel is carried by the pop scale curve, which keeps its 1.85x overshoot from 1.0.2.
    - Net effect: the per-tick render writes triggered by drift are reduced relative to 1.0.2, recovering most of the perf cost while keeping the punchy entrance.
Version: 1.0.2
Date: 01. 05. 2026
  Features:
    - Added killing blow marker: the damage number that finishes off an entity is suffixed with "!" by default and gets an emphasis pulse so it pops out from the rest of the hits.
    - Added Mark killing blow startup toggle.
    - Added Killing blow marker startup string setting (default "!"); leave blank to keep the emphasis pulse without the suffix.
  Changes:
    - Punchier pop animation: bigger overshoot on spawn (peak ~1.85x), with a small bounce-back undershoot before settling, for a more impactful entrance.
    - More fluid drift: motion now starts sooner in the indicator's life and uses ease-out cubic instead of ease-out quad, giving stronger initial momentum that settles smoothly toward the end.
Version: 1.0.1
Date: 01. 05. 2026
  Optimizations:
    - Cached startup settings on script load to eliminate repeated settings table lookups in hot paths (animate, damage event, viewport check).
    - Cached per-player runtime settings; invalidated on settings-changed and player-leave events.
    - Cached LuaRenderObject references in a runtime-only table keyed by render id, eliminating get_object_by_id lookups every tick while preserving save/load safety via stored ids.
    - Cached per-tick player viewport bounds; precomputed half-width/half-height to avoid repeated divisions.
    - Skipped render-side scale/alpha/target writes when values are unchanged from the previous tick.
    - Reused color and target buffer tables across animation updates to cut per-tick allocations.
    - Replaced O(n) table.remove calls in on_tick and trim with compact-in-place pattern.
    - Throttled external damage reduction expiration scan to every 60 ticks instead of every tick.
    - Added fast path for default text template ("__damage__") to avoid gsub/concat work.
    - Removed redundant bring_to_front on text refresh.
    - Switched unit_number damage keys to numeric keys to avoid per-event string allocation.
    - Localized math/string functions for hot-path performance.
  Bugfixes:
    - Avoided reassigning render players list on every text refresh when viewer set is unchanged.
  Changes:
    - Restored damage indicators for trees and simple entities; player radius and viewport culling remain the performance gate.
    - Brightened the high end of damage-ramp mode so large values remain readable.
Version: 1.0.0
Date: 01. 05. 2026
  Features:
    - Added animated floating damage indicators with punch pop, drift, batching, and fade.
    - Added continuous-damage aggregation with configurable new-popup delay and text update interval.
    - Added entity-following indicators for moving targets, including last-position fallback on death or removal.
    - Added shooter-aware, upward, and mixed drift modes.
    - Added stacked shadow styles: Off, Light, and Heavy.
    - Added custom startup font family/size, rendered font selection, rich text, and text template support.
    - Added per-player display controls for visibility, radius, minimum damage, and scale.
    - Added startup controls for lifetime, animation speed, active indicator cap, rounding threshold, and viewport culling.
    - Added damage-type color mode with tuned physical, impact, explosion, fire, laser, electric, acid, and poison colors.
    - Added damage-ramp color mode from light yellow to dark red based on damage amount.
    - Added optional damage color intensity scaling, capped by default at 2k damage.
    - Added deterministic generated colors for unknown modded damage types.
    - Added a remote interface for mods to register damage type colors.
    - Added externally reported damage reduction support for displays such as 50 (-50).
    - Added optional Stable Foundations integration for reduced-damage reporting.
    - Added /damage-indicators-clear command.
  Optimizations:
    - Batched per-tick damage text updates to reduce render text rewrites.
    - Added viewport culling to skip indicators outside eligible players' estimated screen view.
    - Added configurable active indicator cap with oldest-indicator trimming.
    - Combined repeated damage on the same entity to reduce popup clutter.
  Changes:
    - Moved shared behavior settings to Startup settings so they persist as defaults for new worlds.
    - Reordered settings alphabetically by English locale label.
    - Enabled rich text by default so reduced damage can render in white.
    - Changed compact/rounded display to start at 10k by default.
    - Hide decimals once damage reaches double digits.
    - Retuned damage type colors to better match source visuals and separate poison from electric/acid.
  Bugfixes:
    - Prevented combined indicators from restarting the pop animation during continuous damage.
    - Reset drift positioning whenever a batched damage number refreshes.
    - Kept existing combined indicators refreshing even when follow-up hits are below the minimum damage threshold.
    - Flushed pending batched damage when an entity dies or is removed before the next text update interval.
    - Detached active indicators from removed entities so they finish fading at their last known position.