• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.
  • Create a faction for Warcraft 3 and enter Hive's 19th Techtree Contest: Co-Op Commanders! Click here to enter!
  • Create a void inspired texture for Warcraft 3 and enter Hive's 34th Texturing Contest: Void! Click here to enter!
  • The Hive's 21st Texturing Contest: Upgrade is now concluded, time to vote for your favourite set of icons! Click here to vote!

[AI] Problems with Custom Campaign AI

Level 5
Joined
Oct 19, 2024
Messages
23
Hello! I have been trying to use Jass to make an AI for a Custom Campaign. However, once the level starts and the appropiate triggers are detonated, the computer does nothing?

Here is the code:

JASS:
//------------------------------------------------
//              GLOBALS
//------------------------------------------------

globals
    player user = PlayerEx(1)
    
endglobals

//------------------------------------------------
//              MAIN
//------------------------------------------------

function main takes nothing returns nothing
    call CampaignAI(ZIGGURAT_1, null)
    call DoCampaignFarms(true)
    
    call SetHeroesFlee(false)
    call SetGroupsFlee(false)
    call SetReplacements(1, 1, 1)
    call SetSlowChopping(true)
    call SetPeonsRepair(true)
    
    call SetBuildUnitEx(1, 1, 1, NECROPOLIS_2)
    call SetBuildUnitEx(1, 1, 1, UNDEAD_MINE)
    call SetBuildUnitEx(6, 6, 6, ACOLYTE)
    call SetBuildUnitEx(2, 2, 2, CRYPT)
    call SetBuildUnitEx(2, 2, 3, GHOUL)
    call SetBuildUnitEx(1, 1, 1, UNDEAD_ALTAR)
    call SetBuildUnitEx(1, 1, 1, DAMNED_TEMPLE)
    call SetBuildUnitEx(1, 1, 1, GRAVEYARD)
    call SetBuildUnitEx(6, 6, 7, ZIGGURAT_2)
    
    call CampaignDefenderEx(3, 3, 4, GHOUL)
    call CampaignDefenderEx(1, 1, 2, NECRO)
    call CampaignDefenderEx(1, 2, 2, CRYPT_FIEND)
    call CampaignDefenderEx(0, 1, 1, BANSHEE)
    
    call WaitForSignal()
    
    // WAVE 1
    
    call InitAssaultGroup()
    call CampaignAttackerEx(4, 4, 4, GHOUL)
    call SuicideOnPlayerEx(180, 180, 150, user)
    
    // WAVE 2
    
    call InitAssaultGroup()
    call CampaignAttackerEx(3, 3, 4, GHOUL)
    call CampaignAttackerEx(1, 1, 2, NECRO)
    call SuicideOnPlayerEx(180, 180, 180, user)
    
    // WAVE 3
    
    call InitAssaultGroup()
    call CampaignAttackerEx(4, 4, 5, GHOUL)
    call CampaignAttackerEx(1, 2, 2, CRYPT_FIEND)
    call SuicideOnPlayerEx(180, 180, 180, user)
    
    // WAVE 4
    
    call InitAssaultGroup()
    call CampaignAttackerEx(4, 4, 5, GHOUL)
    call CampaignAttackerEx(1, 1, 2, BANSHEE)
    call SuicideOnPlayerEx(180, 180, 180, user)
    
    // WAVE 5
    
    call InitAssaultGroup()
    call CampaignAttackerEx(3, 4, 4, GHOUL)
    call CampaignAttackerEx(1, 1, 2, NECRO)
    call CampaignAttackerEx(0, 1, 1, BANSHEE)
    call SuicideOnPlayerEx(180, 180, 180, user)
    
    loop
        
        // WAVE A
    
        call InitAssaultGroup()
        call CampaignAttackerEx(5, 5, 6, GHOUL)
        call CampaignAttackerEx(1, 1, 2, NECRO)
        call CampaignAttackerEx(0, 0, 1, MEAT_WAGON)
        call SuicideOnPlayerEx(180, 180, 180, user)
        
        // WAVE B
    
        call InitAssaultGroup()
        call CampaignAttackerEx(4, 4, 6, GHOUL)
        call CampaignAttackerEx(2, 2, 2, CRYPT_FIEND)
        call CampaignAttackerEx(1, 1, 1, BANSHEE)
        call SuicideOnPlayerEx(180, 180, 180, user)
        
        // WAVE C
    
        call InitAssaultGroup()
        call CampaignAttackerEx(7, 7, 9, GHOUL)
        call CampaignAttackerEx(0, 1, 2, CRYPT_FIEND)
        call CampaignAttackerEx(0, 0, 2, MEAT_WAGON)
        call SuicideOnPlayerEx(180, 180, 180, user)
        
        // WAVE D
    
        call InitAssaultGroup()
        call CampaignAttackerEx(4, 4, 4, GHOUL)
        call CampaignAttackerEx(0, 1, 2, CRYPT_FIEND)
        call CampaignAttackerEx(1, 2, 2, NECRO)
        call CampaignAttackerEx(0, 1, 1, BANSHEE)
        call SuicideOnPlayerEx(180, 180, 180, user)        
        
    endloop
