• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Solved] TD Creep Spawn via Ability - problem with lag

Status
Not open for further replies.
Level 3
Joined
Jan 3, 2019
Messages
15
Hi!

The map is a TD where each induvidual player spawn its own wave by using an ability in the players "builder unit". I think there's some problem when many players uses his/her ability at the same time.

The problem is that when playing the map online, spawning gets buggy, it's supposed to spawn 25 or 50 units (depending on level) but it seems like it's random every time. Sometimes 18, sometimes 28 etc. (It works great offline, spawning all 50 with no problem)

At first, I thought it was because of it being the same ability, so I made 9 separate abilities so that each player has their own unique ability id. That did not solve the problem... I have also tried splitting the trigger into 9 of the same but each trigger only responding to the specific player that casts ability. This resulted in the exact same thing, same problem.

Please help!

This is the trigger:

  • Spawn Level
    • Events
      • Unit - A unit Finishes casting an ability
    • Conditions
      • (Ability being cast) Equal to GoSpawn[(Player number of (Owner of (Triggering unit)))]
    • Actions
      • Set Level[(Player number of (Owner of (Triggering unit)))] = (Level[(Player number of (Owner of (Triggering unit)))] + 1)
      • Leaderboard - Change the label for (Owner of (Triggering unit)) in LEADERBOARD to ((Name of (Owner of (Triggering unit))) + ( |c00ffffff@lvl:|r |c00FFFF00 + (String(Level[(Player number of (Owner of (Triggering unit)))]))))
      • Unit - Set Max Mana of (Random unit from (Units owned by (Owner of (Triggering unit)) of type |cFFFF0000Summoner|r)) to 0
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Level[(Player number of (Owner of (Triggering unit)))] Equal to 10) or ((Level[(Player number of (Owner of (Triggering unit)))] Equal to 17) or (Level[(Player number of (Owner of (Triggering unit)))] Equal to 20))
        • Then - Actions
          • Set Points[(Player number of (Owner of (Triggering unit)))] = (Center of TempLoc[(Player number of (Owner of (Triggering unit)))])
          • Unit - Create 1 MonsterType[Level[(Player number of (Owner of (Triggering unit)))]] for Player 12 (Brown) at Points[(Player number of (Owner of (Triggering unit)))] facing Default building facing degrees
          • Custom script: call RemoveLocation(udg_Points[GetConvertedPlayerId(GetOwningPlayer(GetTriggerUnit()))])
          • Set LastCUnit[(Player number of (Owner of (Triggering unit)))] = (Last created unit)
          • Set TempMovePoint1[(Player number of (Owner of (Triggering unit)))] = (Center of MovePoint1[(Player number of (Owner of (Triggering unit)))])
          • Unit - Order LastCUnit[(Player number of (Owner of (Triggering unit)))] to Move To TempMovePoint1[(Player number of (Owner of (Triggering unit)))]
          • Custom script: call RemoveLocation(udg_TempMovePoint1[GetConvertedPlayerId(GetOwningPlayer(GetTriggerUnit()))])
          • Game - Display to (All players) for 5.00 seconds the text: ((Spawning level: |c00FFFF00 + (String(Level[(Player number of (Owner of (Triggering unit)))]))) + (|r - + ((Name of LastCUnit[(Player number of (Owner of (Triggering unit)))]) + (( for + pc[(Player number of (Owner of (Triggering unit)))]) + ((Name of (Own
          • For each (Integer A) from 1 to 25, do (Actions)
            • Loop - Actions
              • If ((Number of units in (Units in PlayerArea[(Player number of (Owner of (Triggering unit)))] owned by Player 12 (Brown))) Greater than 4) then do (Wait until ((Number of units in (Units in PlayerArea[(Player number of (Owner of (Triggering unit)))] owned by Player 12 (Brown))) Less than 5), checking every 0.10 seconds) else do (Do nothing)
              • If (PlayerChances[(Player number of (Owner of (Triggering unit)))] Less than or equal to 0) then do (Skip remaining actions) else do (Wait 3.00 game-time seconds)
              • Set Points[(Player number of (Owner of (Triggering unit)))] = (Center of TempLoc[(Player number of (Owner of (Triggering unit)))])
              • Unit - Create 1 MonsterType[Level[(Player number of (Owner of (Triggering unit)))]] for Player 12 (Brown) at Points[(Player number of (Owner of (Triggering unit)))] facing Default building facing degrees
              • Custom script: call RemoveLocation(udg_Points[GetConvertedPlayerId(GetOwningPlayer(GetTriggerUnit()))])
              • Set LastCUnit[(Player number of (Owner of (Triggering unit)))] = (Last created unit)
              • Set TempMovePoint1[(Player number of (Owner of (Triggering unit)))] = (Center of MovePoint1[(Player number of (Owner of (Triggering unit)))])
              • Unit - Order LastCUnit[(Player number of (Owner of (Triggering unit)))] to Move To TempMovePoint1[(Player number of (Owner of (Triggering unit)))]
              • Custom script: call RemoveLocation(udg_TempMovePoint1[GetConvertedPlayerId(GetOwningPlayer(GetTriggerUnit()))])
          • Unit - Set Max Mana of (Random unit from (Units owned by (Owner of (Triggering unit)) of type |cFFFF0000Summoner|r)) to 10
        • Else - Actions
          • Set Points[(Player number of (Owner of (Triggering unit)))] = (Center of TempLoc[(Player number of (Owner of (Triggering unit)))])
          • Unit - Create 1 MonsterType[Level[(Player number of (Owner of (Triggering unit)))]] for Player 12 (Brown) at Points[(Player number of (Owner of (Triggering unit)))] facing Default building facing degrees
          • Custom script: call RemoveLocation(udg_Points[GetConvertedPlayerId(GetOwningPlayer(GetTriggerUnit()))])
          • Set LastCUnit[(Player number of (Owner of (Triggering unit)))] = (Last created unit)
          • Set TempMovePoint1[(Player number of (Owner of (Triggering unit)))] = (Center of MovePoint1[(Player number of (Owner of (Triggering unit)))])
          • Unit - Order LastCUnit[(Player number of (Owner of (Triggering unit)))] to Move To TempMovePoint1[(Player number of (Owner of (Triggering unit)))]
          • Custom script: call RemoveLocation(udg_TempMovePoint1[GetConvertedPlayerId(GetOwningPlayer(GetTriggerUnit()))])
          • Game - Display to (All players) for 5.00 seconds the text: ((Spawning level: |c00FFFF00 + (String(Level[(Player number of (Owner of (Triggering unit)))]))) + (|r - + ((Name of LastCUnit[(Player number of (Owner of (Triggering unit)))]) + (( for + pc[(Player number of (Owner of (Triggering unit)))]) + ((Name of (Own
          • For each (Integer A) from 1 to 50, do (Actions)
            • Loop - Actions
              • If ((Number of units in (Units in PlayerArea[(Player number of (Owner of (Triggering unit)))] owned by Player 12 (Brown))) Greater than 7) then do (Wait until ((Number of units in (Units in PlayerArea[(Player number of (Owner of (Triggering unit)))] owned by Player 12 (Brown))) Less than 8), checking every 0.10 seconds) else do (Do nothing)
              • If (PlayerChances[(Player number of (Owner of (Triggering unit)))] Less than or equal to 0) then do (Skip remaining actions) else do (Wait 0.30 game-time seconds)
              • Set Points[(Player number of (Owner of (Triggering unit)))] = (Center of TempLoc[(Player number of (Owner of (Triggering unit)))])
              • Unit - Create 1 MonsterType[Level[(Player number of (Owner of (Triggering unit)))]] for Player 12 (Brown) at Points[(Player number of (Owner of (Triggering unit)))] facing Default building facing degrees
              • Custom script: call RemoveLocation(udg_Points[GetConvertedPlayerId(GetOwningPlayer(GetTriggerUnit()))])
              • Set LastCUnit[(Player number of (Owner of (Triggering unit)))] = (Last created unit)
              • Set TempMovePoint1[(Player number of (Owner of (Triggering unit)))] = (Center of MovePoint1[(Player number of (Owner of (Triggering unit)))])
              • Unit - Order LastCUnit[(Player number of (Owner of (Triggering unit)))] to Move To TempMovePoint1[(Player number of (Owner of (Triggering unit)))]
              • Custom script: call RemoveLocation(udg_TempMovePoint1[GetConvertedPlayerId(GetOwningPlayer(GetTriggerUnit()))])
          • Unit - Set Max Mana of (Random unit from (Units owned by (Owner of (Triggering unit)) of type |cFFFF0000Summoner|r)) to 10
Pathing 1 red
  • red 1
    • Events
      • Unit - A unit enters red1 <gen>
    • Conditions
      • (Owner of (Entering unit)) Equal to Player 12 (Brown)
    • Actions
      • Set RedMovePoints[2] = (Center of MovePoint2[1])
      • Unit - Order (Entering unit) to Move To RedMovePoints[2]
      • Custom script: call RemoveLocation(udg_RedMovePoints[2])
Pathing 2 red
  • red 2
    • Events
      • Unit - A unit enters red2 <gen>
    • Conditions
      • (Owner of (Entering unit)) Equal to Player 12 (Brown)
    • Actions
      • Set RedMovePoints[3] = (Center of MovePoint3[1])
      • Unit - Order (Entering unit) to Move To RedMovePoints[3]
      • Custom script: call RemoveLocation(udg_RedMovePoints[3])
Pathing 3 red
  • red 3
    • Events
      • Unit - A unit enters red3 <gen>
    • Conditions
      • (Owner of (Entering unit)) Equal to Player 12 (Brown)
    • Actions
      • Set RedMovePoints[4] = (Center of MovePoint4[1])
      • Unit - Order (Entering unit) to Move To RedMovePoints[4]
      • Custom script: call RemoveLocation(udg_RedMovePoints[4])
Pathing 4 red
  • red 4 to end
    • Events
      • Unit - A unit enters red4 <gen>
    • Conditions
      • (Owner of (Entering unit)) Equal to Player 12 (Brown)
    • Actions
      • Set RedMovePoints[5] = (Center of MovePoint5[1])
      • Unit - Order (Entering unit) to Move To RedMovePoints[5]
      • Custom script: call RemoveLocation(udg_RedMovePoints[5])
If you see anything obvious I would be grateful for some help!

Edit: I think solving my problem involves Local Variables, will try to read up on this. Help still appreciated!
 
Last edited:
you use wait inside for Loop A.
That will break if it runs multiple times at once, cause each execution increases thze for loop counter at the same time resulting into skipped loop steps for all currently running instances of that trigger.

  1. You could outsource the spawning into another trigger that runs every x seconds. Each player has an spawn counter, every intervale spawn an unit until the players counter drops to 0. If all units are spawned disable the periodic trigger.
  2. Cause you don't use For Loop A inside any action / condition you also could make LoopA a local variable for this trigger only, then each execution has its own counter. That is done by adding following line with custom script as first action to that trigger.
  • local integer bj_forLoopAIndex
 
Last edited:
Level 3
Joined
Jan 3, 2019
Messages
15
you use wait inside for Loop A.
That will break if it runs multiple times at once, cause each execution increases thze for loop counter at the same time resulting into skipped loop steps for all currently running instances of that trigger.

  1. You could outsource the spawning into another trigger that runs every x seconds. Each player has an spawn counter, every intervale spawn an unit until the players counter drops to 0. If all units are spawned disable the periodic trigger.
  2. Cause you don't use For Loop A inside any action / condition you also could make LoopA a local variable for this trigger only, then each execution has its own counter. That is done by adding following line with custom script as first action to that trigger.
  • local integer bj_forLoopAIndex

Thanks for your response!

I had tried with local unit for triggering unit, but it only lets red player cast spawn ability now, nothing happens when other players use their ability. So its a new problem hehe, but I added the custom script local integer bj_forLoopAIndex too but still the same problem with only red being able to cast the spawn ability.

This is how it looks now:

  • Spawn Level
    • Events
      • Unit - A unit Finishes casting an ability
    • Conditions
      • (Ability being cast) Equal to GoSpawn[(Player number of (Owner of TriggeringUnit))]
    • Actions
      • Custom script: local unit udg_TriggeringUnit
      • Custom script: local integer bj_forLoopAIndex
      • Set TriggeringUnit = (Triggering unit)
      • Set Level[(Player number of (Owner of TriggeringUnit))] = (Level[(Player number of (Owner of TriggeringUnit))] + 1)
      • Leaderboard - Change the label for (Owner of TriggeringUnit) in LEADERBOARD to ((Name of (Owner of TriggeringUnit)) + ( |c00ffffff@lvl:|r |c00FFFF00 + (String(Level[(Player number of (Owner of TriggeringUnit))]))))
      • Unit - Set Max Mana of (Random unit from (Units owned by (Owner of TriggeringUnit) of type |cFFFF0000Summoner|r)) to 0
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Level[(Player number of (Owner of TriggeringUnit))] Equal to 10) or ((Level[(Player number of (Owner of TriggeringUnit))] Equal to 17) or (Level[(Player number of (Owner of TriggeringUnit))] Equal to 20))
        • Then - Actions
          • Set Points[(Player number of (Owner of TriggeringUnit))] = (Center of TempLoc[(Player number of (Owner of TriggeringUnit))])
          • Unit - Create 1 MonsterType[Level[(Player number of (Owner of TriggeringUnit))]] for Player 12 (Brown) at Points[(Player number of (Owner of TriggeringUnit))] facing Default building facing degrees
          • Custom script: call RemoveLocation(udg_Points[GetConvertedPlayerId(GetOwningPlayer(udg_TriggeringUnit))])
          • Set LastCUnit[(Player number of (Owner of TriggeringUnit))] = (Last created unit)
          • Set TempMovePoint1[(Player number of (Owner of TriggeringUnit))] = (Center of MovePoint1[(Player number of (Owner of TriggeringUnit))])
          • Unit - Order LastCUnit[(Player number of (Owner of TriggeringUnit))] to Move To TempMovePoint1[(Player number of (Owner of TriggeringUnit))]
          • Custom script: call RemoveLocation(udg_TempMovePoint1[GetConvertedPlayerId(GetOwningPlayer(udg_TriggeringUnit))])
          • Game - Display to (All players) for 5.00 seconds the text: ((Spawning level: |c00FFFF00 + (String(Level[(Player number of (Owner of TriggeringUnit))]))) + (|r - + ((Name of LastCUnit[(Player number of (Owner of TriggeringUnit))]) + (( for + pc[(Player number of (Owner of TriggeringUnit))]) + ((Name of (Owner of Tri
          • For each (Integer A) from 1 to 25, do (Actions)
            • Loop - Actions
              • If ((Number of units in (Units in PlayerArea[(Player number of (Owner of TriggeringUnit))] owned by Player 12 (Brown))) Greater than 4) then do (Wait until ((Number of units in (Units in PlayerArea[(Player number of (Owner of TriggeringUnit))] owned by Player 12 (Brown))) Less than 5), checking every 0.10 seconds) else do (Do nothing)
              • If (PlayerChances[(Player number of (Owner of TriggeringUnit))] Less than or equal to 0) then do (Skip remaining actions) else do (Wait 3.00 game-time seconds)
              • Set Points[(Player number of (Owner of TriggeringUnit))] = (Center of TempLoc[(Player number of (Owner of TriggeringUnit))])
              • Unit - Create 1 MonsterType[Level[(Player number of (Owner of TriggeringUnit))]] for Player 12 (Brown) at Points[(Player number of (Owner of TriggeringUnit))] facing Default building facing degrees
              • Custom script: call RemoveLocation(udg_Points[GetConvertedPlayerId(GetOwningPlayer(udg_TriggeringUnit))])
              • Set LastCUnit[(Player number of (Owner of TriggeringUnit))] = (Last created unit)
              • Set TempMovePoint1[(Player number of (Owner of TriggeringUnit))] = (Center of MovePoint1[(Player number of (Owner of TriggeringUnit))])
              • Unit - Order LastCUnit[(Player number of (Owner of TriggeringUnit))] to Move To TempMovePoint1[(Player number of (Owner of TriggeringUnit))]
              • Custom script: call RemoveLocation(udg_TempMovePoint1[GetConvertedPlayerId(GetOwningPlayer(udg_TriggeringUnit))])
          • Unit - Set Max Mana of (Random unit from (Units owned by (Owner of TriggeringUnit) of type |cFFFF0000Summoner|r)) to 10
        • Else - Actions
          • Set Points[(Player number of (Owner of TriggeringUnit))] = (Center of TempLoc[(Player number of (Owner of TriggeringUnit))])
          • Unit - Create 1 MonsterType[Level[(Player number of (Owner of TriggeringUnit))]] for Player 12 (Brown) at Points[(Player number of (Owner of TriggeringUnit))] facing Default building facing degrees
          • Custom script: call RemoveLocation(udg_Points[GetConvertedPlayerId(GetOwningPlayer(udg_TriggeringUnit))])
          • Set LastCUnit[(Player number of (Owner of TriggeringUnit))] = (Last created unit)
          • Set TempMovePoint1[(Player number of (Owner of TriggeringUnit))] = (Center of MovePoint1[(Player number of (Owner of TriggeringUnit))])
          • Unit - Order LastCUnit[(Player number of (Owner of TriggeringUnit))] to Move To TempMovePoint1[(Player number of (Owner of TriggeringUnit))]
          • Custom script: call RemoveLocation(udg_TempMovePoint1[GetConvertedPlayerId(GetOwningPlayer(udg_TriggeringUnit))])
          • Game - Display to (All players) for 5.00 seconds the text: ((Spawning level: |c00FFFF00 + (String(Level[(Player number of (Owner of TriggeringUnit))]))) + (|r - + ((Name of LastCUnit[(Player number of (Owner of TriggeringUnit))]) + (( for + pc[(Player number of (Owner of TriggeringUnit))]) + ((Name of (Owner of Tri
          • For each (Integer A) from 1 to 50, do (Actions)
            • Loop - Actions
              • If ((Number of units in (Units in PlayerArea[(Player number of (Owner of TriggeringUnit))] owned by Player 12 (Brown))) Greater than 7) then do (Wait until ((Number of units in (Units in PlayerArea[(Player number of (Owner of TriggeringUnit))] owned by Player 12 (Brown))) Less than 8), checking every 0.10 seconds) else do (Do nothing)
              • If (PlayerChances[(Player number of (Owner of TriggeringUnit))] Less than or equal to 0) then do (Skip remaining actions) else do (Wait 0.30 game-time seconds)
              • Set Points[(Player number of (Owner of TriggeringUnit))] = (Center of TempLoc[(Player number of (Owner of TriggeringUnit))])
              • Unit - Create 1 MonsterType[Level[(Player number of (Owner of TriggeringUnit))]] for Player 12 (Brown) at Points[(Player number of (Owner of TriggeringUnit))] facing Default building facing degrees
              • Custom script: call RemoveLocation(udg_Points[GetConvertedPlayerId(GetOwningPlayer(udg_TriggeringUnit))])
              • Set LastCUnit[(Player number of (Owner of TriggeringUnit))] = (Last created unit)
              • Set TempMovePoint1[(Player number of (Owner of TriggeringUnit))] = (Center of MovePoint1[(Player number of (Owner of TriggeringUnit))])
              • Unit - Order LastCUnit[(Player number of (Owner of TriggeringUnit))] to Move To TempMovePoint1[(Player number of (Owner of TriggeringUnit))]
              • Custom script: call RemoveLocation(udg_TempMovePoint1[GetConvertedPlayerId(GetOwningPlayer(udg_TriggeringUnit))])
          • Unit - Set Max Mana of (Random unit from (Units owned by (Owner of TriggeringUnit) of type |cFFFF0000Summoner|r)) to 10
Did I mess up with the custom script local unit? Maybe I should revert it and only use your suggestion: local integer bj_forLoopAIndex?

Thanks!
 
Level 3
Joined
Jan 3, 2019
Messages
15
Don't use locals inside gui conditions/if-conditions it fails.
the default triggering unit is save over waits. The problem is/was that the same Integer A is written & read by all running casts.
Does it not work without using that triggering unit variable.

Ok, tested online and it works without triggering unit variable!!

I also added this: local integer bj_forLoopAIndexEnd

Thanks alot Tasyen!
 
Level 3
Joined
Jan 3, 2019
Messages
15
Ok, I decided to create a spawn trigger for each player instead, my all in 1 trigger dreams ends now! :(

This is how I made it instead if anyone is interested:

  • Go
    • Events
      • Unit - A unit Finishes casting an ability
    • Conditions
    • Actions
      • Set pn = (Player number of (Owner of (Triggering unit)))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Ability being cast) Equal to GoSpawn[pn]
          • PlayerChances[pn] Greater than or equal to 1
          • Level[pn] Less than or equal to 41
        • Then - Actions
          • Set Level[pn] = (Level[pn] + 1)
          • Multiboard - Set the text for mb item in column 3, row (pn + 1) to (String(Level[pn]))
          • Multiboard - Set the icon for mb item in column 3, row (pn + 1) to MonsterIcons[Level[pn]]
          • Unit - For Yoshi[pn], Ability GoSpawn[pn], Disable ability: True, Hide UI: False
          • Game - Display to (All players) the text: (Spawning level + (gc + ((String(Level[pn])) + (|r: + (LevelNames[Level[pn]] + (|r for + (pc[pn] + ((Name of (Player(pn))) + |r!))))))))
          • Trigger - Run Spawn[pn] (checking conditions)
        • Else - Actions
  • SpawnRed
    • Events
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • CreepAmount[1] Less than or equal to 49
          • PlayerChances[1] Greater than or equal to 1
        • Then - Actions
          • Set Points[1] = (Center of TempLoc[1])
          • Unit - Create 1 MonsterType[Level[1]] for Player 12 (Brown) at Points[1] facing Default building facing degrees
          • Custom script: call RemoveLocation(udg_Points[1])
          • Set CreepAmount[1] = (CreepAmount[1] + 1)
          • Set LastCUnit[1] = (Last created unit)
          • Set TempMovePoint1[1] = (Center of MovePoint1[1])
          • Unit - Order LastCUnit[1] to Move To TempMovePoint1[1]
          • Custom script: call RemoveLocation(udg_TempMovePoint1[1])
          • If ((Number of units in (Units in PlayerArea[1] owned by Player 12 (Brown))) Greater than 7) then do (Wait until ((Number of units in (Units in PlayerArea[1] owned by Player 12 (Brown))) Less than 8), checking every 0.10 seconds) else do (Wait 0.30 seconds)
          • Trigger - Run (This trigger) (checking conditions)
        • Else - Actions
          • Set CreepAmount[1] = 0
          • Unit - For Yoshi[1], Ability GoSpawn[1], Disable ability: False, Hide UI: False
 
Last edited:
Status
Not open for further replies.
Top