Skip to content

Conversation

@tryuan99
Copy link
Member

To be more explicit for the interceptor and threat events, this PR adds a new event called INTERCEPTOR_DESTROYED and THREAT_DESTROYED, which occur when agents are destroyed prior to reaching their target.

  • INTERCEPTOR_HIT denotes when an interceptor successfully hits its target.

  • INTERCEPTOR_MISS denotes exclusively when an interceptor misses its target due to the kill probability. This does not destroy the interceptor.

  • INTERCEPTOR_DESTROYED denotes when an interceptor is destroyed prior to reaching its target, e.g., through a ground collision.

  • THREAT_HIT denotes when a threat hits its target (the asset).

  • THREAT_DESTROYED denotes when a threat is destroyed prior to reaching the asset, e.g., by being intercepted or colliding with the ground.

  • THREAT_MISS has been removed because threats cannot miss their targets.

@tryuan99 tryuan99 requested a review from daniellovell January 30, 2026 21:54
@stacklane-pr-stack-visualizer
Copy link

stacklane-pr-stack-visualizer bot commented Jan 30, 2026

🧱 Stack PR · Base of stack

Stack Structure:

@tryuan99 tryuan99 linked an issue Jan 30, 2026 that may be closed by this pull request
@tryuan99 tryuan99 changed the title [Logging] Add DESTROYED events [Logging] Add destroyed agent events Jan 30, 2026
Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces INTERCEPTOR_DESTROYED and THREAT_DESTROYED events to provide more explicit logging for when agents are destroyed before reaching their targets. Correspondingly, the THREAT_MISS event has been removed. These changes have been consistently implemented across the C# simulation code, Python analysis tools, and documentation. The refactoring to support these new events is well-executed. I have one suggestion to improve maintainability by replacing a hardcoded string used for ground collision detection with a more robust solution like a Unity Tag.

@coderabbitai
Copy link

coderabbitai bot commented Jan 30, 2026

📝 Walkthrough

Walkthrough

Renames AgentBase.CheckFloorCollision to CheckGroundCollision. Replaces multiple interceptor/threat-specific delegate types with unified InterceptorEventHandler and ThreatEventHandler; removes OnMiss events and adds OnDestroyed events on interceptors and threats. Updates InterceptorBase and ThreatBase to invoke OnDestroyed where appropriate, reorganizes interceptor miss/destroy handling via RegisterMiss/RegisterDestroyed/RequestTargetReassignment, and adjusts collision flows to call CheckGroundCollision. SimManager and SimMonitor wiring updated to subscribe to OnDestroyed and record destroyed events. Adds EventType constants for INTERCEPTOR_DESTROYED and THREAT_DESTROYED, a new metric NumMissileInterceptorsDestroyed, and corresponding logging/visualization/docs updates.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • daniellovell
🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title '[Logging] Add destroyed agent events' directly matches the PR's primary change: introducing new INTERCEPTOR_DESTROYED and THREAT_DESTROYED event types for logging.
Description check ✅ Passed The description comprehensively explains the new events, their distinctions, and why THREAT_MISS was removed, providing clear context for the event semantic changes throughout the codebase.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch titan/destroyed

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
docs/Simulation_Logging.md (1)

200-208: ⚠️ Potential issue | 🟡 Minor

Update the example output to include the new destroyed metric.

The process_run.py script now includes NumMissileInterceptorsDestroyed() in SCALAR_METRICS, but this example output doesn't reflect that. Consider adding a line for the destroyed metric to keep documentation consistent with actual output.

📝 Suggested addition
 Aggregating the stats for 50 runs found in the log directory.
   Number of missile interceptors: mean: 150.360000, std: 13.805448.
   Number of missile interceptor hits: mean: 99.840000, std: 0.611882.
   Number of missile interceptor misses: mean: 36.360000, std: 14.784803.
+  Number of missile interceptors destroyed: mean: X.XXXXXX, std: X.XXXXXX.
   Missile interceptor hit rate: mean: 0.741564, std: 0.077913.
   Missile interceptor efficiency: mean: 0.669430, std: 0.059498.
   Minimum intercept distance: mean: 6154.423782, std: 1283.849098.
Assets/Scripts/Monitors/SimMonitor.cs (1)

209-218: ⚠️ Potential issue | 🟡 Minor

Add a null guard before filtering on IsTerminated.

The per-agent null check is good, but the LINQ filter can still throw if a destroyed Unity object remains in the list. Guard nulls before IsTerminated to avoid MissingReferenceException.

🛠️ Proposed fix
-    List<IAgent> agents = SimManager.Instance.Agents.Where(agent => !agent.IsTerminated).ToList();
+    List<IAgent> agents = SimManager.Instance.Agents
+        .Where(agent => agent != null && !agent.IsTerminated)
+        .ToList();
🤖 Fix all issues with AI agents
In `@Assets/Scripts/Interceptors/IInterceptor.cs`:
- Around line 10-13: Fix the typo in the comment for the OnMiss event: update
the comment text near the event declaration for OnMiss in IInterceptor (the
event named OnMiss) to correct "is misses its target" to "misses its target" or
similar concise grammar ("called when the interceptor misses its target but is
not destroyed.").

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Tools/visualize_log.py (1)

64-82: 🧹 Nitpick | 🔵 Trivial

Consider adding statistics for the new INTERCEPTOR_DESTROYED event type.

The log_event_summary function logs detailed statistics for INTERCEPTOR_HIT and INTERCEPTOR_MISS events but doesn't include the newly added INTERCEPTOR_DESTROYED event type. For completeness, you may want to add similar logging for destroyed interceptors.

Proposed addition for destroyed event statistics
     logging.info("Number of interceptor misses recorded: %d.",
                  len(interceptor_misses))
     if not interceptor_misses.empty:
         first_miss_time = interceptor_misses[Column.TIME].min()
         last_miss_time = interceptor_misses[Column.TIME].max()
         logging.info("  First miss at %.2f, last miss at %.2f.",
                      first_miss_time, last_miss_time)
+
+    # Determine the times of interceptor destroyed events.
+    interceptor_destroyed = (
+        event_df[event_df[Column.EVENT] == EventType.INTERCEPTOR_DESTROYED])
+    logging.info("Number of interceptors destroyed recorded: %d.",
+                 len(interceptor_destroyed))
+    if not interceptor_destroyed.empty:
+        first_destroyed_time = interceptor_destroyed[Column.TIME].min()
+        last_destroyed_time = interceptor_destroyed[Column.TIME].max()
+        logging.info("  First destroyed at %.2f, last destroyed at %.2f.",
+                     first_destroyed_time, last_destroyed_time)
🤖 Fix all issues with AI agents
In `@Tools/visualize_log.py`:
- Around line 27-38: EVENT_TYPE_TO_MARKER is missing a mapping for the new
EventType.THREAT_DESTROYED so destroyed threats are not visualized; add an entry
to EVENT_TYPE_TO_MARKER mapping EventType.THREAT_DESTROYED to an appropriate
EventMarker (e.g., symbol, color, and label) similar to
EventType.INTERCEPTOR_DESTROYED. Update the dict where EVENT_TYPE_TO_MARKER is
defined and use the EventMarker class to provide a distinct marker (for example
"v", "black", "Threat Destroyed" or whatever fits the visual scheme) so
SimMonitor.cs logged THREAT_DESTROYED events appear in the visualization.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Logging] Log ground collisions

2 participants