endfunction

Now, I had a similar issue in the past, which was due to a Syntax Error. However, I've run this code over the few Syntax Checkers I managed to get working, and they didn't report anything out of the ordinary. Could someone please tell me where the mistake is?
 
Level 32
Joined
Aug 29, 2012
Messages
1,477
You may want to specify this for their workers (whatever values fit your map)

JASS:
set campaign_gold_peons = 5
set campaign_wood_peons = 4

"DoCampaignFarms" I don't think I've ever seen used, although Blizzard does this:

JASS:
set do_campaign_farms = true

I'm not sure about PlayerEx(1), have you tried Player(1)? Also remember that Player 1 in the script = Player 2 in the editor.
Finally, do you send a command so that it can respond to WaitForSignal()?
 
Level 5
Joined
Oct 19, 2024
Messages
23
So, after trying the suggestions, the script doesn't still doesn't work.

JASS:
//------------------------------------------------
//              GLOBALS
//------------------------------------------------

globals
    player user = Player(0)
    
endglobals

//------------------------------------------------
//              MAIN
//------------------------------------------------

function main takes nothing returns nothing

    call CampaignAI(ZIGGURAT_1, null)
    set do_campaign_farms = true
    
    call SetHeroesFlee(false)
    call SetGroupsFlee(false)
    call SetReplacements(1, 1, 1)
    call SetSlowChopping(true)
    call SetPeonsRepair(true)
    
    set campaign_gold_peons = 5
    set campaign_wood_peons = 4
        
    call SetBuildUnitEx(1, 1, 1, NECROPOLIS_2)
    call SetBuildUnitEx(1, 1, 1, UNDEAD_MINE)
    call SetBuildUnitEx(6, 6, 6, ACOLYTE)
    call SetBuildUnitEx(2, 2, 2, CRYPT)
    call SetBuildUnitEx(2, 2, 3, GHOUL)
    call SetBuildUnitEx(1, 1, 1, UNDEAD_ALTAR)
    call SetBuildUnitEx(1, 1, 1, DAMNED_TEMPLE)
    call SetBuildUnitEx(1, 1, 1, GRAVEYARD)
    call SetBuildUnitEx(6, 6, 7, ZIGGURAT_2)
    
    call CampaignDefenderEx(3, 3, 4, GHOUL)
    call CampaignDefenderEx(1, 1, 2, NECRO)
    call CampaignDefenderEx(1, 2, 2, CRYPT_FIEND)
    call CampaignDefenderEx(0, 1, 1, BANSHEE)
    
    call WaitForSignal()
    
    // WAVE 1
    
    call InitAssaultGroup()
    call CampaignAttackerEx(4, 4, 4, GHOUL)
    call SuicideOnPlayerEx(180, 180, 150, user)
    
    // WAVE 2
    
    call InitAssaultGroup()
    call CampaignAttackerEx(3, 3, 4, GHOUL)
    call CampaignAttackerEx(1, 1, 2, NECRO)
    call SuicideOnPlayerEx(180, 180, 180, user)
    
    // WAVE 3
    
    call InitAssaultGroup()
    call CampaignAttackerEx(4, 4, 5, GHOUL)
    call CampaignAttackerEx(1, 2, 2, CRYPT_FIEND)
    call SuicideOnPlayerEx(180, 180, 180, user)
    
    // WAVE 4
    
    call InitAssaultGroup()
    call CampaignAttackerEx(4, 4, 5, GHOUL)
    call CampaignAttackerEx(1, 1, 2, BANSHEE)
    call SuicideOnPlayerEx(180, 180, 180, user)
    
    // WAVE 5
    
    call InitAssaultGroup()
    call CampaignAttackerEx(3, 4, 4, GHOUL)
    call CampaignAttackerEx(1, 1, 2, NECRO)
    call CampaignAttackerEx(0, 1, 1, BANSHEE)
    call SuicideOnPlayerEx(180, 180, 180, user)
    
    loop
        
        // WAVE A
    
        call InitAssaultGroup()
        call CampaignAttackerEx(5, 5, 6, GHOUL)
        call CampaignAttackerEx(1, 1, 2, NECRO)
        call CampaignAttackerEx(0, 0, 1, MEAT_WAGON)
        call SuicideOnPlayerEx(180, 180, 180, user)
        
        // WAVE B
    
        call InitAssaultGroup()
        call CampaignAttackerEx(4, 4, 6, GHOUL)
        call CampaignAttackerEx(2, 2, 2, CRYPT_FIEND)
        call CampaignAttackerEx(1, 1, 1, BANSHEE)
        call SuicideOnPlayerEx(180, 180, 180, user)
        
        // WAVE C
    
        call InitAssaultGroup()
        call CampaignAttackerEx(7, 7, 9, GHOUL)
        call CampaignAttackerEx(0, 1, 2, CRYPT_FIEND)
        call CampaignAttackerEx(0, 0, 2, MEAT_WAGON)
        call SuicideOnPlayerEx(180, 180, 180, user)
        
        // WAVE D
    
        call InitAssaultGroup()
        call CampaignAttackerEx(4, 4, 4, GHOUL)
        call CampaignAttackerEx(0, 1, 2, CRYPT_FIEND)
        call CampaignAttackerEx(1, 2, 2, NECRO)
        call CampaignAttackerEx(0, 1, 1, BANSHEE)
        call SuicideOnPlayerEx(180, 180, 180, user)        
        
    endloop
