Dear community, I hope someone can help me with this issue!
I edited my last post to be more precise by providing an easy example that anyone can test.
Problem Summary
I'm experiencing a persistent issue with custom AI scripts where ships dock successfully but immediately undock due to premature DockAndWait order cancellation. This creates an infinite dock/undock loop that I can't resolve despite following vanilla X4 patterns exactly.
I've created a minimal test mod that reproduces this issue 100% of the time. The complete test case is attached as a ZIP file - you can drop it in your X4 extensions folder and see the exact same behavior.
Test Mod Contents:
• order.test.dosomething.xml - Master order that picks random stations
• order.test.trainperform.xml - Training order that exhibits the dock/undock issue
• Comprehensive logging patches - Shows exactly what's happening
What should happen:
1. Ship creates DockAndWait order
2. Ship docks successfully
3. TrainPerform script continues with training
4. Ship stays docked during training
What actually happens:
1. Ship creates DockAndWait order
2. Ship docks successfully
3. DockAndWait confirms "waiting" state
4. Ship undocks immediately
5. Script takes ~8 seconds to restart and detect undocking
6. TrainPerform creates new DockAndWait order
7. Infinite loop
Code: Select all
[Scripts] 290.40: [TEST-TRAIN] ❌ Not docked. Creating DockAndWait and waiting for completion
[Scripts] 380.23: [TEST-PATCH] DockAndWait: === DOCK SUCCESS === Now waiting for caller to complete operations...
[Scripts] 380.23: Kurier Verteidiger successfully docked at ARG Mikrochipfabrik I. waiting.
!! SHIP UNDOCKS MYSTERIOUSLY !!
[Scripts] 388.44: [TEST-TRAIN] === TRAINING START === Ship: KPC-834, Destination: ARG Mikrochipfabrik I
[Scripts] 388.44: [TEST-TRAIN] ❌ Not docked. Creating DockAndWait...
TrainPerform Order (Simplified):
Code: Select all
<!-- Check if already docked -->
<do_if value="(this.ship.dock and (this.ship.dock.container == $destination)) or
(this.ship.parkedat and ((this.ship.parkedat == $destination) or
this.ship.parkedat.hascontext.{$destination}))">
<debug_text text="Already docked - proceeding to training"/>
<resume label="perform_training"/>
</do_if>
<!-- NOT DOCKED: Create DockAndWait -->
<do_if value="not $cannotdock">
<debug_text text="Not docked. Creating DockAndWait and waiting for completion"/>
<create_order id="'DockAndWait'" object="this.ship" immediate="true">
<param name="destination" value="$destination"/>
<param name="timeout" value="0s"/>
<param name="waittime" value="60min"/>
<param name="callerid" value="this.assignedcontrolled.order"/>
<param name="internalorder" value="true"/>
</create_order>
<wait exact="1ms"/>
<resume label="perform_training"/>
</do_if>
<label name="perform_training"/>
<!-- Training logic here -->
• Exact vanilla order.trade.perform.xml pattern with <return/>
• Repair order pattern with <wait exact="1ms"/>
• Both immediate="true" and without immediate flag
• timeout="null" (infinite wait)
• timeout="0s" (no timeout)
• waittime="60min" (explicit wait time)
• With/without callerid parameter
• With/without undockhandler parameter
• Proper subordinate order cleanup
• Critical order state management
• Signal-based completion handling
1. What could cause a DockAndWait order to be cancelled immediately after successful docking?
The ship docks, DockAndWait reports "waiting" state, but then undocks 8 seconds later. What mechanism could cause this?
2. Are there hidden requirements for DockAndWait orders created by custom scripts?
Vanilla orders like TradePerform use DockAndWait successfully. Are there differences in how custom scripts should create these orders?
3. Could there be interference between the parent TrainPerform order and the DockAndWait sub-order?
Is there a proper way to coordinate between a parent AI script and its DockAndWait sub-orders?
4. What's the correct pattern for "dock and wait for script to continue" behavior?
Should custom scripts use <return/> (like TradePerform) or <wait> (like Repair) after creating DockAndWait?
The download contains a complete test mod that reproduces this issue:
To test:
1. Download and extract to X4/extensions/
2. Load any save game
3. Assign "DoSomething" order to any small ship
4. Watch debug log for dock/undock loop
Expected behavior: Ship docks and stays docked for training
Actual behavior: Ship docks, immediately undocks, infinite loop
• X4 Version: 7.60
• Other Mods: None (vanilla + test mod only)
• Script Type: AI Script (aiscripts/), not MD script
This issue has been persistent across multiple implementation attempts. Any insights into:
• X4's order lifecycle management
• Proper DockAndWait usage patterns
• Debugging approaches for order cancellation
• Alternative patterns for dock-and-continue behavior
Would be incredibly helpful! The complete test case should make it easy to reproduce and investigate.
Thanks in advance for any help!
Note: Test mod ZIP attached - contains complete reproducible case with comprehensive logging