• 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.

Question regarding trigger-based AI

Level 9
Joined
Mar 17, 2016
Messages
151
Hi all,

I am wondering if there is a better way to make a sort of "pseudo AI" for my map. Imagine that there are players surviving against computer units, and I want the computer units to simply attack move to the player positions. I know a very basic way of doing it, but am curious if there's a better more seamless way that will feel better in game than the simple way like this:
  • AttackMove
    • Events
      • Time - Every 2.50 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in (Random 1 units from GladiatorUnitGroup) and do (Actions)
        • Loop - Actions
          • Set VariableSet Spawn_TargetUnitPoint = (Position of (Picked unit))
      • Unit Group - Pick every unit in SpawnedUnitGroup and do (Actions)
        • Loop - Actions
          • Unit - Order (Picked unit) to Attack-Move To (Center of (Playable map area))
      • Custom script: call RemoveLocation(udg_Spawn_TargetUnitPoint)


So basically that's my question, is there a better way of doing this trigger that would have a better "in game feeling"? Or is it just this simple and would just need tweaks. My idea here is to just have a high Acquisition Range on the computer units so that one player if alone wont get randomly swarmed if other players are already in combat or nearby, but I feel like its too basic and could easily be better.
Any help is appreciated!
 
It's a good start! At an essence, most wc3 AI's behave similar to that--there is some "loop" that is continuously feeding them commands and the AI works toward particular "goals" (e.g. destroy the enemy base, to kill a gladiator, etc.).

In your case, it seems like you have a gladiator-like map where units get spawned and continuously get sent after the players. Looking at the code, I'm guessing you have one group that tracks all your spawned units and you send them to attack a random player hero. It depends on your map, but I could see that behaving a bit weirdly in some cases (e.g. after 2.5 seconds they go to player 1, and then after 2.5 seconds they change their mind to go after player 2). If the players are far away enough from each other, this could lead to some weird flip-flopping that looks a bit unnatural (and ultimately swarms a single player). (also, just as a note, the trigger you posted looks like it sends the enemy to "Center of (Playable map area)"--but I assume you meant to send them after Spawn_TargetUnitPoint)

So I'd suggest a few improvements to your system:
  1. Instead of having all the spawned units go after a single target, it might make sense to assign a group of spawned units to attack a particular gladiator. This might mean you'll need an array of groups instead of just one, and you might need to track a little extra info for each one (e.g. for each group you'll want to track their assigned target so they don't flip-flop around). The logic will probably get a fair bit more complex, but it'd avoid that swarming problem!
  2. Another thing to help prevent a player getting randomly swarmed--instead of choosing a random gladiator each time, you could adjust your triggers so each wave will be assigned to a separate (random) gladiator before choosing the same gladiator again. One simple way to do this is to keep two groups: one that stores all your gladiators (GladiatorUnitGroup) and then one that just stores the "next units to attack" (GladiatorsToAttack). Then you could decide who a wave should attack when the wave gets spawned. It'd basically be something like--"if GladiatorsToAttack is empty, then fill it up with GladiatorUnitGroup. Then pick a random unit from GladiatorsToAttack (to be the target), and remove it from GladiatorsToAttack". That way you'll still get random results, but you won't end up with one person being targeted three times in a row.
  3. To make the enemy attack more realistically, it might make sense to use "Unit Group - Issue Order Targeting a Point" instead of "Pick every... Unit - Order (Picked unit) to...". By using the unit group version of that action, you'll order the whole group to attack-move--and they'll move together as a unit (similar to a regular group you'd order in wc3). That way they'll keep a formation. Just note that the unit group orders are limited to up to 12 units.
I'll attach a sample map that has some of the things mentioned above if you're curious! Waves will get spawned every 10 seconds to attack a random hero. Roughly, it is broken up into three components:
  1. Triggers to handle spawning the waves and tracking them for subsequent commands ("Spawning" folder)
  2. Triggers to decide which gladiator to attack ("AI" folder)
  3. Triggers to periodically issue commands ("AI/Commands" folder)
But this is just an example so it may be a bit rough around the edges. Hopefully it gives you some ideas!
 

Attachments

  • GladiatorSample.w3m
    47.1 KB · Views: 1
Level 9
Joined
Mar 17, 2016
Messages
151
Thank you 1000x, you are legendary! I'll take a look at this as soon as I get some time.

(Also you're right about the attack order, it's meant to be at the point that's set. I guess I didn't set it up properly before posting.)
 
Top