Welcome Guest! To enable all features please Login or Register.

Notification

Icon
Error

i^love^mixery Offline
#1 Posted : Sunday, July 22, 2018 7:05:18 AM(UTC)
i^love^mixery
Colonel
Joined: 10/13/2008(UTC)
Posts: 755

Thanks: 7 times
Was thanked: 186 time(s) in 140 post(s)
Warning: Long post incoming, explaining the most advanced Scripting Technique in existence of ZH.


This is a summary how multiplayer-syncing in Generals works and about the hard-to-understand way <Local Player> behaves.

Also this post will teach you how to use this new knowledge to your advantage in order to create far more powerful multiplayer maps. You will learn how to individually show different briefings and different timers to different players and how to individually move the camera to a different spot for each or any player at the same time. And you will learn what can absolutely not be done separately for each player.



What most people know: In Singleplayer Mission Maps (no start positions) and in singleplayer compstomp maps you can use <Local Player> to transfer stuff to the human player without any trouble.

But if you use <Local Player> in Multiplayer while another human player is present, the map will trigger a mismatch and the match will force-end (Like this: Mismatch Picture).

But why is that?

The explanation is simple.

As a reminder:
player0 is the player in the first lobby slot.
player1 is the player in the second lobby slot, etc.

But <Local Player> is the human player sitting in front of the computer the code is being executed on. And that's why this will cause trouble in multiplayer maps when more than one human player is present.

Example to make it easier to understand:

You are playing online 1vs1 against a human player. In your map you have a script:
Code:
*** IF ***
True.
*** THEN ***
Unit 'Bulldozer' is transferred to the command of Player '<Local Player>'



The game will mismatch.


Both players will individually see that the "Bulldozer" was transfered to them. Theoretically the "Bulldozer" is now being owned by two human players at the same time, with both players having full control over it. But the game engine does not support that. There may only be one owner. And the game does not know whos game-data is valid and who is the rightful owner of the unit. Thus the match mismatches.


This is also being abused by assheads online to force-end a match they are losing. Of course they do not use a script, as they can't modify the map on-the-go. So instead they use a game-trainer/cheat-engine. For example they use a cheap cheat tool that increases their money. And their money does increase. But only on their computer. Again, the online-engine does not know who to trust and force-ends the game with a mismatch warning. But don't worry, Gentool blocks people from starting their game if they have a trainer installed, otherwise I wouldn't be teaching you how to mismatch your game :D



Now you know why the game mismatches. But how could you possibly use that to an advantage in order to make better maps?


The answer is actually quite simple: Not all script actions will trigger that Mismatch Warning! And that changes everything, because some of these actions you will absolutely love to use in a local-player-dependant way and I will teach you how and why.


Example:

We have a 4-human-players-multiplayer-mission-map with 5 start positions. The first 4 lobby slots are for 4 human players. The last lobby slot is for a computer player (same as in many AOD maps), let's say teamSkirmishGLA.

Every Human-Player has a different thing to do in the map. Human-Player 1 must kill a dozer. Human-Player 2 must kill some tanks. Human-Player 3 must snipe some people and Human-Player 4 must prevent the others from doing any of that.

How do you explain that ingame? You would need 4 different briefings, explaining the mission to one player after the other sequentially. Every player will learn about their mission... but also they will learn about 3 missions that they aren't supposed to do by themselves, reducing the amount of valuable information to a mere 25% and also making the intro very confusing. It also greatly reduces the re-playability of the map, because all players will know exactly what each player's job is and the map will round-about always be the same for everybody. That's not good (at times).

Let's see how to script it in a way that a mission is only explained to the player that is supposed to do that exact mission.

First we will need a support-script to spawn and transfer four support units, one for each human player (use units that will not attack each other or spawn the units at different waypoints):

Code:

*** IF ***
True.
*** THEN ***
Spawn Unit 'player0unit' of type 'ChinaCommandCenter' on Team 'teamSkirmishGLA' at waypoint Waypoint 'some place far off the map'
Spawn Unit 'player1unit' of type 'ChinaCommandCenter' on Team 'teamSkirmishGLA' at waypoint Waypoint 'some place far off the map'
Spawn Unit 'player2unit' of type 'ChinaCommandCenter' on Team 'teamSkirmishGLA' at waypoint Waypoint 'some place far off the map'
Spawn Unit 'player3unit' of type 'ChinaCommandCenter' on Team 'teamSkirmishGLA' at waypoint Waypoint 'some place far off the map'
[???] Unit 'player0unit' is transferred to the command of Player 'player0'
[???] Unit 'player1unit' is transferred to the command of Player 'player1'
[???] Unit 'player2unit' is transferred to the command of Player 'player2'
[???] Unit 'player3unit' is transferred to the command of Player 'player3'