endfunction

The weird thing about this, though, is that a code nearly identical to the original one does work on a normal non-campaign map, so I'm not really sure of what's happening here.

As for the triggers, both seem to be working properly: The AI is loaded in with the player's resources, and the signal is sent when the heroes are loaded in; which as far as I can tell, are running without an issue.

As for what it does... well, nothing! The acolytes don't harves the mine, the ghouls don't chop trees, and it doesn't train anything: Nor garrison nor attack waves.
 
Level 5
Joined
Oct 19, 2024
Messages
23
Well, but that's the issue. All those variables and functions, as far as I am aware, are pre-defined in JassCraft, so they shouldn't be giving trouble. Now, JassCraft's own Syntax Checker (F9) tells me none of those functions are defined... but it says the same thing for a Script that does work correctly, so I don't know what I'm doing wrong here.
 
Level 32
Joined
Aug 29, 2012
Messages
1,477
If you look at Blizzard AI for Undead, they do this
JASS:
    call SetBuildUnitEx( 1,1,1, ACOLYTE           )
    call SetBuildUnitEx( 0,0,1, NECROPOLIS_1      )
    call SetBuildUnitEx( 0,0,1, CRYPT             )
    call SetBuildUnitEx( 0,0,1, GRAVEYARD         )
    // etc

Notice the 1 acolyte before the town hall, maybe that makes a difference. Also I've just noticed that you order to build a NECROPOLIS_2 but no sign of NECROPOLIS_1, it could be that the AI is stuck at this very point because of the missing link
 
Level 5
Joined
Oct 19, 2024
Messages
23
Okay, so I've tried the proposed solutions... and it still does nothing! I've checked the triggers three times over, tried moving the Actions around a little... and still nothing. I've also applied the corrections of the buildings, but it doesn't work.

I also tried the script in a normal, non-campaing map... and it works! The acolytes start harvesting gold, they start to summon buildings... so I must be importing the AI wrong somehow. Is there anything to be taken into consideration when importing and running an AI script in a campaing?
 
Level 32
Joined
Aug 29, 2012
Messages
1,477
Well at least the script per se seems to work, that's good news, now to find what's wrong in the map...

Do you apply the AI at map init? After a few seconds? Do you use "pause all units" in a trigger? I've noticed that this tends to break the AI (but picking individual units and pausing them doesn't)
 
Top