• 🏆 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!

My game crashes others in multiplayer, before the loadcreen :(

Status
Not open for further replies.
Level 5
Joined
Aug 8, 2012
Messages
154
Hey there!

I have been working on a survival map with zombies, blah blah, the usual...

However, when I test the map with my friends over LAN, as soon as the game starts (before the loading screen) my friends disconnect and their games crash, whereas mine is fine.

I have an inkling that this has something to do with a GetLocalPlayer() action I have, due to my attempts to have player specific multiboard readings.

Here are the triggers involving the LocalPlayer:


  • Create Multiboard
    • Events
      • Time - Elapsed game time is 1.00 seconds
    • Conditions
    • Actions
      • Custom script: set udg_LocalPlayer = GetLocalPlayer()
      • Multiboard - Create a multiboard with 2 columns and 4 rows, titled WarZ Killboard
      • Multiboard - Set the text for (Last created multiboard) item in column 1, row 1 to Z-Kills:
      • Multiboard - Set the text for (Last created multiboard) item in column 1, row 2 to Murders:
      • Multiboard - Set the text for (Last created multiboard) item in column 1, row 3 to Deaths:
      • Multiboard - Set the text for (Last created multiboard) item in column 1, row 4 to Blood:
      • For each (Integer A) from 1 to 5, do (Actions)
        • Loop - Actions
          • Multiboard - Set the display style for (Last created multiboard) item in column 1, row (Integer A) to Show text and Hide icons
          • Multiboard - Set the display style for (Last created multiboard) item in column 2, row (Integer A) to Show text and Hide icons
          • Multiboard - Set the display style for (Last created multiboard) item in column 3, row (Integer A) to Show text and Hide icons
          • Multiboard - Set the display style for (Last created multiboard) item in column 4, row (Integer A) to Show text and Hide icons
          • Multiboard - Set the width for (Last created multiboard) item in column 1, row (Integer A) to 4.00% of the total screen width
          • Multiboard - Set the width for (Last created multiboard) item in column 2, row (Integer A) to 2.00% of the total screen width
      • For each (Integer A) from 1 to 4, do (Actions)
        • Loop - Actions
          • Multiboard - Set the color for (Last created multiboard) item in column 1, row (Integer A) to (100.00%, 100.00%, 0.00%) with 0.00% transparency
      • For each (Integer A) from 2 to 5, do (Actions)
        • Loop - Actions
      • Custom script: set udg_LocalPlayer = null
      • Multiboard - Show (Last created multiboard)

  • checking
    • Events
      • Time - Every 0.20 seconds of game time
    • Conditions
    • Actions
      • Multiboard - Set the text for (Last created multiboard) item in column 2, row 1 to (String(PlayerKillzzz[(Player number of LocalPlayer)]))
      • Multiboard - Set the text for (Last created multiboard) item in column 2, row 2 to (String(murder1[(Player number of LocalPlayer)]))
      • Multiboard - Set the text for (Last created multiboard) item in column 2, row 3 to (String(playerdeaths[(Player number of LocalPlayer)]))
      • Multiboard - Set the text for (Last created multiboard) item in column 2, row 4 to (String(Blood[(Player number of LocalPlayer)]))
I am almost certain that something here is causing other players to desync, even though it works fine for me. I couldn't find any GUI tutorials for LocalPlayer, so it is likely there is something wrong here. Any ideas?

If it is necessary for me to PM someone the map so they can test it themselves, then so be it, but I'd rather not post it here on the forum :)

Cheers in advance! :thumbs_up:
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
Of course GetLocalPlayer would desync everyone except the host :)

Besides, there isn't any Local player, because the trigger doesn't hold any player or unit event. You're setting the GetLocalPlayer to a variable, and LocalPlayer is already null, but then, every 0.20 seconds, you update the hashtable with LocalPlayer values, which doesn't exist... and besides, are locals.

To have specific player readings, you have to create 1 multiboard for each player, and display the data you want for that player only, with a loop.

set i = 0
Pick every player in All players (Users that are playing) and
set p = Picked PLayer
set i = Player number of p
Create a multiboard for p
Set Multiboard last created multiboard

here's a small tutorial
http://www.wc3c.net/showthread.php?t=81262
 
Level 5
Joined
Aug 8, 2012
Messages
154
I didn't think you could have more than one multiboard created at one time though, or for specific players? I don't suppose you could make a tiny testmap just as a small example to what you mean? It's fine if you don't, it's just that I am rather new to triggering and I have no idea what I'm doing ;L