Now come the trigger scripts that differ between the four Human Players:
Code:

*** IF ***
Unit 'player0unit' is owned by Player '<Local Player>'
*** THEN ***
Show military briefing String: 'Hi, your mission is to kill the Dozer.' for 5000 milliseconds.

Code:

*** IF ***
Unit 'player1unit' is owned by Player '<Local Player>'
*** THEN ***
Show military briefing String: 'Hi, your mission is to kill the Tanks.' for 5000 milliseconds.

Code:

*** IF ***
Unit 'player2unit' is owned by Player '<Local Player>'
*** THEN ***
Show military briefing String: 'Hi, your mission is to snipe the people.' for 5000 milliseconds.

Code:

*** IF ***
Unit 'player3unit' is owned by Player '<Local Player>'
*** THEN ***
Show military briefing String: 'Hi, your mission is to defend the Dozer, the Tanks and the People.' for 5000 milliseconds.


Yes, it is that simple.

Depending on which lobby slot you are in, you will only see one of these four briefings.


This can also be combined with any other ***IF*** condition (a timer/counter, a trigger area etc.).



The only thing you absolutely positively need to make sure when using this method:
Do NEVER run an Action that will actually trigger a mismatch warning that force-ends the match. For example, you will never be able to share Ownership of a unit between multiple players, even with this method! You can only do cosmetic/visual things with these local-player-dependant scripts!


Things that do not cause a mismatch when made Local-Player-Dependant
- Display of Counter / Timer (ONLY DISPLAY!!!))
- Display of military Briefings
- Movement of Camera
- (untested) Radar Events
- (untested) Highlighting of Units

Things that will definitely mismatch a game if made Local-Player-Dependant:
- "Play Sound 'XYZ'" (for some weird reason. So you can !!!!NOT!!!! play sound effects via scripts in individualized intros). Instead do this:
http://www.cnclabs.com/f...tiplayer.aspx#post148375
- Movement of any unit
- Cashflow
- Triggering any other script that contains any of these actions (logically)
- (untested) mere ownership of a unit (without the unit being used or moved in any other way, probably not a good idea!!)


Generally speaking:
Always keep local-player-dependant scripts and non-local-player-dependant scripts STRICTLY seperated. If you mix them up your map will be very unstable and bugs will be hard to find.



That is all for now.


If anything is too confusing or hard to understand, please feel free to ask.

Edited by user Tuesday, February 5, 2019 7:50:24 AM(UTC)  | Reason: Not specified

 5 users thanked i^love^mixery for this useful post.
SkyMix_RMT on 7/22/2018(UTC), Unknown Editor on 7/22/2018(UTC), acidbrain on 7/23/2018(UTC), thepredatorbg on 7/25/2018(UTC), UTD^Force on 7/27/2018(UTC)
Sponsor
SkyMix_RMT Offline
#2 Posted : Sunday, July 22, 2018 2:46:48 PM(UTC)
SkyMix_RMT
Major
Joined: 2/21/2015(UTC)
Posts: 343
Portugal

Thanks: 77 times
Was thanked: 114 time(s) in 81 post(s)
I just tested some scripts with one of my friends and the following scripts dont cause mismatches:

-Flashing units.
-Radar events.
-Disable/Enable Letterbox mode.
-Disable/Enable User Input.
-Disable/Enable Draw-icon UI.
-Disable/Enable EVA.
-Disable/Enable Occlusion.
-Disable/Enable Particle Cap.
-Set max FPS.

All these can be done for different players and will not cause mismatches.

Speech and sound effects don't give a mismatch if you only play it for player0, but any other and there will be a mismatch. (Odd...)

Alternatively to creating a script that spawns and transfers units to all playerX (where X is the number of the player), you can create players in the player list named "playerX" then place an object for each player and in Object Properties change the team to "teamplayerX" then make sure to name the units like, for example the way I^love^mixery did, to playerXhelper, so you can use them in the scripts later. Doing this will also remove all the [???] from the scripts that use playerX.

This topic needs to be pinned btw.

Edited by user Sunday, July 22, 2018 3:49:56 PM(UTC)  | Reason: Not specified

Operation Kihill Beach V2 Released!
Download it here:
http://www.mediafire.com/file/q9ac32nklaghnhd/

Have fun!
 3 users thanked SkyMix_RMT for this useful post.
