hammer-dependency-analyzer

Verify dependency structure and architecture health for SDL3 HammerEngine. Detects circular dependencies, excessive coupling, layer violations, header bloat, and provides dependency graph visualization. Ensures adherence to layered architecture (Core→Managers→States→Entities). Use monthly, after major refactors, or when investigating compile time issues.

allowed_tools: Bash, Read, Write, Grep, Glob

$ 설치

git clone https://github.com/Ronin15/SDL3_HammerEngine_Template /tmp/SDL3_HammerEngine_Template && cp -r /tmp/SDL3_HammerEngine_Template/.claude/skills/hammer-dependency-analyzer ~/.claude/skills/SDL3_HammerEngine_Template

// tip: Run this command in your terminal to install the skill


name: hammer-dependency-analyzer description: Verify dependency structure and architecture health for SDL3 HammerEngine. Detects circular dependencies, excessive coupling, layer violations, header bloat, and provides dependency graph visualization. Ensures adherence to layered architecture (Core→Managers→States→Entities). Use monthly, after major refactors, or when investigating compile time issues. allowed-tools: [Bash, Read, Write, Grep, Glob]

HammerEngine Dependency Analyzer

Comprehensive dependency structure analysis for SDL3 HammerEngine. Verifies architectural integrity, detects circular dependencies, identifies coupling issues, and maintains clean layered design.

Purpose

HammerEngine follows a layered architecture pattern:

Core (ThreadSystem, Logger, GameLoop)
  ↓
Managers (AIManager, CollisionManager, etc.)
  ↓
States (GameState, MenuState, etc.)
  ↓
Entities (Entity classes, Components)
  ↓
Utils (Vector2D, Math helpers)

This Skill ensures:

  1. Circular Dependency Detection - Prevent include cycles that break compilation
  2. Coupling Analysis - Maintain loose coupling between managers
  3. Layer Violation Detection - Enforce one-way dependencies (no upward dependencies)
  4. Header Bloat Identification - Find unnecessary includes slowing compilation
  5. Forward Declaration Opportunities - Reduce compilation dependencies
  6. Dependency Graph Visualization - Understand system relationships
  7. Compile Time Impact Analysis - Estimate compilation cost per component
  8. Architecture Health Scoring - Quantify overall design quality

Architecture Rules (from CLAUDE.md)

Layer Rules

1. Core Layer (src/core/, include/core/)

  • Can depend on: Nothing (foundation layer)
  • Used by: Everything
  • Components: ThreadSystem, Logger, GameLoop, GameEngine

2. Managers Layer (src/managers/, include/managers/)

  • Can depend on: Core, Utils
  • Cannot depend on: States, Entities (except via interfaces)
  • Coupling: Managers should be loosely coupled, communicate via GameEngine
  • Components: AIManager, CollisionManager, PathfinderManager, EventManager, etc.

3. States Layer (src/gameStates/, include/gameStates/)

  • Can depend on: Core, Managers, Utils
  • Cannot depend on: Other States (no cross-state dependencies)
  • Components: GameState, MainMenuState, PlayingState, PauseState, etc.

4. Entities Layer (src/entities/, include/entities/)

  • Can depend on: Core, Utils
  • Should avoid: Direct manager dependencies (use interfaces/callbacks)
  • Components: Entity, Component classes

5. Utils Layer (src/utils/, include/utils/)

  • Can depend on: Nothing (pure utility functions)
  • Used by: Everything
  • Components: Vector2D, Math, JsonReader

Coupling Rules

Important: Game Engine Functional Coupling

Game engines have necessary functional dependencies between managers. The following patterns are CORRECT and expected:

Functional Game System Dependencies (GOOD):

  • AIManager → CollisionManager (AI needs collision queries for obstacle avoidance, LOS)
  • AIManager → PathfinderManager (AI needs pathfinding for navigation)
  • CollisionManager → WorldManager (collision needs world geometry/tile data)
  • Managers → EventManager (event-driven notifications are good architecture)
  • UIManager → FontManager (UI needs fonts to render text)
  • WorldManager → ResourceManager (world needs tile/sprite resources)
  • ResourceFactory → ResourceTemplateManager (factory pattern requires templates)

Manager-to-Manager Rules:

  • ✅ GOOD: Functional dependencies for game systems
  • ✅ GOOD: Event-based communication between managers
  • 🔴 FORBIDDEN: Circular Manager dependencies (breaks compilation)
  • 🔴 FORBIDDEN: Managers depending on States (violates layer boundaries)

What Actually Matters:

  • Circular dependencies: 🔴 ALWAYS BAD (breaks compilation)
  • Layer violations: 🔴 ALWAYS BAD (breaks architecture)
  • Tight coupling: ✅ OFTEN NECESSARY for game systems to work together
  • High reference counts: ✅ EXPECTED when systems interact functionally