Cheers!
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
Check the map Dark Invasion II, It has 5 Multiboards for each player :)

Don't worry, we were all noobs once.

What data do you want to show on the multiboard? Give me a small example here as text so i can make a testmap for you. You can use
JASS:
 tags to display it more precisely

Example
[code=jass]

Team 1 Name | Team 1 Kills | Team 1 Deads | Nothing
Player# Name | Player# Kills | Player# Deads | Player# Gold
Player# Name | Player# Kills | Player# Deads | Player# Gold
Player# Name | Player# Kills | Player# Deads | Player# Gold
Player# Name | Player# Kills | Player# Deads | Player# Gold
Player# Name | Player# Kills | Player# Deads | Player# Gold

Team 2 Name | Team 2 Kills | Team 2 Deads | Nothing
Player# Name | Player# Kills | Player# Deads | Player# Gold
Player# Name | Player# Kills | Player# Deads | Player# Gold
Player# Name | Player# Kills | Player# Deads | Player# Gold
Player# Name | Player# Kills | Player# Deads | Player# Gold
Player# Name | Player# Kills | Player# Deads | Player# Gold
 
Level 5
Joined
Aug 8, 2012
Messages
154
Well have you ever played DayZ?

The board I am wanting is information just for that player's main character in a small multiboard at the top right: their kills, their hero kills, their deaths, and their health. So it would be two columns and four rows:

Z-Kills: [Number of Z-Killz]
Murders: [Number of Murders]
Deaths: [Number of Deaths]
Health: [Amount of Health]

