Staredit Network > Forums > Modding Assistance > Topic: StarCraft 64 Co-Op Mod - Enemy AI won't launch scripted attacks
StarCraft 64 Co-Op Mod - Enemy AI won't launch scripted attacks
3 hours ago
By: tokatta007  

3 hours ago tokatta007 Post #1



Hi all,

I've built a 2-player split-screen shared-control co-op hack of StarCraft 64 that runs across all 60 campaign missions (I released it as V1 on romhacking.net + GitHub). It works well, but there's one bug I've spent about two days chasing and can't crack, and I'm hoping someone with deeper SC64 knowledge might be able to help out.

The bug: On script-driven survival missions (clearest example: Terran mission 3, "Desperate Alliance" / 00C.chk), the enemy computer doesn't launch proactive scripted attack waves in co-op like it does in the vanilla game. It builds units, the defense buildings fire, and units occasionally defend when directly attacked, but the zerg ai never sends scripted waves of enemies at the player. In vanilla single-player, the same mission's enemy attacks reliably (~1–3 min in). Missions where the enemy uses autonomous/melee-style AI (T1, T2, T5) attack perfectly fine in co-op. Only the trigger/script-driven survival mission type fails.

What I've verified (live, in the PJ64 debugger, vanilla vs co-op on the same mission):
- Enemy is a valid computer player, correct owner (05) / race, on the same slot (4) in both. The AI did not shift to a different slot in co-op.
- The AI script interpreter (0x800939F0 I think), the command dispatcher (0x800196F8 I think), and the AI-script setup action (0x80073740 I think) all run in co-op, same as vanilla.
- Alliance/hostility is fine. The enemy attacks the human players on the missions that work, so it does consider the human an enemy. And occasionally the enemy will attack the units I send at it on this T3 mission.
- I traced the 2-player flag (0x800AFEFC): 137 read sites, 16 that run during the mission. I force-patched all 16 to take the 1-player path simultaneously, but sadly no change to the enemy. So the bug is NOT a 2p-flag branch.

- The mod's functional changes are: P2 shares P1's slot, a stamp of type=2 into player-3's slot (0x800B0108) for independent P2 control, viewport, and a campaign-load enable at 0x800229B4 that also bumps the player count to 2.
- The clearest data difference is the enemy's per-player AI struct (0x800F0E70 + slot*0x500): in co-op its unit-tracking list has ~10 records vs ~4 in vanilla, but I traced the code that adds them (0x8004AB20 / 0x8004B208) and it registers records keyed by unit type, so I believe that's a symptom of the busier co-op game, not the cause.

My working theory: The no-attack behavior is emergent from the 2-player context. Some timing/ordering difference in the scripted-wave path that doesn't reduce to a single flag or value I can find. But I'd love to be wrong, because that means it's fixable. Currently I'm stumped.

Questions:
1. Does anyone know how SC64's trigger engine handles AI Script/scripted attack activation, and whether the player count or the 2-player launch path changes when or whether that action fires? That's the piece I can't see cleanly.
2. Any docs on the runtime trigger/AI-script data layout in RAM (the trigger data lives around 0x800C0000) would help a lot.

I can share the full list of addresses, my debugger captures, RAM dumps (vanilla vs co-op on Desperate Alliance), and the BPS patch, or whatever's useful. Happy to do any tests someone wants to suggest. Thanks for reading, and thanks for keeping Starcraft alive <3

My mod: https://github.com/Tokatta007/Starcraft-64-Co-Op-Mod

Post has been edited 3 time(s), last time on 3 hours ago by tokatta007.



None.

1 hour ago Heinermann Post #2

memes memes memes memes memes memes memes memes memes memes memes memes memes memes memes memes memes memes memes memes memes memes memes memes memes

Starcraft 64 uses almost the same code as the PC ver, it is a true port as far as I could tell. I think maybe the patch turned a UMS (campaign) into a Team game. I think we did this as a hack on PC a long time ago too, but I don't remember what issues it caused if any.

Is the slot that P2 is using not overlapping with other in-game slots? Are they both marked as human-controlled in the same force? If one is marked as something else (i.e. computer/inactive) it might cause a problem. Of course, that's only if SC64 is handling it the same way it would on PC.

Quote
2. Any docs on the runtime trigger/AI-script data layout in RAM (the trigger data lives around 0x800C0000) would help a lot.
It depends on the ROM, I think? The addresses provided don't match the ROM I annotated. I don't know that triggers would impact it, and since Team UMS is not a valid game mode on PC unless hacked in I don't know how the AI interacts with it. I think it's strictly an AIScript issue or slot configuration issue, unless that mission specifically has a trigger that forces an attack wave.

I have only ported some symbols to SC64 to use as a reference for reverse engineering the PC ver. In the reverse engineering project, AI is by far the least understood and least labelled part of the source right now.

I plan to create a thread announcing the project Soon™ with crowdsourcing tasks for non-coders too, but I'd be happy to share stuff early. Let me know if you want source access & I can upload the IDA dbs separately. The IDB I labelled is for `StarCraft 64 (E) [f1] (NTSC).z64`, and the best labelled idb I have is 1.17 followed by MacOS's 1.16.1. If you don't have/use IDA I can dump the symbols into any format you want.

Some structs in SC64 are different i.e. in https://www.decomp.me/scratch/nolS6 (see Context tab) TRIGGERNODE has a pointer to the TRIGGER struct instead of a copy, to reduce memory usage on the N64. You can grab all the enums and related structs from that context tab.

After looking at Terran3 it does run Send All Units on Strategic Suicide Missions after 2 minutes, and runs Terran 3 - Zerg Town at the start.

I've got this for the send suicide opcode lol so not much info
Code
   case AIOPC_SEND_SUICIDE:
     {
       BYTE bSuicideType = aiscript_get_byte(pScp);
       aiscript_attack_clear(pScp->owner, TRUE);
       //sub_4B11B0(pScp->owner, bSuicideType);
       aiscript_quick_attack(pScp->owner, 5);  // TODO def
     }
     break;





Options
  Back to forum
Please log in to reply to this topic or to report it.
Members in this topic: None.
[02:59 am]
lifebot -- scrmaps.com Post Your Map
[02:34 am]
Symmetry -- Power to ya tokatta
[02:34 am]
Symmetry -- Jeez someone's modding SC64? I've never even hear of anyone trying
[02:27 am]
Symmetry -- if you're looking to upload a map put it on scmscx and link it here. the dldb is... inconsistent
[12:51 pm]
Zakerozi -- Lel... This guy is probably a Zoomer :D :D :D
[09:57 am]
NudeRaider -- dydwk474
dydwk474 shouted: HOW DO YOU EVEN UPLOAD FILE HERE THATS BULLCOWAP THE WEBSITE DUMB
mostly magic, but also doing a :wob:-raindance and sacrificing your firstborn. If that sounds like too much effort, just use www.scmscx.com
[09:55 am]
NudeRaider -- Vrael, did you rename your account?
[07:30 am]
dydwk474 -- HOW DO YOU EVEN UPLOAD FILE HERE THATS BULLCOWAP THE WEBSITE DUMB
[07:30 am]
dydwk474 -- WHAT
[2026-8-24. : 1:15 am]
Symmetry -- There are so many people here I'm surprised we're still online :hurr:
Please log in to shout.


Members Online: dydwk474, MobMob, Zycorax, Heinermann