View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0005270 | Spring engine | AI | public | 2016-06-07 15:06 | 2018-02-01 18:27 |
| Reporter | lamer | Assigned To | |||
| Priority | normal | Severity | crash | Reproducibility | sometimes |
| Status | resolved | Resolution | fixed | ||
| Product Version | 101.0+git | ||||
| Fixed in Version | 104.0 | ||||
| Summary | 0005270: Unit events sent after UnitDestroyed may crash AI | ||||
| Description | If unit isDead then AI can't do anything about it. So why bother native AIs with false events when there is no unit validation API? | ||||
| Additional Information | Here is a debug snippet of bad run: [f=0007989] Skirmish AI <Circuit-0.8.3>: 0 | EVENT_UNIT_CREATED unitId: 18785 [f=0008017] Skirmish AI <Circuit-0.8.3>: 0 | EVENT_UNIT_DESTROYED unitId: 18785 [f=0008017] Skirmish AI <Circuit-0.8.3>: 0 | attackerDestroyedHandler task:N7circuit9CNullTaskE | [f=0008017] Skirmish AI <Circuit-0.8.3>: 0 | attackerDestroyedHandler task:N7circuit9CIdleTaskE | [f=0008018] Skirmish AI <Circuit-0.8.3>: 0 | EVENT_UNIT_FINISHED unitId: 18785 [f=0008022] Skirmish AI <Circuit-0.8.3>: 0 | EVENT_UNIT_CREATED unitId: 29964 [f=0008024] Skirmish AI <Circuit-0.8.3>: 0 | CScheduler::ProcessTasks Repeat EXCEPTION: Error calling method "fight": 18785 EVENT_UNIT_FINISHED for unitId 18785 was sent after EVENT_UNIT_DESTROYED. It is allowed by engine to send FINISHED event before CREATED (when lua instantly changes health to full), thus no way to detect that EVENT_UNIT_FINISHED was an error and that unit can't be actually used. Consider legacy AIs (KAIK, E323): seems they don't have try-catch blocks for unit commands and are tottally affected by this bug. | ||||
| Tags | No tags attached. | ||||
| Checked infolog.txt for Errors | |||||
|
|
Hmm, legacy AIs are not affected because only newOO API throws exceptions intentionally. Should be requalified as major annoying bug (or feature request), not crash. Edit: A simple solution that might work is to check isDead before eoh->UnitFinished() (and maybe UnitGiven) call. UnitFinished happens comparatively rare and additional 'if' shouldn't be a performance hog. This will allow to deregister unit on UnitDestroyed event, not register dead unit and thus ignore all other fail Updates or UnitDamaged. |
|
|
Fixed https://github.com/spring/spring/commit/6350db5de5c297e170f22efa27600eefc37bde8c |
|
|
that commit covers the finished-after-destroyed case, not the (Lua-driven) finished-before-created one. since in practice the latter is easily handled, this should still be closable. |
| Date Modified | Username | Field | Change |
|---|---|---|---|
| 2016-06-07 15:06 | lamer | New Issue | |
| 2016-06-07 15:09 | lamer | Note Added: 0016407 | |
| 2016-06-07 22:06 | lamer | Note Edited: 0016407 | |
| 2016-06-08 10:17 | lamer | Note Edited: 0016407 | |
| 2016-06-08 14:11 | lamer | Note Edited: 0016407 | |
| 2017-10-20 13:29 | sprung | Note Added: 0018538 | |
| 2018-02-01 18:27 | Kloot | Status | new => resolved |
| 2018-02-01 18:27 | Kloot | Resolution | open => fixed |
| 2018-02-01 18:27 | Kloot | Fixed in Version | => 104.0 |
| 2018-02-01 18:27 | Kloot | Note Added: 0018764 |