I have made it work for one player, I was just confused about having each different player see only their own stats. :(
 
Level 20
Joined
Jul 14, 2011
Messages
3,213

This is the Multiboard initial setup
  • Multiboard create
    • Events
      • Time - Elapsed game time is 0.00 seconds
    • Conditions
    • Actions
      • Player Group - Pick every player in (All players) and do (Actions)
        • Loop - Actions
          • Set p = (Picked player)
          • Set i = (Player number of p)
          • Custom script: if GetPlayerSlotState(udg_p) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(udg_p) == MAP_CONTROL_USER then
          • Multiboard - Create a multiboard with 2 columns and 4 rows, titled WarZ Killboard
          • Set MB[i] = (Last created multiboard)
          • Multiboard - Hide MB[i]
          • Multiboard - Set the display style for MB[i] item in column 0, row 0 to Show text and Hide icons
          • Multiboard - Set the width for MB[i] item in column 1, row 0 to 6.00% of the total screen width
          • Multiboard - Set the width for MB[i] item in column 2, row 0 to 1.00% of the total screen width
          • Multiboard - Set the color for MB[i] item in column 1, row 0 to (100.00%, 100.00%, 0.00%) with 0.00% transparency
          • Multiboard - Set the text for MB[i] item in column 1, row 1 to Z-Kills:
          • Multiboard - Set the text for MB[i] item in column 1, row 2 to Murders:
          • Multiboard - Set the text for MB[i] item in column 1, row 3 to Deaths:
          • Multiboard - Set the text for MB[i] item in column 1, row 4 to Blood:
          • Multiboard - Set the text for MB[i] item in column 2, row 0 to 0
          • Player Group - Add p to PlayersPlaying
          • Trigger - Add to PlayerLeave <gen> the event (Player - p leaves the game)
          • Custom script: endif
      • Player Group - Pick every player in PlayersPlaying and do (Actions)
        • Loop - Actions
          • Set p = (Picked player)
          • Set i = (Player number of (Picked player))
          • Custom script: if ConvertedPlayer(udg_i) == GetLocalPlayer() then
          • Multiboard - Show MB[i]
          • Custom script: endif
This destroys the multiboard if the player leaves the game

  • PlayerLeave
    • Events
      • Player - Player 1 (Red) leaves the game
    • Conditions
    • Actions
      • Set p = (Triggering player)
      • Set i = (Player number of p)
      • Player Group - Remove p from PlayersPlaying
      • Multiboard - Destroy MB[i]
This updates the multiboard

  • Multiboard update
    • Events
      • Time - Every 0.20 seconds of game time
    • Conditions
    • Actions
      • Player Group - Pick every player in PlayersPlaying and do (Actions)
        • Loop - Actions
          • Set p = (Picked player)
          • Set i = (Player number of (Picked player))
          • Multiboard - Set the text for MB[i] item in column 2, row 1 to (String(PlayerKills[i]))
          • Multiboard - Set the text for MB[i] item in column 2, row 2 to (String(Murders[i]))
          • Multiboard - Set the text for MB[i] item in column 2, row 3 to (String(PlayerDeads[i]))
          • Multiboard - Set the text for MB[i] item in column 2, row 4 to (String(Blood[i]))



This is the Multiboard Creation
JASS:
function MultiboardCreate takes nothing returns nothing
    local player p = GetEnumPlayer()
    local integer i = GetPlayerId(p)+1
    if GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(p) == MAP_CONTROL_USER then
        set udg_MB[i] = CreateMultiboard() // Multiboard Creation
        call MultiboardSetRowCount(udg_MB[i], 4) // Rows
        call MultiboardSetColumnCount(udg_MB[i], 2) // Columns
        call MultiboardSetTitleText(udg_MB[i], "WarZ Killboard") // Title
        call MultiboardDisplay(udg_MB[i], false) // False = Initially Hidden
        call MultiboardSetItemStyleBJ( udg_MB[i], 0, 0, true, false )
        call MultiboardSetItemWidthBJ( udg_MB[i], 1, 0, 6.00 )
        call MultiboardSetItemWidthBJ( udg_MB[i], 2, 0, 1.00 )
        call MultiboardSetItemColorBJ( udg_MB[i], 1, 0, 100, 100.00, 0.00, 0 )
        call MultiboardSetItemValueBJ( udg_MB[i], 1, 1, "ZKills:" )
        call MultiboardSetItemValueBJ( udg_MB[i], 1, 2, "Murders:" )
        call MultiboardSetItemValueBJ( udg_MB[i], 1, 3, "Deads:" )
        call MultiboardSetItemValueBJ( udg_MB[i], 1, 4, "Blood" )
        call MultiboardSetItemValueBJ( udg_MB[i], 2, 0, "0" )
        call ForceAddPlayer(udg_PlayersPlaying, p)
        call TriggerRegisterPlayerEvent(gg_trg_PlayerLeave_GUI, p, EVENT_PLAYER_LEAVE)
        set p = null
    endif
endfunction

function MultiboardShow takes nothing returns nothing
    local player p = GetEnumPlayer()
    local integer i = GetPlayerId(p)+1
    if Player(i-1) == GetLocalPlayer() then
        call MultiboardDisplay(udg_MB[i], true)
    endif
    set p = null
endfunction

function MultiboardGroupCreate takes nothing returns nothing
    call ForForce( bj_FORCE_ALL_PLAYERS, function MultiboardCreate )
    call ForForce( udg_PlayersPlaying, function MultiboardShow )
endfunction

//===========================================================================
function InitTrig_Multiboard_create takes nothing returns nothing
    set gg_trg_Multiboard_create = CreateTrigger(  )
    call TriggerRegisterTimerEvent( gg_trg_Multiboard_create, 0.00, false )
    call TriggerAddAction( gg_trg_Multiboard_create, function MultiboardGroupCreate )
endfunction

This destroys the multiboard if the player leaves the game

JASS:
function Trig_PlayerLeave_Actions takes nothing returns nothing
    local player p = GetTriggerPlayer()
    local integer i = GetPlayerId(p)+1
    call ForceRemovePlayer(udg_PlayersPlaying, p)
    call DestroyMultiboard(udg_MB[i])
    set p = null
endfunction

//===========================================================================
function InitTrig_PlayerLeave takes nothing returns nothing
    set gg_trg_PlayerLeave = CreateTrigger(  )
    call TriggerAddAction( gg_trg_PlayerLeave, function Trig_PlayerLeave_Actions )
endfunction

This updates the multiboard
JASS:
function Trig_Multiboard_update_Func002A takes nothing returns nothing
    local player p = GetEnumPlayer()
    local integer i = GetPlayerId(p)+1
    call MultiboardSetItemValueBJ( udg_MB[udg_i], 2, 1, I2S(udg_PlayerKills[udg_i]) )
    call MultiboardSetItemValueBJ( udg_MB[udg_i], 2, 2, I2S(udg_Murders[udg_i]) )
    call MultiboardSetItemValueBJ( udg_MB[udg_i], 2, 3, I2S(udg_PlayerDeads[udg_i]) )
    call MultiboardSetItemValueBJ( udg_MB[udg_i], 2, 4, R2S(udg_Blood[udg_i]) )
    set p = null
endfunction

function Trig_Multiboard_update_Actions takes nothing returns nothing
    call ForForce( udg_PlayersPlaying, function Trig_Multiboard_update_Func002A )
endfunction

//===========================================================================
function InitTrig_Multiboard_update takes nothing returns nothing
    set gg_trg_Multiboard_update = CreateTrigger(  )
    TriggerRegisterTimerEvent(gg_trg_Multiboard_update, 0.2, true)
    call TriggerAddAction( gg_trg_Multiboard_update, function Trig_Multiboard_update_Actions )
endfunction


<< EDIT >> I fixed the thing on the JASS and GUI, but not on the Test map. JASS is also a bit improved (better than GUI).
 

Attachments

  • 12345.w3x
    16.7 KB · Views: 121
Last edited:
Level 5
Joined
Aug 8, 2012
Messages
154
What.JPG

Not sure what this means, being as I can't see which things it is talking about :( I seriously need to learn JASS :goblin_cry:
 
Level 5
Joined
Aug 8, 2012
Messages
154
Ahh thank you! Works like a charm in single player, won't have a chance to test it with friends until tomorrow though :(

Cheers!
 
Level 5
Joined
Aug 8, 2012
Messages
154
What would be the difference? Is it just more efficient or is there a problem with the GUI? I am seriously going to learn JASS tomorrow :grin:

Also, I tried the map with a friend over LAN, and he at least got to the loadscreen this time, but the loading bar got stuck partway through and then his game crashed and he was forced to ctrl + alt + delete. Still not sure why this is happening... Other updates I have made since I last tested with friends was a custom UI and a custom loading screen... not sure if either of those could have caused this.
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
Most GUI actions works calling another actions called "natives" and "constants"

As an example

JASS Tanslates the GUI: (All Players) to
JASS:
function GetPlayersAll takes nothing returns force
    return bj_FORCE_ALL_PLAYERS
endfunction
As you can see, "GetPlayersAll()" is a function itself that has only one unique result: bj_FORCE_ALL_PLAYERS which is a constant.

Why would we want to call "GetPlayersAll()" if we already know that the function will return bj_FORCE_ALL_PLAYERS? It's stupid. GUI forces you to call "GetPlayersAll()", but JASS allows you to replace "GetPlayersAll()" directly with "bj_FORCE_ALL_PLAYERS". So, your system works with less information, less useless function callings (which means faster and smoother) and does the same you want.

So, JASS allows optimizing GUI functions by giving direct access to natives and constants, also giving access to functions that GUI doesn't (like displaying a Multiboard for each player. That's only possible with JASS==custom scripts). Also allows creating and using custom functions. Its easier and faster to manipulate and write (once you understand it), allows using locals (so you don't need to take Wc3 memory for globals, but instead, dinamically take the memory, use it, and clear it later). Jass allows cleaning leaks (gargbage that stacks up and eventually makes your map so laggy that it's unplayable). Allows access to coordenates X/Y which are a lot faster than using Points... and so on.