State-to-Manager:

  • ✅ GOOD: PlayingState → AIManager (states use managers)
  • 🔴 FORBIDDEN: AIManager → PlayingState (managers don't know about states)

Header Inclusion:

  • ✅ GOOD: Forward declarations in headers, include in .cpp
  • ⚠️ WARNING: Including heavy headers in .hpp (ripple effect)
  • 🔴 FORBIDDEN: Circular includes (breaks compilation)

Analysis Modes

Mode 1: Quick Dependency Check (2-3 minutes)

  • Scan for circular dependencies only
  • Quick validation before commits
  • Use when: Daily development, pre-commit

Mode 2: Coupling Analysis (5-10 minutes)

  • Analyze manager-to-manager coupling
  • Identify high fan-out components
  • Measure coupling strength
  • Use when: Adding new managers, refactoring

Mode 3: Full Architecture Audit (15-20 minutes)

  • Complete dependency graph
  • Layer violation detection
  • Header bloat analysis
  • Forward declaration opportunities
  • Compile time impact estimation
  • Use when: Monthly audits, major refactors, release prep

Mode 4: Specific Component Analysis (3-5 minutes)

  • Analyze single component's dependencies
  • Show what it depends on and what depends on it
  • Use when: Investigating specific coupling issues

Step 1: Gather User Input

Use AskUserQuestion to determine analysis scope:

Question 1: Analysis Mode

  • Header: "Mode"
  • Question: "What type of dependency analysis do you want?"
  • Options:
    • "Quick Circular Check" (2-3 min, daily use)
    • "Coupling Analysis" (5-10 min, manager refactoring)
    • "Full Architecture Audit" (15-20 min, comprehensive)
    • "Specific Component" (3-5 min, targeted analysis)
  • multiSelect: false

Question 2: Scope (if Mode = Specific Component)

  • Header: "Component"
  • Question: "Which component should be analyzed?"
  • Options:
    • "AIManager"
    • "CollisionManager"
    • "PathfinderManager"
    • "EventManager"
    • "Custom (specify)"
  • multiSelect: false
  • Only show if Mode = "Specific Component"

Question 3: Output Format

  • Header: "Format"
  • Question: "Preferred output format?"
  • Options:
    • "Markdown Report" (default, saved to docs/)
    • "ASCII Tree" (console visualization)
    • "Both" (report + console tree)
  • multiSelect: false

Step 2: Scan Include Dependencies

2a. Find All Header Files

echo "=== Scanning Include Dependencies ==="

# Find all headers
INCLUDE_HEADERS=$(find include/ -name "*.hpp" -type f)
SRC_HEADERS=$(find src/ -name "*.hpp" -type f)

ALL_HEADERS=$(echo "$INCLUDE_HEADERS $SRC_HEADERS" | tr ' ' '\n' | sort -u)

HEADER_COUNT=$(echo "$ALL_HEADERS" | wc -l)
echo "Total headers found: $HEADER_COUNT"

2b. Extract Include Directives

OUTPUT_DIR="test_results/dependency_analysis"
mkdir -p "$OUTPUT_DIR"

DEPENDENCY_FILE="$OUTPUT_DIR/dependencies_raw.txt"
> "$DEPENDENCY_FILE"  # Clear file

echo "Extracting #include directives..."

for HEADER in $ALL_HEADERS; do
    # Extract local includes only (not system includes)
    LOCAL_INCLUDES=$(grep '^#include "' "$HEADER" | sed 's/#include "\(.*\)"/\1/' | tr -d '\r')

    if [ ! -z "$LOCAL_INCLUDES" ]; then
        echo "=== $HEADER ===" >> "$DEPENDENCY_FILE"
        echo "$LOCAL_INCLUDES" >> "$DEPENDENCY_FILE"
        echo "" >> "$DEPENDENCY_FILE"
    fi
done

echo "Dependencies extracted to: $DEPENDENCY_FILE"

2c. Build Dependency Graph

Graph Structure (Adjacency List):

# Create adjacency list representation
GRAPH_FILE="$OUTPUT_DIR/dependency_graph.txt"
> "$GRAPH_FILE"

echo "Building dependency graph..."

for HEADER in $ALL_HEADERS; do
    # Get just the filename (without path)
    HEADER_NAME=$(basename "$HEADER")

    # Get all includes from this header
    INCLUDES=$(grep '^#include "' "$HEADER" | sed 's/#include "\(.*\)"/\1/' | xargs -n1 basename 2>/dev/null)

    # Write to graph file: source -> dependencies
    if [ ! -z "$INCLUDES" ]; then
        for INCLUDE in $INCLUDES; do
            echo "$HEADER_NAME -> $INCLUDE" >> "$GRAPH_FILE"
        done
    fi
done

echo "Dependency graph built: $GRAPH_FILE"

Step 3: Analyze Dependencies by Mode

Mode 1: Quick Circular Check

3a. Detect Circular Dependencies (DFS)

echo "=== Circular Dependency Detection ==="

# Create Python script for cycle detection (more reliable than bash)
cat > "$OUTPUT_DIR/detect_cycles.py" <<'PYTHON_SCRIPT'
#!/usr/bin/env python3
import sys
from collections import defaultdict

def read_graph(graph_file):
    """Read dependency graph from file."""
    graph = defaultdict(list)
    with open(graph_file, 'r') as f:
        for line in f:
            if '->' in line:
                source, target = line.strip().split(' -> ')
                graph[source].append(target)
    return graph

def find_cycles_dfs(graph):
    """Find all cycles using DFS with recursion stack."""
    visited = set()
    rec_stack = set()
    cycles = []

    def dfs(node, path):
        visited.add(node)
        rec_stack.add(node)
        path.append(node)

        for neighbor in graph.get(node, []):
            if neighbor not in visited:
                dfs(neighbor, path.copy())
            elif neighbor in rec_stack:
                # Found a cycle
                cycle_start = path.index(neighbor)
                cycle = path[cycle_start:] + [neighbor]
                cycles.append(cycle)

        rec_stack.remove(node)

    for node in graph:
        if node not in visited:
            dfs(node, [])

    return cycles

def main():
    if len(sys.argv) != 2:
        print("Usage: detect_cycles.py <graph_file>")
        sys.exit(1)

    graph_file = sys.argv[1]
    graph = read_graph(graph_file)

    print(f"Analyzing {len(graph)} nodes...")

    cycles = find_cycles_dfs(graph)

    if not cycles:
        print("✅ NO CIRCULAR DEPENDENCIES DETECTED")
        sys.exit(0)
    else:
        print(f"🔴 FOUND {len(cycles)} CIRCULAR DEPENDENCIES:")
        print()
        for i, cycle in enumerate(cycles, 1):
            print(f"Cycle {i}:")
            print("  " + " -> ".join(cycle))
            print()
        sys.exit(1)

if __name__ == '__main__':
    main()
PYTHON_SCRIPT

chmod +x "$OUTPUT_DIR/detect_cycles.py"

# Run cycle detection
python3 "$OUTPUT_DIR/detect_cycles.py" "$GRAPH_FILE"
CYCLE_STATUS=$?

if [ $CYCLE_STATUS -ne 0 ]; then
    echo ""
    echo "🔴 CIRCULAR DEPENDENCIES BLOCK COMPILATION"
    echo "Action: Break cycles using forward declarations or interface extraction"
fi

3b. Suggest Fixes for Circular Dependencies

If cycles detected:

echo ""
echo "=== Circular Dependency Fix Suggestions ==="

# Read cycles from previous output
# For each cycle, suggest:
# 1. Forward declaration approach
# 2. Interface extraction
# 3. Dependency inversion

# Example output:
cat <<EOF
Cycle: AIManager.hpp -> PathfinderManager.hpp -> AIManager.hpp

Suggested Fixes:

1. Forward Declaration (RECOMMENDED):
   In AIManager.hpp:
     Remove: #include "PathfinderManager.hpp"
     Add: class PathfinderManager; // Forward declaration

   In AIManager.cpp:
     Add: #include "PathfinderManager.hpp"

2. Interface Extraction:
   Create IPathfinder.hpp with pure virtual interface
   AIManager depends on IPathfinder (no circular dependency)
   PathfinderManager implements IPathfinder

3. Dependency Inversion:
   Both managers depend on abstract interface
   GameEngine wires concrete implementations
EOF

Mode 2: Coupling Analysis

3a. Calculate Coupling Metrics

Fan-Out (Efferent Coupling):

echo "=== Coupling Analysis ==="

# For each component, count how many others it depends on
echo "Fan-Out (Efferent Coupling - what this component depends on):"
echo ""

while IFS= read -r HEADER; do
    HEADER_NAME=$(basename "$HEADER")
    FAN_OUT=$(grep "^$HEADER_NAME ->" "$GRAPH_FILE" | wc -l)

    if [ "$FAN_OUT" -gt 0 ]; then
        # Classify coupling strength
        if [ "$FAN_OUT" -gt 15 ]; then
            STATUS="🔴 HIGH"
        elif [ "$FAN_OUT" -gt 10 ]; then
            STATUS="⚠️  MEDIUM"
        elif [ "$FAN_OUT" -gt 5 ]; then
            STATUS="🟡 MODERATE"
        else
            STATUS="✅ LOW"
        fi

        echo "  $HEADER_NAME: $FAN_OUT dependencies - $STATUS"
    fi
done <<< "$ALL_HEADERS" | sort -t: -k2 -rn | head -20

echo ""

Fan-In (Afferent Coupling):

echo "Fan-In (Afferent Coupling - what depends on this component):"
echo ""

while IFS= read -r HEADER; do
    HEADER_NAME=$(basename "$HEADER")
    FAN_IN=$(grep " -> $HEADER_NAME$" "$GRAPH_FILE" | wc -l)

    if [ "$FAN_IN" -gt 0 ]; then
        # High fan-in indicates core/stable component
        if [ "$FAN_IN" -gt 20 ]; then
            STATUS="⭐ CORE"
        elif [ "$FAN_IN" -gt 10 ]; then
            STATUS="📦 STABLE"
        elif [ "$FAN_IN" -gt 5 ]; then
            STATUS="🔧 UTILITY"
        else
            STATUS="📄 LEAF"
        fi

        echo "  $HEADER_NAME: $FAN_IN dependents - $STATUS"
    fi
done <<< "$ALL_HEADERS" | sort -t: -k2 -rn | head -20

echo ""

Instability Metric (I = Fan-Out / (Fan-In + Fan-Out)):

echo "Instability Metric (I = Efferent / (Afferent + Efferent)):"
echo "  0.0 = Maximally Stable (hard to change)"
echo "  1.0 = Maximally Unstable (easy to change)"
echo ""

while IFS= read -r HEADER; do
    HEADER_NAME=$(basename "$HEADER")

    FAN_OUT=$(grep "^$HEADER_NAME ->" "$GRAPH_FILE" | wc -l)
    FAN_IN=$(grep " -> $HEADER_NAME$" "$GRAPH_FILE" | wc -l)

    TOTAL=$((FAN_OUT + FAN_IN))

    if [ "$TOTAL" -gt 0 ]; then
        # Calculate instability (using bc for float arithmetic)
        INSTABILITY=$(echo "scale=2; $FAN_OUT / $TOTAL" | bc)

        echo "  $HEADER_NAME: I=$INSTABILITY (out=$FAN_OUT, in=$FAN_IN)"
    fi
done <<< "$ALL_HEADERS" | head -20

3b. Manager-to-Manager Coupling

echo ""
echo "=== Manager-to-Manager Coupling ==="

# Find all manager headers
MANAGERS=$(find include/managers -name "*.hpp" -type f 2>/dev/null)

if [ -z "$MANAGERS" ]; then
    echo "No managers found in include/managers/"
else
    # Build coupling matrix
    echo "Manager Coupling Matrix:"
    echo ""
    printf "%-25s" "Manager"

    # Header row
    for MGR in $MANAGERS; do
        MGR_NAME=$(basename "$MGR" .hpp)
        printf "%-8s" "${MGR_NAME:0:7}"
    done
    echo ""

    # Matrix rows
    for MGR1 in $MANAGERS; do
        MGR1_NAME=$(basename "$MGR1" .hpp)
        printf "%-25s" "$MGR1_NAME"

        for MGR2 in $MANAGERS; do
            MGR2_NAME=$(basename "$MGR2" .hpp)

            # Check if MGR1 includes MGR2
            INCLUDES=$(grep -c "#include \"$MGR2_NAME.hpp\"" "$MGR1" 2>/dev/null || echo "0")

            if [ "$MGR1_NAME" = "$MGR2_NAME" ]; then
                printf "%-8s" "-"
            elif [ "$INCLUDES" -gt 0 ]; then
                printf "%-8s" "✓"
            else
                printf "%-8s" " "
            fi
        done
        echo ""
    done
fi

echo ""
echo "Legend: ✓ = Direct dependency, - = Self, (blank) = No dependency"
echo ""
echo "Note: Manager-to-manager dependencies are EXPECTED in game engines."
echo "Game systems must interact: AI needs collision, world needs events, etc."

3c. Coupling Strength Analysis

echo ""
echo "=== Coupling Strength Analysis ==="

# Define functional game engine dependencies (these are EXPECTED and CORRECT)
# Format: "Manager1->Manager2" (these will NOT be flagged as problems)
FUNCTIONAL_DEPS=(
    "AIManager->CollisionManager"
    "AIManager->PathfinderManager"
    "CollisionManager->WorldManager"
    "CollisionManager->EventManager"
    "WorldManager->EventManager"
    "WorldManager->WorldResourceManager"
    "WorldManager->TextureManager"
    "UIManager->FontManager"
    "UIManager->UIConstants"
    "InputManager->UIManager"
    "InputManager->FontManager"
    "PathfinderManager->EventManager"
    "ParticleManager->EventManager"
    "ResourceFactory->ResourceTemplateManager"
    "ResourceTemplateManager->ResourceFactory"
    "WorldResourceManager->EventManager"
)

# Convert array to grep pattern
FUNCTIONAL_PATTERN=$(printf "|%s" "${FUNCTIONAL_DEPS[@]}")
FUNCTIONAL_PATTERN="${FUNCTIONAL_PATTERN:1}"  # Remove leading |

# For each manager pair with coupling, analyze strength
TIGHT_COUPLING_COUNT=0
FUNCTIONAL_COUPLING_COUNT=0

for MGR1 in $MANAGERS; do
    MGR1_NAME=$(basename "$MGR1" .hpp)
    MGR1_CPP="src/managers/${MGR1_NAME}.cpp"

    if [ -f "$MGR1_CPP" ]; then
        for MGR2 in $MANAGERS; do
            MGR2_NAME=$(basename "$MGR2" .hpp)

            if [ "$MGR1_NAME" != "$MGR2_NAME" ]; then
                # Count references to MGR2 in MGR1's implementation
                REF_COUNT=$(grep -c "$MGR2_NAME" "$MGR1_CPP" 2>/dev/null || echo "0")

                if [ "$REF_COUNT" -gt 10 ]; then
                    COUPLING_PAIR="${MGR1_NAME}->${MGR2_NAME}"

                    # Check if this is a functional dependency
                    if echo "$COUPLING_PAIR" | grep -qE "$FUNCTIONAL_PATTERN"; then
                        echo "✅ FUNCTIONAL: $MGR1_NAME -> $MGR2_NAME ($REF_COUNT references)"
                        echo "    Status: Expected game system interaction (correct design)"
                        FUNCTIONAL_COUPLING_COUNT=$((FUNCTIONAL_COUPLING_COUNT + 1))
                    else
                        echo "🔴 TIGHT: $MGR1_NAME -> $MGR2_NAME ($REF_COUNT references)"
                        echo "    Review: Is this coupling necessary for game functionality?"
                        TIGHT_COUPLING_COUNT=$((TIGHT_COUPLING_COUNT + 1))
                    fi
                elif [ "$REF_COUNT" -gt 5 ]; then
                    echo "📊 MODERATE: $MGR1_NAME -> $MGR2_NAME ($REF_COUNT references)"
                fi
            fi
        done
    fi
done

echo ""
echo "Summary:"
echo "  - Functional coupling (expected): $FUNCTIONAL_COUPLING_COUNT pairs"
echo "  - Tight coupling (review): $TIGHT_COUPLING_COUNT pairs"
echo ""
echo "Note: Functional coupling is CORRECT for game engines - systems must interact!"

Mode 3: Full Architecture Audit

3a. Layer Violation Detection

echo "=== Layer Violation Detection ==="

# Define layers
CORE_HEADERS=$(find include/core src/core -name "*.hpp" 2>/dev/null)
MANAGER_HEADERS=$(find include/managers src/managers -name "*.hpp" 2>/dev/null)
STATE_HEADERS=$(find include/gameStates src/gameStates -name "*.hpp" 2>/dev/null)
ENTITY_HEADERS=$(find include/entities src/entities -name "*.hpp" 2>/dev/null)
UTIL_HEADERS=$(find include/utils src/utils -name "*.hpp" 2>/dev/null)

# Check Core layer (should not depend on anything)
echo "1. Core Layer (should be dependency-free):"
for CORE in $CORE_HEADERS; do
    VIOLATIONS=$(grep '#include "' "$CORE" | grep -v 'core/' | grep -v 'utils/' | wc -l)
    if [ "$VIOLATIONS" -gt 0 ]; then
        echo "  🔴 $(basename "$CORE"): includes non-Core/Utils headers"
        grep '#include "' "$CORE" | grep -v 'core/' | grep -v 'utils/'
    fi
done

# Check Manager layer (should not depend on States or Entities)
echo ""
echo "2. Manager Layer (should not depend on States/Entities):"
for MGR in $MANAGER_HEADERS; do
    STATE_DEPS=$(grep '#include "' "$MGR" | grep -c 'gameStates/' 2>/dev/null || echo "0")
    ENTITY_DEPS=$(grep '#include "' "$MGR" | grep -c 'entities/' 2>/dev/null || echo "0")

    if [ "$STATE_DEPS" -gt 0 ] || [ "$ENTITY_DEPS" -gt 0 ]; then
        echo "  🔴 $(basename "$MGR"): violates layer boundaries"
        [ "$STATE_DEPS" -gt 0 ] && echo "    - Includes State headers (forbidden)"
        [ "$ENTITY_DEPS" -gt 0 ] && echo "    - Includes Entity headers (review needed)"
    fi
done

# Check State layer (should not depend on other States)
echo ""
echo "3. State Layer (states should not depend on each other):"
for STATE1 in $STATE_HEADERS; do
    STATE1_NAME=$(basename "$STATE1")

    for STATE2 in $STATE_HEADERS; do
        STATE2_NAME=$(basename "$STATE2")

        if [ "$STATE1_NAME" != "$STATE2_NAME" ]; then
            if grep -q "#include \"$STATE2_NAME\"" "$STATE1" 2>/dev/null; then
                echo "  🔴 $STATE1_NAME -> $STATE2_NAME (cross-state dependency)"
            fi
        fi
    done
done

# Check Utils layer (should not depend on anything)
echo ""
echo "4. Utils Layer (should be dependency-free):"
for UTIL in $UTIL_HEADERS; do
    NON_UTIL_DEPS=$(grep '#include "' "$UTIL" | grep -v 'utils/' | wc -l)
    if [ "$NON_UTIL_DEPS" -gt 0 ]; then
        echo "  ⚠️  $(basename "$UTIL"): includes non-Utils headers"
        grep '#include "' "$UTIL" | grep -v 'utils/'
    fi
done

echo ""
echo "Layer Violation Summary:"
CORE_VIOLATIONS=$(find include/core src/core -name "*.hpp" -exec grep '#include "' {} \; | grep -v 'core/' | grep -v 'utils/' | wc -l)
MANAGER_VIOLATIONS=$(find include/managers src/managers -name "*.hpp" -exec grep '#include "' {} \; | grep 'gameStates/' | wc -l)
STATE_VIOLATIONS=0  # Count from previous check
UTIL_VIOLATIONS=$(find include/utils src/utils -name "*.hpp" -exec grep '#include "' {} \; | grep -v 'utils/' | wc -l)

TOTAL_VIOLATIONS=$((CORE_VIOLATIONS + MANAGER_VIOLATIONS + STATE_VIOLATIONS + UTIL_VIOLATIONS))

if [ "$TOTAL_VIOLATIONS" -eq 0 ]; then
    echo "  ✅ No layer violations detected"
else
    echo "  🔴 $TOTAL_VIOLATIONS layer violations found"
fi

3b. Header Bloat Analysis

echo ""
echo "=== Header Bloat Analysis ==="

# Find headers with excessive includes
echo "Headers with High Include Count (potential bloat):"
echo ""

for HEADER in $ALL_HEADERS; do
    INCLUDE_COUNT=$(grep -c '^#include "' "$HEADER")

    if [ "$INCLUDE_COUNT" -gt 15 ]; then
        echo "  🔴 $(basename "$HEADER"): $INCLUDE_COUNT includes (HIGH - review for bloat)"
    elif [ "$INCLUDE_COUNT" -gt 10 ]; then
        echo "  ⚠️  $(basename "$HEADER"): $INCLUDE_COUNT includes (MODERATE)"
    fi
done

# Find commonly included heavy headers
echo ""
echo "Frequently Included Headers (ripple effect on compile times):"
echo ""

# Count how many files include each header
while IFS= read -r HEADER; do
    HEADER_NAME=$(basename "$HEADER")
    INCLUDE_COUNT=$(grep -r "#include \"$HEADER_NAME\"" include/ src/ 2>/dev/null | wc -l)

    if [ "$INCLUDE_COUNT" -gt 10 ]; then
        echo "  $HEADER_NAME: included by $INCLUDE_COUNT files"

        # Check if this header itself has many includes (bloat amplification)
        HEADER_INCLUDES=$(grep -c '^#include' "$HEADER" 2>/dev/null || echo "0")
        if [ "$HEADER_INCLUDES" -gt 10 ]; then
            echo "    ⚠️  This header includes $HEADER_INCLUDES files (bloat amplification)"
        fi
    fi
done <<< "$ALL_HEADERS" | sort -t: -k2 -rn | head -15

3c. Forward Declaration Opportunities

echo ""
echo "=== Forward Declaration Opportunities ==="

# Find headers that could use forward declarations
# Pattern: Header includes another header but only uses pointers/references

echo "Analyzing headers for forward declaration opportunities..."
echo ""

for HEADER in $ALL_HEADERS; do
    # Get all includes
    INCLUDES=$(grep '^#include "' "$HEADER" | sed 's/#include "\(.*\.hpp\)"/\1/')

    for INCLUDE in $INCLUDES; do
        INCLUDE_BASE=$(basename "$INCLUDE" .hpp)

        # Check if only used as pointer or reference
        # Look for: ClassName* or ClassName&, but NOT ClassName object;
        PTR_REF_ONLY=$(grep -c "${INCLUDE_BASE}[*&]" "$HEADER" 2>/dev/null || echo "0")
        DIRECT_USE=$(grep -c "${INCLUDE_BASE}[^*&];.*;" "$HEADER" 2>/dev/null || echo "0")

        if [ "$PTR_REF_ONLY" -gt 0 ] && [ "$DIRECT_USE" -eq 0 ]; then
            echo "  ✨ $(basename "$HEADER"): Can forward-declare $INCLUDE_BASE"
            echo "     Remove: #include \"$INCLUDE\""
            echo "     Add: class $INCLUDE_BASE; // Forward declaration"
            echo ""
        fi
    done
done | head -30  # Limit output

echo "Note: Move #include to .cpp file after forward declaration"

3d. Compile Time Impact Estimation

echo ""
echo "=== Compile Time Impact Estimation ==="

# Estimate compilation cost based on dependency depth
echo "Dependency Depth (higher = more recompilation ripple):"
echo ""

# For each header, calculate max depth to leaf nodes
# This is an approximation of compile time impact

# Create depth calculation script
cat > "$OUTPUT_DIR/calc_depth.py" <<'PYTHON_SCRIPT'
#!/usr/bin/env python3
import sys
from collections import defaultdict, deque

def read_graph(graph_file):
    graph = defaultdict(list)
    with open(graph_file, 'r') as f:
        for line in f:
            if '->' in line:
                source, target = line.strip().split(' -> ')
                graph[source].append(target)
    return graph

def calculate_depth(graph, node, memo=None):
    """Calculate max dependency depth using DFS with memoization."""
    if memo is None:
        memo = {}

    if node in memo:
        return memo[node]

    if node not in graph or not graph[node]:
        memo[node] = 0
        return 0

    max_depth = 0
    for neighbor in graph[node]:
        depth = calculate_depth(graph, neighbor, memo)
        max_depth = max(max_depth, depth + 1)

    memo[node] = max_depth
    return max_depth

def main():
    if len(sys.argv) != 2:
        print("Usage: calc_depth.py <graph_file>")
        sys.exit(1)

    graph = read_graph(sys.argv[1])

    # Calculate depth for all nodes
    depths = {}
    for node in graph:
        depths[node] = calculate_depth(graph, node)

    # Sort by depth (highest first)
    sorted_depths = sorted(depths.items(), key=lambda x: x[1], reverse=True)

    print("Top 20 Headers by Dependency Depth:")
    print()
    for node, depth in sorted_depths[:20]:
        if depth > 10:
            status = "🔴 VERY HIGH"
        elif depth > 7:
            status = "⚠️  HIGH"
        elif depth > 4:
            status = "🟡 MODERATE"
        else:
            status = "✅ LOW"

        print(f"  {node}: depth={depth} {status}")

    print()
    print("Note: High depth = changing this header causes cascading recompilation")

if __name__ == '__main__':
    main()
PYTHON_SCRIPT

chmod +x "$OUTPUT_DIR/calc_depth.py"
python3 "$OUTPUT_DIR/calc_depth.py" "$GRAPH_FILE"

# Estimate total compile impact
echo ""
echo "Estimated Compile Time Impact:"
TOTAL_DEPTH=$(python3 "$OUTPUT_DIR/calc_depth.py" "$GRAPH_FILE" 2>/dev/null | grep "depth=" | awk -F'depth=' '{print $2}' | awk '{print $1}' | paste -sd+ | bc)
echo "  Total dependency depth: $TOTAL_DEPTH"
echo "  Average per header: $(echo "scale=1; $TOTAL_DEPTH / $HEADER_COUNT" | bc)"

Mode 4: Specific Component Analysis

4a. Single Component Dependency Analysis

# User specified component (e.g., AIManager)
COMPONENT="$USER_COMPONENT"
COMPONENT_HEADER=$(find include/ src/ -name "${COMPONENT}.hpp" | head -1)

if [ -z "$COMPONENT_HEADER" ]; then
    echo "❌ Component not found: $COMPONENT"
    exit 1
fi

echo "=== Dependency Analysis: $COMPONENT ==="
echo ""

# What this component depends on (efferent)
echo "1. What $COMPONENT depends on (Efferent Dependencies):"
echo ""
grep '^#include "' "$COMPONENT_HEADER" | sed 's/#include "\(.*\)"/  - \1/'

EFFERENT_COUNT=$(grep -c '^#include "' "$COMPONENT_HEADER")
echo ""
echo "  Total: $EFFERENT_COUNT direct dependencies"

# What depends on this component (afferent)
echo ""
echo "2. What depends on $COMPONENT (Afferent Dependencies):"
echo ""

COMPONENT_NAME=$(basename "$COMPONENT_HEADER")
DEPENDENTS=$(grep -r "#include \"$COMPONENT_NAME\"" include/ src/ 2>/dev/null | cut -d: -f1 | sort -u)

if [ -z "$DEPENDENTS" ]; then
    echo "  (None - this is a leaf component)"
else
    echo "$DEPENDENTS" | while read DEP; do
        echo "  - $(basename "$DEP")"
    done
fi

AFFERENT_COUNT=$(echo "$DEPENDENTS" | wc -l)
echo ""
echo "  Total: $AFFERENT_COUNT dependent files"

# Coupling metrics
echo ""
echo "3. Coupling Metrics:"
echo "  - Efferent Coupling (Fan-Out): $EFFERENT_COUNT"
echo "  - Afferent Coupling (Fan-In): $AFFERENT_COUNT"

TOTAL=$((EFFERENT_COUNT + AFFERENT_COUNT))
if [ "$TOTAL" -gt 0 ]; then
    INSTABILITY=$(echo "scale=2; $EFFERENT_COUNT / $TOTAL" | bc)
    echo "  - Instability (I): $INSTABILITY"

    if (( $(echo "$INSTABILITY > 0.8" | bc -l) )); then
        echo "    → Highly unstable (easy to change, but volatile)"
    elif (( $(echo "$INSTABILITY < 0.2" | bc -l) )); then
        echo "    → Highly stable (hard to change, but reliable)"
    else
        echo "    → Balanced stability"
    fi
fi

# Layer check
echo ""
echo "4. Layer Classification:"
if echo "$COMPONENT_HEADER" | grep -q "core/"; then
    echo "  - Layer: Core"
    echo "  - Should depend on: Nothing"
elif echo "$COMPONENT_HEADER" | grep -q "managers/"; then
    echo "  - Layer: Managers"
    echo "  - Should depend on: Core, Utils"
    echo "  - Should NOT depend on: States, other Managers (loosely coupled)"
elif echo "$COMPONENT_HEADER" | grep -q "gameStates/"; then
    echo "  - Layer: States"
    echo "  - Should depend on: Core, Managers, Utils"
    echo "  - Should NOT depend on: Other States"
elif echo "$COMPONENT_HEADER" | grep -q "entities/"; then
    echo "  - Layer: Entities"
    echo "  - Should depend on: Core, Utils"
elif echo "$COMPONENT_HEADER" | grep -q "utils/"; then
    echo "  - Layer: Utils"
    echo "  - Should depend on: Nothing"
fi

# Specific issues
echo ""
echo "5. Potential Issues:"
# Check for layer violations
VIOLATIONS=0

if echo "$COMPONENT_HEADER" | grep -q "managers/"; then
    STATE_DEPS=$(grep '#include "' "$COMPONENT_HEADER" | grep -c 'gameStates/' || echo "0")
    if [ "$STATE_DEPS" -gt 0 ]; then
        echo "  🔴 Includes State headers (layer violation)"
        VIOLATIONS=$((VIOLATIONS + 1))
    fi
fi

if [ "$EFFERENT_COUNT" -gt 15 ]; then
    echo "  ⚠️  High efferent coupling ($EFFERENT_COUNT dependencies)"
    VIOLATIONS=$((VIOLATIONS + 1))
fi

# Check for circular dependencies involving this component
COMPONENT_BASE=$(basename "$COMPONENT_HEADER")
CYCLES=$(python3 "$OUTPUT_DIR/detect_cycles.py" "$GRAPH_FILE" 2>&1 | grep "$COMPONENT_BASE" || echo "")
if [ ! -z "$CYCLES" ]; then
    echo "  🔴 Part of circular dependency"
    echo "$CYCLES" | sed 's/^/      /'
    VIOLATIONS=$((VIOLATIONS + 1))
fi

if [ "$VIOLATIONS" -eq 0 ]; then
    echo "  ✅ No issues detected"
fi

Step 4: Generate Dependency Visualizations

4a. ASCII Dependency Tree

echo ""
echo "=== Dependency Tree (ASCII) ==="

# Create tree visualization script
cat > "$OUTPUT_DIR/make_tree.sh" <<'TREE_SCRIPT'
#!/bin/bash

# Function to print tree recursively
print_tree() {
    local node=$1
    local prefix=$2
    local visited=$3
    local max_depth=$4
    local current_depth=$5

    # Prevent infinite loops
    if echo "$visited" | grep -q "|$node|"; then
        echo "${prefix}└── $node (circular)"
        return
    fi

    # Max depth limit
    if [ "$current_depth" -ge "$max_depth" ]; then
        echo "${prefix}└── $node (...)"
        return
    fi

    echo "${prefix}└── $node"

    # Get dependencies
    local deps=$(grep "^$node ->" "$GRAPH_FILE" | cut -d'>' -f2 | tr -d ' ')

    if [ ! -z "$deps" ]; then
        local new_visited="${visited}|${node}|"
        local new_depth=$((current_depth + 1))

        echo "$deps" | while read dep; do
            print_tree "$dep" "${prefix}    " "$new_visited" "$max_depth" "$new_depth"
        done
    fi
}

# Entry point
GRAPH_FILE="$1"
ROOT_NODE="$2"
MAX_DEPTH="${3:-5}"

print_tree "$ROOT_NODE" "" "" "$MAX_DEPTH" 0
TREE_SCRIPT

chmod +x "$OUTPUT_DIR/make_tree.sh"

# Generate trees for key components
echo ""
echo "GameEngine Dependency Tree:"
"$OUTPUT_DIR/make_tree.sh" "$GRAPH_FILE" "GameEngine.hpp" 3

echo ""
echo "AIManager Dependency Tree:"
"$OUTPUT_DIR/make_tree.sh" "$GRAPH_FILE" "AIManager.hpp" 3

4b. Dependency Matrix (for report)

# Generate full dependency matrix for report
echo ""
echo "Generating dependency matrix for report..."

cat > "$OUTPUT_DIR/dependency_matrix.txt" <<EOF
# Dependency Matrix

Rows depend on Columns (✓ = direct dependency)

EOF

# Get top 20 most connected headers
TOP_HEADERS=$(cat "$GRAPH_FILE" | grep -o '[^ ]*\.hpp' | sort | uniq -c | sort -rn | head -20 | awk '{print $2}')

# Print header row
printf "%-25s" "Component"
echo "$TOP_HEADERS" | while read HEADER; do
    HEADER_SHORT=$(echo "$HEADER" | cut -d'.' -f1 | cut -c1-7)
    printf "%-8s" "$HEADER_SHORT"
done
echo ""

# Print matrix rows
echo "$TOP_HEADERS" | while read ROW_HEADER; do
    printf "%-25s" "$(echo "$ROW_HEADER" | cut -d'.' -f1)"

    echo "$TOP_HEADERS" | while read COL_HEADER; do
        if [ "$ROW_HEADER" = "$COL_HEADER" ]; then
            printf "%-8s" "-"
        else
            HAS_DEP=$(grep "^$ROW_HEADER -> $COL_HEADER$" "$GRAPH_FILE")
            if [ ! -z "$HAS_DEP" ]; then
                printf "%-8s" "✓"
            else
                printf "%-8s" " "
            fi
        fi
    done
    echo ""
done >> "$OUTPUT_DIR/dependency_matrix.txt"

echo "Dependency matrix saved to: $OUTPUT_DIR/dependency_matrix.txt"

Step 5: Generate Architecture Health Report

Report Structure:

# HammerEngine Dependency Analysis Report

**Generated:** YYYY-MM-DD HH:MM:SS
**Branch:** <branch>
**Commit:** <hash>
**Analysis Mode:** <mode>

---

## Executive Summary

**Architecture Health Score:** [85/100] (GOOD)

**Status:** ✅ HEALTHY / ⚠️ NEEDS ATTENTION / 🔴 CRITICAL ISSUES

**Key Findings:**
- [Finding 1]
- [Finding 2]
- [Finding 3]

**Overall Assessment:** [2-3 sentence summary]

---

## Dependency Statistics

**Codebase Size:**
- Total headers analyzed: [N]
- Core layer: [N] files
- Managers layer: [N] files
- States layer: [N] files
- Entities layer: [N] files
- Utils layer: [N] files

**Dependency Metrics:**
- Total dependencies: [N]
- Average dependencies per file: [X.X]
- Max dependencies (single file): [N]
- Circular dependencies: [N] 🔴/✅

---

## Circular Dependencies (CRITICAL)

[If none:]
✅ **NO CIRCULAR DEPENDENCIES DETECTED**

All include hierarchies are acyclic. Compilation order is deterministic.

[If found:]
🔴 **FOUND [N] CIRCULAR DEPENDENCIES**

### Cycle 1: [Component A] ↔ [Component B]

**Cycle Path:**

ComponentA.hpp -> ComponentB.hpp -> ComponentA.hpp


**Impact:** Breaks compilation or requires workarounds

**Suggested Fix:**
1. **Forward Declaration** (RECOMMENDED)
   - In ComponentA.hpp, replace `#include "ComponentB.hpp"` with `class ComponentB;`
   - Move include to ComponentA.cpp

2. **Interface Extraction**
   - Create IComponentB.hpp with pure virtual interface
   - ComponentA depends on interface (breaks cycle)

[Repeat for each cycle]

---

## Coupling Analysis

### High-Coupling Components (Top 10)

| Component | Fan-Out | Fan-In | Instability | Status |
|-----------|---------|--------|-------------|--------|
| [Component1] | 18 | 5 | 0.78 | 🔴 HIGH |
| [Component2] | 15 | 12 | 0.55 | ⚠️  MODERATE |
| [Component3] | 8 | 20 | 0.29 | ✅ STABLE |

**Legend:**
- **Fan-Out:** Number of dependencies (efferent coupling)
- **Fan-In:** Number of dependents (afferent coupling)
- **Instability:** Fan-Out / (Fan-In + Fan-Out)
  - 0.0 = Maximally stable (hard to change)
  - 1.0 = Maximally unstable (easy to change)

### Manager-to-Manager Coupling

**Coupling Matrix:**

[Include dependency matrix from Step 4b]

**Manager Coupling Analysis:**

**Important Context:** Game engines have **necessary functional dependencies**. Tight coupling between game systems is often **CORRECT and required** for the engine to function.

**Functional Coupling (✅ Expected & Correct):**
[List coupling pairs that serve game functionality]
- AIManager → CollisionManager (AI obstacle avoidance, LOS checks)
- CollisionManager → WorldManager (world geometry queries)
- Managers → EventManager (event-driven notifications)
- UIManager → FontManager (text rendering)
- etc.

**Status:** ✅ These dependencies are functionally necessary and represent correct game engine architecture.

**Problematic Coupling (🔴 Review Required):**
[If any non-functional tight coupling exists]
1. **[Manager1] → [Manager2]** (N references)
   - Status: 🔴 REVIEW
   - Reason: Unclear functional necessity
   - Recommendation: Verify this coupling serves game functionality

[If none:]
✅ **NO PROBLEMATIC COUPLING**

All tight coupling serves clear game system functionality.

---

## Layer Violations

### Layer Integrity Check

**Core Layer** (should depend on nothing):
[✅ CLEAN / 🔴 [N] violations]

**Managers Layer** (should depend on Core, Utils only):
[✅ CLEAN / 🔴 [N] violations]

**States Layer** (no cross-state dependencies):
[✅ CLEAN / 🔴 [N] violations]

**Utils Layer** (should be dependency-free):
[✅ CLEAN / 🔴 [N] violations]

### Violation Details

[If violations found:]

**Violation 1: AIManager includes PlayingState.hpp**
- **File:** include/managers/AIManager.hpp:15
- **Issue:** Manager layer depending on State layer
- **Impact:** Violates layered architecture, creates tight coupling
- **Fix:** Remove include, use interface or event system

[Repeat for each violation]

[If none:]
✅ **NO LAYER VIOLATIONS**

All components respect layered architecture boundaries.

---

## Header Bloat Analysis

### High-Include Headers

| Header | #Includes | Status | Dependents |
|--------|-----------|--------|-----------|
| [Header1] | 22 | 🔴 HIGH | 15 files |
| [Header2] | 18 | ⚠️  MODERATE | 8 files |

**Bloat Amplification:**

Headers with many includes that are widely used cause compilation ripple effects.

**Worst Offenders:**
1. **GameEngine.hpp** - 22 includes, used by 15 files
   - Ripple effect: ~330 transitive includes
   - Recommendation: Split into GameEngine_fwd.hpp with forward declarations

### Forward Declaration Opportunities

[Top 10 opportunities from Step 3c]

**Estimated Compile Time Savings:** ~15-25% reduction

---

## Dependency Depth Analysis

### Compile Time Impact

| Header | Depth | Impact | Recommendation |
|--------|-------|--------|----------------|
| [Header1] | 14 | 🔴 VERY HIGH | Reduce dependencies |
| [Header2] | 9 | ⚠️  HIGH | Consider splitting |
| [Header3] | 6 | 🟡 MODERATE | Monitor |

**Total Dependency Depth:** [N]
**Average Depth:** [X.X]

**High-Depth Components:**

Changing these headers causes cascading recompilation:
- [List top 5 highest depth headers]

**Recommendation:** Use forward declarations and split large headers

---

## Architecture Health Scorecard

| Category | Score | Weight | Weighted | Status |
|----------|-------|--------|----------|--------|
| Circular Dependencies | [X/10] | 30% | [X.X] | 🔴/⚠️/✅ |
| Layer Compliance | [X/10] | 25% | [X.X] | 🔴/⚠️/✅ |
| Coupling Strength | [X/10] | 20% | [X.X] | 🔴/⚠️/✅ |
| Header Bloat | [X/10] | 15% | [X.X] | 🔴/⚠️/✅ |
| Dependency Depth | [X/10] | 10% | [X.X] | 🔴/⚠️/✅ |
| **TOTAL** | | **100%** | **[XX/100]** | **[GRADE]** |

**Grading Scale:**
- 90-100: A+ (Excellent architecture)
- 80-89: A (Good architecture, minor issues)
- 70-79: B (Fair architecture, needs improvement)
- 60-69: C (Poor architecture, refactoring required)
- Below 60: F (Critical issues, major refactoring needed)

---

## Recommendations

### Critical (Fix Immediately)

1. **Break Circular Dependencies** ([N] found)
   - Use forward declarations
   - Extract interfaces
   - Priority: HIGH, Effort: 2-4 hours

2. **Fix Layer Violations** ([N] found)
   - Remove inappropriate includes
   - Use event system for cross-layer communication
   - Priority: HIGH, Effort: 1-2 hours

### Important (Address Soon)

3. **Review Non-Functional Coupling (if any)**
   - [Only list coupling that doesn't serve clear game functionality]
   - Verify: Does this coupling serve a game system requirement?
   - If yes: Document the functional reason, no change needed
   - If no: Consider refactoring or event-based communication
   - Priority: MEDIUM (only if problematic coupling exists)

4. **Optimize High-Include Headers**
   - Split [Header] into interface and implementation
   - Add forward declaration headers
   - Priority: MEDIUM, Effort: 2-3 hours

**Note:** Do NOT refactor functional game system dependencies. Coupling between managers is often necessary and correct for game engines.

### Optional (Consider)

5. **Improve Compile Times**
   - Apply forward declaration opportunities
   - Split large headers
   - Expected improvement: 15-25% faster compilation
   - Priority: LOW, Effort: 3-5 hours

---

## Dependency Visualizations

### GameEngine Dependency Tree

[ASCII tree from Step 4a]

### AIManager Dependency Tree

[ASCII tree from Step 4a]

### Full Dependency Matrix

[Link to or include dependency_matrix.txt]

---

## Comparison with Previous Analysis (if baseline exists)

| Metric | Previous | Current | Change | Trend |
|--------|----------|---------|--------|-------|
| Total Dependencies | [N] | [N] | [+/-N] | 📈/📉/➡️ |
| Circular Dependencies | [N] | [N] | [+/-N] | 📈/📉/➡️ |
| Layer Violations | [N] | [N] | [+/-N] | 📈/📉/➡️ |
| Average Coupling | [X.X] | [X.X] | [+/-X.X] | 📈/📉/➡️ |
| Health Score | [XX] | [XX] | [+/-XX] | 📈/📉/➡️ |

**Overall Trend:** [Improving/Stable/Degrading]

---

## Action Plan

### Immediate (This Week)
- [ ] Break circular dependency: [Cycle description]
- [ ] Fix layer violation: [Specific violation]

### Short-term (This Month)
- [ ] Reduce coupling between [Component1] and [Component2]
- [ ] Split high-include headers: [Header list]
- [ ] Apply top 5 forward declaration opportunities

### Long-term (This Quarter)
- [ ] Comprehensive header cleanup
- [ ] Establish pre-commit dependency checks
- [ ] Document architecture patterns

---

## Files Requiring Attention

Based on analysis, these files need modification:

**High Priority:**
- [File1] - Circular dependency
- [File2] - Layer violation

**Medium Priority:**
- [File3] - High coupling
- [File4] - Header bloat

**Low Priority:**
- [File5] - Forward declaration opportunity

---

## Next Steps

1. **Review this report** with team/architect
2. **Prioritize fixes** based on impact and effort
3. **Create tickets** for identified issues
4. **Re-run analysis** after fixes to verify improvements
5. **Schedule regular audits** (monthly recommended)

**Re-run Analysis:**
```bash
# After fixes, verify improvements
[Command to re-invoke skill]

Report Generated By: hammer-dependency-analyzer Skill Report Saved To: docs/architecture/dependency_analysis_YYYY-MM-DD.md


**Save report:**
```bash
REPORT_FILE="docs/architecture/dependency_analysis_$(date +%Y-%m-%d).md"
mkdir -p "docs/architecture"

cat > "$REPORT_FILE" <<'EOF'
[Generated markdown report]
EOF

echo "✅ Dependency analysis report saved to: $REPORT_FILE"

Step 6: Console Summary

=== HammerEngine Dependency Analysis ===

Mode: [Mode Name]
Files Analyzed: [N] headers

Architecture Health: [Score]/100 ([GRADE])

Circular Dependencies: [N] 🔴/✅
Layer Violations: [N] 🔴/✅
High Coupling: [N] components ⚠️
Header Bloat: [N] headers 🔴/⚠️

[If issues:]
Status: 🔴 CRITICAL ISSUES / ⚠️  NEEDS ATTENTION

Critical Issues:
  - [Issue 1]
  - [Issue 2]

Recommendations:
  1. [Top recommendation]
  2. [Second recommendation]

[If clean:]
Status: ✅ ARCHITECTURE HEALTHY

All checks passed:
  ✅ No circular dependencies
  ✅ No layer violations
  ✅ Coupling within acceptable limits
  ✅ No excessive header bloat

Full Report: docs/architecture/dependency_analysis_YYYY-MM-DD.md

Next: [Suggested action based on results]

Usage Examples

When the user says:

  • "analyze dependencies"
  • "check architecture health"
  • "find circular dependencies"
  • "check manager coupling"
  • "analyze AIManager dependencies"
  • "audit header dependencies"

Activate this Skill automatically.


Integration with Development Workflow

Use this Skill:

Regular Maintenance

  • Monthly audits - Catch architectural drift early
  • After major refactors - Verify improvements
  • Before releases - Ensure architecture quality

Development Checkpoints

  • Adding new manager - Verify coupling is appropriate
  • Refactoring existing code - Check impact on dependencies
  • Investigating compile times - Identify bloat and depth issues

Problem Investigation

  • Circular dependency errors - Find and break cycles
  • Slow compilation - Identify high-depth headers
  • Tight coupling concerns - Analyze manager interactions

Common Dependency Issues in HammerEngine

Issue 1: Manager Circular Dependencies

Symptom: Compilation errors with forward declaration issues Cause: Two managers including each other's headers Solution: One-way dependency with interface or event system

Issue 2: State-to-State Dependencies

Symptom: States including other state headers Cause: Sharing data/logic between states Solution: Move shared logic to Manager or GameEngine

Issue 3: GameEngine.hpp Bloat

Symptom: Long compile times for any GameEngine change Cause: GameEngine includes all managers in header Solution: Forward declarations + includes in .cpp

Issue 4: Layer Violations

Symptom: Manager includes State header Cause: Manager needs state-specific logic Solution: Dependency inversion - state registers callback with manager

Issue 5: Utils Dependencies

Symptom: Utils including Core or Manager headers Cause: Utils trying to use engine-specific types Solution: Make Utils pure (STL only), or move to appropriate layer


Performance Expectations

  • Quick Circular Check: 2-3 minutes (scan + cycle detection)
  • Coupling Analysis: 5-10 minutes (metrics + matrix)
  • Full Architecture Audit: 15-20 minutes (all checks + visualization)
  • Specific Component: 3-5 minutes (single component deep dive)

Manual Equivalent: 60-120 minutes per full audit


Exit Codes

  • 0: No architectural issues detected
  • 1: Circular dependencies found (BLOCKING)
  • 2: Layer violations detected (CRITICAL)
  • 3: High coupling detected (WARNING)
  • 4: Multiple issues detected

Important Notes

  1. Run regularly - Architecture degrades over time without monitoring
  2. Fix issues promptly - Small issues compound into major refactors
  3. Document patterns - Share good architectural examples with team
  4. Automate checks - Consider pre-commit hooks for critical violations
  5. Track trends - Monitor health score over time
  6. Game Engine Context - Remember that tight manager coupling is often functionally necessary

Scoring Guidance for Game Engines

Coupling Strength Score Calculation:

When scoring coupling (20% of health score), distinguish between:

  1. Functional Coupling (✅ Good, score: 8-10/10)

    • Game systems that must interact to work
    • Examples: AI→Collision, Collision→World, Managers→Events
    • These are correct design and should NOT reduce the score significantly
  2. Problematic Coupling (🔴 Bad, score: 0-4/10)

    • Circular dependencies (breaks compilation)
    • Layer violations (Manager→State)
    • Unclear/unnecessary dependencies

Scoring Formula:

Coupling Score = 10 - (problematic_coupling_count * 1.5)

Where problematic_coupling_count =
  - Circular dependencies found
  - Layer-violating dependencies
  - Non-functional tight coupling (unclear purpose)

Functional coupling does NOT reduce score.

Example:

  • 0 problematic, 9 functional: Score = 10/10 ✅ Excellent
  • 1-2 problematic, 9 functional: Score = 7-8.5/10 ✅ Good
  • 3-5 problematic, 9 functional: Score = 4-6/10 ⚠️ Needs work
  • 6+ problematic: Score = 0-2/10 🔴 Critical

This scoring recognizes that game engines NEED manager coupling to function.


Ready to analyze HammerEngine architecture. Ask user for analysis mode.