My english is kind of limited, so I will make it simple. If you have any questions, you can post it here.
It's a tutorial that teach you how to do asynchronous actor operate with triggers and Data Editor, like show/hide/destroy any actor for specified players only, or send even more actor messages asynchronously. And there will also be a sample map with two custom funcions "Show/Hide Actor For Player Group" and "Destroy Actor For Player Group".
With this, you can make different player see/hear different things(including actor of Units, Doodads, Sounds, Effects, Models, Texts, Splats, and even Terrain Deformations)in the same location.
If you are familiar with the "Phase" tech in WOW, it would be more understandable.
In fact the Actor system itself is asynchronous. An actor might only be created on machines with good graphics cards or with high game video setting, for instance. This won't make they disconnect, even if two players see different actors, because the actors only affect visual effect and sounds.
But so far, the editor doesn't have supports to send per player actor message, or show/hide any actors for specified players.(We have a "Actor-Filter" field but it only works for Effect scope, and the filter is very limited). So we need to find a especial way to do it:
First Leap
First, though we can't send actor message for specified player only, the "actor terms" in actor events still allow us to check the video options(Low <-> Extreme) of local machine. If we can use triggers to reconfig these options for specified players at run time, and write actor events to check their value, then we can make it.
Sure, most of the video setting can't be reconfiged by triggers. But we've got lucky, there is one, and just one game setting can be reconfiged by galaxy, and can be checked by actor terms in the meantime - the "Show Flyer Help" setting.
There is a trigger action: "Lock Flyer Helper Display" allow us temporary set the display style of Flyer Helpers(All, None, Selected.), and an other action: "Unlock Flyer Helper Display" to turn the flyer helper back to player's setting.
So our first conception would be like this: Say if we want to hide an actor for Player 1, we use triggers to lock player 1's flyer helper to "All", and set other player's setting to "None", then use "Send Actor Message" action to send a actor signal to our actor, then unlock the settings of all players. And we modfiy the actor in actor editor, create an actor event that capture this signal, then check the flyer helper settings of local machine with actor terms, if the setting is "All", then send message "SetVisibility" to hide itself.
If you want to improve your actor skill, you can test it yourself, but I'll tell you the result: it works! This will hide the actor for Player 1 only. But we still in the half-way.
A Second Leap
The test above provide us a excellent information: Per Player Actor Message is possible.
But it needs you to modify the actor, add a few actor events. What we most wanted is to show/hide ANY actor we want by specified players. If we want to do it this way, we will need to modfiy almost ALL actors in actor editor. Even if we have CActorEventMacro, it's still not a option.
We need a simple way, a universal way.
Unfortunately, we just can't use triggers to dynamic add actor events for an actor at runtime, or use trigger function to send actor message with actor term.(I really hope blizzard counld add these features in the feature)
It's a dead end then?
No. There is an other path we can choose. We need to thank the Aliases system and the References system in the actor system :)
In the actor editor, we not only can check terms in actor events, but also can make actors send actor messages to other actors with the "Target" field of the messages. We only need one custom agent actor if we can make it check actor terms then send messages to the actor we want to operate.
CActorSimple is enough for such a custom agent actor. And you can fill the "Target" field with explicit Actor IDs or Aliases or References.
So our second conception would be like this: We use triggers lock the flyer helper setting, then send "Create xxxx"(xxxx be the id of the agent actor) message to our target actor, tell it to create a agent actor. Then we immediately use the function "Actor From Actor" with the System References "::LastCreatedActual" to get a hold of the created agent, send a signal to the agent, then destroy the agent, release the flyer helper setting. And in actor editor, we create the agent actor with CActorSimple, capture the signal, and fill the Target fields of it's corresponding messages with System References "::Creator", if that would work, it's done.
But it won't. There is a strange bug here: If you using the trigger action "Send Actor Message" to send "Create" message, the created actor won't set it's "::Creator" References to the Creator, thus, the messages won't reach the target actor - One last obstacle to get through.
And it is easy to do. We just set this System References manually with trigger actor messages. Or we could use Aliases instead, they both work. If we use Aliases, we just need change the target field to the aliase we set.
Sample funtions to Show/Hide given Actors for given Players
In the end, I will give you a sample map with two custom funcions "Show/Hide Actor For Player Group" and "Destroy Actor For Player Group".
In these two sample functions, I use "AliasAdd" message to add custom alias "_TriggerTarget" to the target actor, then remove the alias with "AliasRemove" when its done. The alias is just here to help the agent actor "TriggerPerPlayerActorAgent" to find the target actor.
The detail of the funtion "Show/Hide Actor For Player Group".
There is a test trigger in this map, with 2 custom functions list above.
Everytime any player press "Esc" key, the test trigger do follow things:
1]Destroy the Orbital Command's Main actor for Player 1(It's splat actor will remain).
2]Show 2 random unit, hide 2 random unit for player 1.
3]Show 2 random unit, hide 2 random unit for player 2.
4]Hide Store Front(doodad) for player 2.
5]Hide Xel'Naga Hull Reactor(doodad), Fallen Asteroids Scattered(doodad), Char Arm(doodad) for player 1.
The sample map can be test in test document or be tested online with 2 players (US.battle.net player could search the map name "Per Player Actor" in the game list.)
You can make more acor messages sent asynchronously with this way, "SetVisibility" and "Destroy" are just two examples, we can even remake the "phase" technology of wow in SC2.
Great that this was front-paged. I was wondering about this yesterday for Death Haven, trying to get helper arrow-units only displayed for each player individually to click on...
Nice. I only tested the filter and thought it was impossible to show a unit to only one player and hide it to all other allies or foes. :D
But now that I think of it. Wouldn't it be easier to make a fake upgrade. Create a validator which checks for this upgrade and use this validator in the actor term? Upgrades can more easily be modified in the triggers than this flyer helper state.
Nice. I only tested the filter and thought it was impossible to show a unit to only one player and hide it to all other allies or foes. :D
But now that I think of it. Wouldn't it be easier to make a fake upgrade. Create a validator which checks for this upgrade and use this validator in the actor term? Upgrades can more easily be modified in the triggers than this flyer helper state.
No, this cannot be done. Upgrades actually are not asynchronous. Every machine actually save all player's data table,and keep contact with each other. That's why when you upgraded marine's shield, just your units have shield, other player's units display in your machine doesn't have; And other players see the same things on their machine that just your marine have this upgrade, it's absolutely synchronous.
You can't just modify the upgrades just for your machine, it will certainly disconnect the game.
But "reconfig Player 1 game setting" and "modify upgrades for Player 1" are two completely different things.
They both called "Player 1", but the the former one is actully refers to P1's machine, and the later one is P1's player dataes
The later will affect every player's machine, tell them"hi, I just made a upgrade, and my marine have addtional HP now, haha.!" or something. The game need syn these datas to ensure its progress.
Image if the marine on your machine have 100 atk dmg, but on others' machine it only has 6, when he attack a target with 10 HP, the target should die or live? The game would not allow such things to happen, or the fairness will be ruined, so these data are forced to synchronous. If there any data differences in two machine, the game will forced to disconnect.
Thank you! This is great trigger! I want it for my map, but... it's very strange... this function is not work in my map. I'm copy/paste it from original map.
Function:
Trigger:
I'm select one unit and press Delete button... nothing happens :( Map with this trigger in attachmet. Please help. I'm really need this function for my FPS/TPS/RPG/RTS map :D
Thank you! This is great trigger! I want it for my map, but... it's very strange... this function is not work in my map. I'm copy/paste it from original map.
Function:
Trigger:
I'm select one unit and press Delete button... nothing happens :( Map with this trigger in attachmet.
You forgot to copy the actor. Copy the "TriggerPerPlayerActorAgent" to your map, it's all done.
Its the only actor you need to manipulate ALL actors asynchronously.
why I am so happy?
I will probably use this in my space rts map. This way, I can do colony view or I can do to view your ship design on your current screen without moving camera or eating up map space. (you can design ship in my map)
(I was searching for something like this, since some time)
Don't forget about the Selection Update event, it has a asynchronous version, which also could be used for a workaround.
That's right, but that needs a selectable Unit. And using triggers to save\modify\restore every player's selection.
And there is an other potential problem: modify selection with trigger will throw the selection events to the galaxy, if users of this custom functions doesn't careful, it could accidently triggered their own triggers in their map.The flyer helper will be more universally, and has much better efficiency.
So with this could we create a method to hide all the actors in a "zone" in a first person map to improve frame rates? Or would the cost of hiding them all not be efficient?
You mean like a narrative game for four players, but each player's experiences are script based on each character, so it narrates differently to each character like with individual cutscenes or "visions"?
P1 could play as a warrior who comes from a mercenary background, thus sees the character "think" in his head when activating certain sequences.
P2 can be a royalty wizard, etc. and sees different text and quotes.
All characters can see chat boxes of other characters when a cutscene or sequence involves them.
Kind of like a Semi-Open RPG with storytelling in it.
Better is if players can interact with other players ala "Choice selections" like a player raids another player's town, initiates a "talking sequence" and both player takes turns talking and using the pre-listed story basically.
So with this could we create a method to hide all the actors in a "zone" in a first person map to improve frame rates? Or would the cost of hiding them all not be efficient?
Of course you can. But if we want to hide many actors in the same time, we doesn't need to do reconfig the flyer helper setting for every actors. We just need set it once, and send the asynchronous message to all actors, than reset it.
I plan to do a new custom function could send asynchronous actor message to actos in a region at once for specified players , which could have much more highrt efficiency than just loop-using "Show/Hide Actor For Player Group" for every actors in a region.
You mean like a narrative game for four players, but each player's experiences are script based on each character, so it narrates differently to each character like with individual cutscenes or "visions"?
P1 could play as a warrior who comes from a mercenary background, thus sees the character "think" in his head when activating certain sequences. P2 can be a royalty wizard, etc. and sees different text and quotes.
All characters can see chat boxes of other characters when a cutscene or sequence involves them.
Kind of like a Semi-Open RPG with storytelling in it.
Better is if players can interact with other players ala "Choice selections" like a player raids another player's town, initiates a "talking sequence" and both player takes turns talking and using the pre-listed story basically.
I know it's been awhile but I've been playing with this trying to get it to work on doodads. Right now I can send a message to doodads in a region with send actor message to game region with filters.
My english is kind of limited, so I will make it simple. If you have any questions, you can post it here.
It's a tutorial that teach you how to do asynchronous actor operate with triggers and Data Editor, like show/hide/destroy any actor for specified players only, or send even more actor messages asynchronously. And there will also be a sample map with two custom funcions "Show/Hide Actor For Player Group" and "Destroy Actor For Player Group".
With this, you can make different player see/hear different things(including actor of Units, Doodads, Sounds, Effects, Models, Texts, Splats, and even Terrain Deformations)in the same location.
If you are familiar with the "Phase" tech in WOW, it would be more understandable.
In fact the Actor system itself is asynchronous. An actor might only be created on machines with good graphics cards or with high game video setting, for instance. This won't make they disconnect, even if two players see different actors, because the actors only affect visual effect and sounds.
But so far, the editor doesn't have supports to send per player actor message, or show/hide any actors for specified players.(We have a "Actor-Filter" field but it only works for Effect scope, and the filter is very limited). So we need to find a especial way to do it:
First Leap
First, though we can't send actor message for specified player only, the "actor terms" in actor events still allow us to check the video options(Low <-> Extreme) of local machine. If we can use triggers to reconfig these options for specified players at run time, and write actor events to check their value, then we can make it.
Sure, most of the video setting can't be reconfiged by triggers. But we've got lucky, there is one, and just one game setting can be reconfiged by galaxy, and can be checked by actor terms in the meantime - the "Show Flyer Help" setting.
There is a trigger action: "Lock Flyer Helper Display" allow us temporary set the display style of Flyer Helpers(All, None, Selected.), and an other action: "Unlock Flyer Helper Display" to turn the flyer helper back to player's setting.
So our first conception would be like this: Say if we want to hide an actor for Player 1, we use triggers to lock player 1's flyer helper to "All", and set other player's setting to "None", then use "Send Actor Message" action to send a actor signal to our actor, then unlock the settings of all players. And we modfiy the actor in actor editor, create an actor event that capture this signal, then check the flyer helper settings of local machine with actor terms, if the setting is "All", then send message "SetVisibility" to hide itself.
The actor event will like:
If you want to improve your actor skill, you can test it yourself, but I'll tell you the result: it works! This will hide the actor for Player 1 only. But we still in the half-way.
A Second Leap
The test above provide us a excellent information: Per Player Actor Message is possible.
But it needs you to modify the actor, add a few actor events. What we most wanted is to show/hide ANY actor we want by specified players. If we want to do it this way, we will need to modfiy almost ALL actors in actor editor. Even if we have CActorEventMacro, it's still not a option.
We need a simple way, a universal way.
Unfortunately, we just can't use triggers to dynamic add actor events for an actor at runtime, or use trigger function to send actor message with actor term.(I really hope blizzard counld add these features in the feature)
It's a dead end then?
No. There is an other path we can choose. We need to thank the Aliases system and the References system in the actor system :)
In the actor editor, we not only can check terms in actor events, but also can make actors send actor messages to other actors with the "Target" field of the messages. We only need one custom agent actor if we can make it check actor terms then send messages to the actor we want to operate.
CActorSimple is enough for such a custom agent actor. And you can fill the "Target" field with explicit Actor IDs or Aliases or References.
So our second conception would be like this: We use triggers lock the flyer helper setting, then send "Create xxxx"(xxxx be the id of the agent actor) message to our target actor, tell it to create a agent actor. Then we immediately use the function "Actor From Actor" with the System References "::LastCreatedActual" to get a hold of the created agent, send a signal to the agent, then destroy the agent, release the flyer helper setting. And in actor editor, we create the agent actor with CActorSimple, capture the signal, and fill the Target fields of it's corresponding messages with System References "::Creator", if that would work, it's done.
But it won't. There is a strange bug here: If you using the trigger action "Send Actor Message" to send "Create" message, the created actor won't set it's "::Creator" References to the Creator, thus, the messages won't reach the target actor - One last obstacle to get through.
And it is easy to do. We just set this System References manually with trigger actor messages. Or we could use Aliases instead, they both work. If we use Aliases, we just need change the target field to the aliase we set.
Sample funtions to Show/Hide given Actors for given Players
In the end, I will give you a sample map with two custom funcions "Show/Hide Actor For Player Group" and "Destroy Actor For Player Group".
In these two sample functions, I use "AliasAdd" message to add custom alias "_TriggerTarget" to the target actor, then remove the alias with "AliasRemove" when its done. The alias is just here to help the agent actor "TriggerPerPlayerActorAgent" to find the target actor.
The detail of the funtion "Show/Hide Actor For Player Group".
The function "Destroy Actor For Player Group" is basiclly the same, just have different parameters, and send different signals.
And the agent actor:
just need 4 lines. Concise, isn't it?
And about the sample map:
There is a test trigger in this map, with 2 custom functions list above.
Everytime any player press "Esc" key, the test trigger do follow things:
1]Destroy the Orbital Command's Main actor for Player 1(It's splat actor will remain).
2]Show 2 random unit, hide 2 random unit for player 1.
3]Show 2 random unit, hide 2 random unit for player 2.
4]Hide Store Front(doodad) for player 2.
5]Hide Xel'Naga Hull Reactor(doodad), Fallen Asteroids Scattered(doodad), Char Arm(doodad) for player 1.
The sample map can be test in test document or be tested online with 2 players (US.battle.net player could search the map name "Per Player Actor" in the game list.)
You can make more acor messages sent asynchronously with this way, "SetVisibility" and "Destroy" are just two examples, we can even remake the "phase" technology of wow in SC2.
Attachment #1 is A screenshoot from Player 1
Attachment #2 is A screenshoot from Player 2
Can you tell the difference?
@Renee2islga: Go
Great that this was front-paged. I was wondering about this yesterday for Death Haven, trying to get helper arrow-units only displayed for each player individually to click on...
@Renee2islga: Go
That's amazing! Good job.
Nice. I only tested the filter and thought it was impossible to show a unit to only one player and hide it to all other allies or foes. :D
But now that I think of it. Wouldn't it be easier to make a fake upgrade. Create a validator which checks for this upgrade and use this validator in the actor term? Upgrades can more easily be modified in the triggers than this flyer helper state.
No, this cannot be done. Upgrades actually are not asynchronous. Every machine actually save all player's data table,and keep contact with each other. That's why when you upgraded marine's shield, just your units have shield, other player's units display in your machine doesn't have; And other players see the same things on their machine that just your marine have this upgrade, it's absolutely synchronous.
You can't just modify the upgrades just for your machine, it will certainly disconnect the game.
Not sure my poor english has made it clear.
But "reconfig Player 1 game setting" and "modify upgrades for Player 1" are two completely different things.
They both called "Player 1", but the the former one is actully refers to P1's machine, and the later one is P1's player dataes
The later will affect every player's machine, tell them"hi, I just made a upgrade, and my marine have addtional HP now, haha.!" or something. The game need syn these datas to ensure its progress.
Image if the marine on your machine have 100 atk dmg, but on others' machine it only has 6, when he attack a target with 10 HP, the target should die or live? The game would not allow such things to happen, or the fairness will be ruined, so these data are forced to synchronous. If there any data differences in two machine, the game will forced to disconnect.
Thank you! This is great trigger! I want it for my map, but... it's very strange... this function is not work in my map. I'm copy/paste it from original map.
Function:
Trigger:
I'm select one unit and press Delete button... nothing happens :( Map with this trigger in attachmet. Please help. I'm really need this function for my FPS/TPS/RPG/RTS map :D
You forgot to copy the actor. Copy the "TriggerPerPlayerActorAgent" to your map, it's all done.
Its the only actor you need to manipulate ALL actors asynchronously.
Don't forget about the Selection Update event, it has a asynchronous version, which also could be used for a workaround.
THIS IS SO FUCKING AWESOME!!!
why I am so happy?
I will probably use this in my space rts map. This way, I can do colony view or I can do to view your ship design on your current screen without moving camera or eating up map space. (you can design ship in my map)
(I was searching for something like this, since some time)
That's right, but that needs a selectable Unit. And using triggers to save\modify\restore every player's selection.
And there is an other potential problem: modify selection with trigger will throw the selection events to the galaxy, if users of this custom functions doesn't careful, it could accidently triggered their own triggers in their map.The flyer helper will be more universally, and has much better efficiency.
Not saying you can't do it, anyway
Holy crap this is amazing, time to make use of being able to show terrain deformers for certain players. (Just tested it and it seems to work fine)
and not having to to turn doodads into units just to phase them anymore makes things so much easier.
Thanks so much for finding this out.
So with this could we create a method to hide all the actors in a "zone" in a first person map to improve frame rates? Or would the cost of hiding them all not be efficient?
You mean like a narrative game for four players, but each player's experiences are script based on each character, so it narrates differently to each character like with individual cutscenes or "visions"?
P1 could play as a warrior who comes from a mercenary background, thus sees the character "think" in his head when activating certain sequences. P2 can be a royalty wizard, etc. and sees different text and quotes.
All characters can see chat boxes of other characters when a cutscene or sequence involves them.
Kind of like a Semi-Open RPG with storytelling in it.
Better is if players can interact with other players ala "Choice selections" like a player raids another player's town, initiates a "talking sequence" and both player takes turns talking and using the pre-listed story basically.
Think Fallout talk dialogs, but between players.
Could you use this to create multiplayer first person games? So you can hide a unit from it's controller, but everyone else can still see it?
Of course you can. But if we want to hide many actors in the same time, we doesn't need to do reconfig the flyer helper setting for every actors. We just need set it once, and send the asynchronous message to all actors, than reset it.
I plan to do a new custom function could send asynchronous actor message to actos in a region at once for specified players , which could have much more highrt efficiency than just loop-using "Show/Hide Actor For Player Group" for every actors in a region.
Absolutely you can
Absolutely, you can. It's the most basicly usage of these function.
I know it's been awhile but I've been playing with this trying to get it to work on doodads. Right now I can send a message to doodads in a region with send actor message to game region with filters.
But I'm having a hard time sending the messages signal show signal hide and eventually destroy to the newly attached actors.
I can send a message to every doodad in the map to destroy via the region thing so I know the messages are reaching all the doodads.