Think of GUI as a child building a sand castle on the beach. Think of JASS as an Engineer building the International Space Station.

Personally, there are lots of stuff I still do in GUI, then convert to Custom Text, and optimize, because I still don't know how to do them from scratch in JASS...
 
Level 5
Joined
Aug 8, 2012
Messages
154
Fair enough! I did think that using JASS would enable more detailed and efficient editing, but I had no idea it was so useful in the long run. If I get some free time soon, methinks I will dedicate it to starting the path to JASS-ville.

On a sidenote, still not sure what it is that is causing my friend's loading bar to get stuck and his game to crash... can importing a custom UI or loading screen do that? Because those are pretty much all the changes I made since the last time I tested the map, where it worked :( I still load in fine and can play, but they get stuck about a quarter way through the load bar!

Cheers!
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
You would have to check your triggers and look for the responsable one. Maybe turning the suspicious ones off, one by one (starting from any "Map Initialization" trigger) and testing to see if that trigger was the responsable of your map not working correctly.

Any "GetLocalPlayer()" can desync if not used correctly. Also "Pan Camera as Neccesary" action usually crashes games.

I'm pretty sure that everyone would get desync and crash with the trigger you posted to create the multiboard.
 
Level 5
Joined
Aug 8, 2012
Messages
154
Hey there! I've looked over my triggers, and I am still not spotting anything that I have changed since the last test that could be causing any problems :( I am going to PM the map to you (if possible) and I would greatly appreciate it if you could do a quick look over what's there and if anything could be causing my friends to get stuck on loading. Tis fine if you don't have the time, I will keep disabling stuff and testing until it works!