Unknown Editor on 7/22/2018(UTC), acidbrain on 7/23/2018(UTC), i^love^mixery on 7/23/2018(UTC)
i^love^mixery Offline
#3 Posted : Monday, July 23, 2018 7:15:16 PM(UTC)
i^love^mixery
Colonel
Joined: 10/13/2008(UTC)
Posts: 755

Thanks: 7 times
Was thanked: 186 time(s) in 140 post(s)
Originally Posted by: SkyMix_RMT Go to Quoted Post
Speech and sound effects don't give a mismatch if you only play it for player0, but any other and there will be a mismatch. (Odd...)


So individual sounds for player0 do work with this method but if you use it for any other player# a mismatch will be triggered? Are you sure about that?

Thanks for the tests btw. Feel free to do moreBig Smile
thepredatorbg Offline
#4 Posted : Wednesday, July 25, 2018 3:25:54 AM(UTC)
ThePredatorBG
Private
Joined: 6/20/2017(UTC)
Posts: 15
Bulgaria

Thanks: 1 times
Was thanked: 2 time(s) in 2 post(s)
That's nice scripting logic!
Playing individual sounds for each player would mean that we can overcome the hardcoded super weapon voice events (add new ones to SpecialPowers with no-voice Enums) using scripting (useful for mods). Would be a pity if it causes mismatch.

Edited by user Wednesday, July 25, 2018 3:29:09 AM(UTC)  | Reason: Not specified

SkyMix_RMT Offline
#5 Posted : Wednesday, July 25, 2018 12:37:11 PM(UTC)
SkyMix_RMT
Major
Joined: 2/21/2015(UTC)
Posts: 343
Portugal

Thanks: 77 times
Was thanked: 114 time(s) in 81 post(s)
Originally Posted by: i^love^mixery Go to Quoted Post
Originally Posted by: SkyMix_RMT Go to Quoted Post
Speech and sound effects don't give a mismatch if you only play it for player0, but any other and there will be a mismatch. (Odd...)


So individual sounds for player0 do work with this method but if you use it for any other player# a mismatch will be triggered? Are you sure about that?


Yes.

Operation Kihill Beach V2 Released!
Download it here:
http://www.mediafire.com/file/q9ac32nklaghnhd/

Have fun!
i^love^mixery Offline
#6 Posted : Thursday, November 15, 2018 6:15:41 PM(UTC)
i^love^mixery
Colonel
Joined: 10/13/2008(UTC)
Posts: 755

Thanks: 7 times
Was thanked: 186 time(s) in 140 post(s)
For anybody who still cares, this is how you play sounds for only one player:

Code:

*** IF ***
Unit 'player0' is owned by Player '<Local Player>'
*** THEN ***
Sound 'A10ThunderboltAmbientLoop' is disabled.
Play Sound 'A10ThunderboltAmbientLoop'.



Code:

*** IF ***
Unit 'player1' is owned by Player '<Local Player>'
*** THEN ***
Play Sound 'A10ThunderboltAmbientLoop'.


Any other solution will cause a desync. Of course you can fancy things up a little but this is the basic solution.
 1 user thanked i^love^mixery for this useful post.
SkyMix_RMT on 11/16/2018(UTC)
SkyMix_RMT Offline
#7 Posted : Friday, November 16, 2018 5:29:50 PM(UTC)
SkyMix_RMT
Major
Joined: 2/21/2015(UTC)
Posts: 343
Portugal

Thanks: 77 times
Was thanked: 114 time(s) in 81 post(s)
mixery, you're a genius

here's one way to fancy things up

Code:

*** IF ***
Unit 'playerX' is owned by Player '<Local Player>'
*** THEN ***
Play Sound 'A10ThunderboltAmbientLoop'.
*** ELSE ***
Sound 'A10ThunderboltAmbientLoop' is disabled.
Play Sound 'A10ThunderboltAmbientLoop'.

Edited by user Saturday, November 17, 2018 1:49:14 PM(UTC)  | Reason: Not specified

Operation Kihill Beach V2 Released!
Download it here:
http://www.mediafire.com/file/q9ac32nklaghnhd/

Have fun!
i^love^mixery Offline
#8 Posted : Saturday, February 9, 2019 9:10:54 AM(UTC)
i^love^mixery
Colonel
Joined: 10/13/2008(UTC)
Posts: 755

Thanks: 7 times
Was thanked: 186 time(s) in 140 post(s)
Found a (normally impossible) way to control CommandButton availability differently between human players. It is normally impossible because the CommandButton scripts have no "for player X" insert field, so if both players are the same faction, both players will be able to build X even if only one of them has fulfilled the prerequisites. And if you cheat your way around this using LocalPlayer by removing or adding command-buttons for only one LocalPlayer, the game will be thrown off-sync and eventually mismatch, making this impossible even with all the tricks above.

