← Devblog

Base class for Hyena animal

Hyena animation

Added a base class for hyenas as part of restoring the animal AI system from the original Pharaoh. This initial implementation (January 7, 2025) laid the groundwork for complex pack hunting behavior that would be added later.

Architecture Refactoring

The hyena implementation began by extracting 137 lines of hyena-specific code from the monolithic figure_animal.cpp into a dedicated figure_hyena class. This followed the same pattern as other figure refactorings — moving from global functions to object-oriented classes.

The refactoring removed the old figure::hyena_action() method and figure_combat_get_target_for_hyena() global function, replacing them with class-based implementations. The new figure_hyena.h header defined a 16-line class interface with four key methods:

Animation System

Hyenas use four animation sets defined in figures.js:

figure figure_hyena = {
    animations : {
        walk : { pack:PACK_SPR_MAIN, id:161, max_frames:12 },
        death : { pack:PACK_SPR_MAIN, id:162, max_frames:8, duration:3, loop:false },
        eating : { pack:PACK_SPR_MAIN, id:163, max_frames:7 },
        idle : { pack:PACK_SPR_MAIN, id:164, max_frames:8 },
    },
    terrain_usage : TERRAIN_USAGE_ANIMAL,
}

The update_animation() method selects sprites based on action state: corpse (death animation), attacking (eating animation), resting (idle animation), or moving (walk animation). Each animation is directional — 8 directions × frame count.

Basic AI States

The initial implementation supported three action states:

The formation system positions hyenas using formation_layout_position_x/y(FORMATION_HERD, index), allowing multiple hyenas to move as a coordinated group. Each hyena has an index_in_formation that determines its offset from the formation center.

Target Selection

The figure_combat_get_target_for_hyena() function scans all figures on the map, filtering out:

Distance is calculated using calc_maximum_distance(), and figures already targeted by another hyena have their distance doubled to encourage spreading attacks across multiple targets. This prevents all hyenas from converging on a single victim.

Hyena Strength Grid (January 10, 2026)

A year later, the system was enhanced with a spatial grid tracking hyena presence. The new src/grid/hyena_strength.cpp (94 lines) maintains a map-wide grid where each tile stores the number of nearby hyenas. This enables:

The grid updates every frame as hyenas move, incrementing/decrementing tile values. The city figures system tracks total hyena count via city_figures.hyenas, exposed to JavaScript for mission scripting.

Hunting Behavior (January 11, 2026)

The most significant enhancement came with the hunting system. The file was renamed from figure_hyena.cpp to animal_hyena.cpp and expanded from 137 to 325 lines. Key additions:

The pack feeding system uses formation membership to identify nearby hyenas. When a kill occurs, the successful hunter broadcasts to other hyenas in the formation, and they pathfind to the carrion location. This creates realistic pack behavior where multiple hyenas converge on a single kill.

Gameplay Integration

A new gameplay flag gameplay_hyenas_block allows missions to enable/disable hyena spawning. The Saqqara mission (mission 10) uses this to add hyenas as environmental hazards. The city animals system tracks hyena population via city_animals.hyenas, which can be queried from mission scripts.

Technical Details

Hyenas inherit from figure_impl and use the standard figure action system. Movement uses move_ticks(2) for speed control — hyenas move at 2 tiles per tick, making them faster than most citizens but slower than cavalry. Pathfinding uses the standard route_remove() and direction system, with special handling for DIR_FIGURE_REROUTE when paths become blocked.

Result

The hyena system demonstrates the engine's capability for complex animal AI. What started as a basic class extraction evolved into a sophisticated pack hunting system with spatial awareness, coordinated behavior, and realistic feeding mechanics. The implementation serves as a template for other predator animals that may be added in the future.

← Previous: Sprite tool added Next: The Story of original Pharaoh game →