Cheers!

Edit: Cannot attach in PMs, apparently, so I will just upload the map here :)

View attachment WarZ - Hivehelp.w3x
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
Dude, you're using A LOT of wait actions. You should avoid them at all cost. You shouldn't use "Wait" actions inside "Map Initialization" trigger. "Map Initialization" actions takes place during the loading time of the map, while the loadingscreen is shown. How could you wait 30 seconds inside that loading time?.

Your second trigger is also crazy. Every 0.1 seconds you wait 30 seconds to turn off that trigger. Does it have any sense? And all that random and region stuff? No way...

So many triggers... Soooooooo many things you could improve and fix =/ You should REALLY learn jass with some small projects before trying something this big. I used to read this same suggestion and don't pay attention to them, and now you see in my signature: it went way over my capacities.
 
Level 5
Joined
Aug 8, 2012
Messages
154
I know, right... This map is basically the first one I have ever made, so the quality of triggers starts at terrible and slowly progresses to just bad :L Did you see anything that could have caused the crashing?

I'm genna go ahead and fix a few of those you mentioned, I didn't realise the extent of how bad those first few were o.o
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
WHENEVER You use anything in a trigger (Like [Triggering Unit] or [Integer A] or [Last created unit] or [Picked player], or anything like that) MORE THAN THREE TIMES IN THE SAME TRIGGER first declare it into a variable (set variable = value) and replace ALL the widgets with that variable.


WRONG
Make (Piked Unit) Invulnerable
Hide (Picked Unit)
Set Health of (Picked Unit) = (Health of (Picked Unit) + 10)

CORRECT
Set u = (Picked Unit)
Make u Invulnerable
Hide u
Set Health of u = (Health of u + 10)


· Avoid waits at all cost. Most of these aren't neccesary.

· Try to reduce trigger size, actions, and if/then/else chains as long as possible. Think that there's possible shorter, smarter and more intuitive way to achieve what you want.
 
Level 5
Joined
Aug 8, 2012
Messages
154
WHENEVER You use anything in a trigger (Like [Triggering Unit] or [Integer A] or [Last created unit] or [Picked player], or anything like that) MORE THAN THREE TIMES IN THE SAME TRIGGER first declare it into a variable (set variable = value) and replace ALL the widgets with that variable.


WRONG
Make (Piked Unit) Invulnerable
Hide (Picked Unit)
Set Health of (Picked Unit) = (Health of (Picked Unit) + 10)

CORRECT
Set u = (Picked Unit)
Make u Invulnerable
Hide u
Set Health of u = (Health of u + 10)


· Avoid waits at all cost. Most of these aren't neccesary.

· Try to reduce trigger size, actions, and if/then/else chains as long as possible. Think that there's possible shorter, smarter and more intuitive way to achieve what you want.

Aye! I've been working on it recently to reduce trigger size and waits anyway, you should have seen my zombie spawn trigger... there were literally over 100 waits, it was like:

Create Zombie at [Region]
wait
Create Zombie at region
wait
...

and that went on for over 100 zombies... that trigger size was immense, you probably would have cried to have seen it.


Some updates on map not-working-ness:

Only I can work the map apparently, its not just do with hosting it. When my friend tried to host the map, it froze for him but I loaded in fine, so.... I'm not really sure what could cause that D: This makes me think that it could be something other than triggers... He can run/host/play any other maps, its just mine that makes him freeze, though I can play it when hosting or joining.... confused!

Edit:

Now it appears one of my friends can join it without crashes, while the other cannot... The plot thickens!
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
The next step is actually turning everything to jass, remove most of those Temporal Global Variables and use locals instead. Then, removing all the BJ's to improve system resource usage, map size, and trigger smoothness.
 
Level 5
Joined
Aug 8, 2012
Messages
154
I understand how that can increase efficiency/the speed and smoothness of the game... but would that make any sense of why some people can play my map, and others crash when they try?

Edit:

Turns out after all that, it was my custom loading screen, somehow.... Thanks anyway, my triggers are getting much better :)
 
Last edited:
Status
Not open for further replies.
Top