But wait! There still is a way to fix that behaviour:
With this script you can only build neutrone shells if you own an InternetCenter, the script is fully in sync and will not cause a mismatch. Note the different slot numbers. Basically, the command button is made off-limits instead of being removed.

Take a look at the slot numbers in these scripts:

(active, run every frame, don't deactivate upon success)
Code:

*** IF ***
Player '<Local Player>' has Less Than 1 unit or structure of type 'Nuke_ChinaInternetCenter'
*** THEN ***
[???] Command button: 'Command_UpgradeChinaNeutronShells' is removed from all objects of type 'Nuke_ChinaNuclearMissileLauncher'.
[???] Command button: 'Command_UpgradeChinaNeutronShells' is added to all objects of type 'Nuke_ChinaNuclearMissileLauncher' in slot number 16 (1-12).
*** ELSE ***
Command button: 'Command_UpgradeChinaNeutronShells' is removed from all objects of type 'Nuke_ChinaNuclearMissileLauncher'.
Command button: 'Command_UpgradeChinaNeutronShells' is added to all objects of type 'Nuke_ChinaNuclearMissileLauncher' in slot number 6 (1-12).


Limitation: The imaginary slots (16 in the example above) may only be the slots 15, 16, 17 and 18. Slots higher than that will still cause a mismatch! So you are limited to 4 command buttons per faction per building.

Explanation why this works:
So player0 owns an InternetCenter.
player1 doesn't.

For player0 the upgrade is in slot 6.
For player1 the upgrade is in slot 16, which means that, for player1 only, it is technically there, but off-limits and not clickable or keyboard-shortcut-able, but the machine of player1 still accepts the fact that somehow player0 clicked the upgrade (because, technically, the command button is there, the game doesn't understand it's off-limits). AI behaviour not tested.

This allows you to fully and completely customize the entire building and unit tech-tree of maps without .ini file! Things like "you need 5 propaganda centers and exactly 57 dozers to build a nuke are now easily do-able with this. And the best thing, you only need one script for all 8 player slots!

One tiny detail to keep in mind:

There, however, is one tiny glitch:
In order to update command button positions, the object needs to be re-selected. That means: If one player has the requirements to "see" the command button, and, while having the object selected, loses the requirements, the command button will still be there and click-able until the object is re-selected. It is the same the other way around, the button is not there until the object was re-selected.

If you, absolutely positively, need to fix that tiny bug, this would be the way to force-deselect everything, but will require some more work to check if the condition changed:
Code:

*** IF ***
[prerequities changed]
*** THEN ***
Disable mouse and keyboard input.
Enable mouse and keyboard input.

Edited by user Monday, February 25, 2019 1:19:19 PM(UTC)  | Reason: Not specified

 2 users thanked i^love^mixery for this useful post.
Unknown Editor on 2/9/2019(UTC), SkyMix_RMT on 2/10/2019(UTC)
SkyMix_RMT Offline
#9 Posted : Sunday, February 10, 2019 2:17:18 PM(UTC)
SkyMix_RMT
Major
Joined: 2/21/2015(UTC)
Posts: 343
Portugal

Thanks: 77 times
Was thanked: 114 time(s) in 81 post(s)
How did you even come up with that?! Shock Shock Shock
Operation Kihill Beach V2 Released!
Download it here:
http://www.mediafire.com/file/q9ac32nklaghnhd/

Have fun!
i^love^mixery Offline
#10 Posted : Monday, February 11, 2019 10:37:02 AM(UTC)
i^love^mixery
Colonel
Joined: 10/13/2008(UTC)
Posts: 755

Thanks: 7 times
Was thanked: 186 time(s) in 140 post(s)
Not sure if that question was rhetorical or not, but anyway:

I usually narrow a problem down by factual approach. I knew why the game was desynced and searched for a way around it. So, similar to the sound solution above, I had to find a way to "fake" something not being there even though it is there. Having to find a way to hide the button without actually disabling it was the only logical conclusion.

Of course I didn't know whether it would crash or not, so I simply tested it. And it worked. So yea, a mix of narrowing down and trial and error. You can pretty much fix anything that is fixable by following these steps, given that you know the tools and their limits.

Edited by user Monday, February 11, 2019 1:03:35 PM(UTC)  | Reason: Not specified

 1 user thanked i^love^mixery for this useful post.
SkyMix_RMT on 2/11/2019(UTC)
Users browsing this topic
Guest (6)
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.

Powered by YAF 1.9.6.1 | YAF © 2003-2019, Yet Another Forum.NET
This page was generated in 0.997 seconds.