Hello, I’ve been playing with the workshop for a while and its incredible frustrating as i can almost never get what i want no matter how much the code makes sense to me. I want to create a custom hero limits option where there will be no limits on any hero other than mercy. i am making a president game (mercy as president) and i want there to be only 1 mercy a team. If this isn’t possible i want to force 1 random player on each team to be mercy regardless of their picks which i definitely think is possible. I’ve spent WAAAAY to much time trying to do this and i need help. If anyone can create the code for me or at least give any advice on what i could do to do this, it will be highly appreciated
You already tried something right? So it might be more helpful for you if you share the code you have already so I/we can tell you what you did wrong and where you have to change things, instead me just telling from scratch what to do.
i was planning on starting from scratch to get that fresh feeling again but if you really want to ill give u the code.
T0XR2
Hey sizzlin, I haven’t tested this code but I think it will do you want.
First we will need to pick a ‘president’ for each team. To do this, we choose to use player variable ‘M
’ designate our mercy. You can actually use any letter variable here but I chose ‘M
’ for clarity. The idea is that we will set this player variable for each player at the start of the match to be TRUE
for the two players who are chosen as ‘the president’ and FALSE
for all other players.
This is what the code for the first rule will look like.
RULE: DESIGNATE MERCY FOR EACH TEAM
EVENT: ONGOING-GLOBAL
CONDITIONS: NONE
ACTIONS:
SET PLAYER VARIABLE(ALL PLAYERS(ALL TEAMS), M, FALSE)
SET PLAYER VARIABLE(RANDOM VALUE IN ARRAY(ALL PLAYERS(TEAM 1)), M, TRUE)
SET PLAYER VARIABLE(RANDOM VALUE IN ARRAY(ALL PLAYERS(TEAM 2)), M, TRUE)
This will run once at the start of the match. Now that the designation part is out of the way. We need to start forcing the president players to be mercy. We do this by checking each player and seeing if their player variable ‘M
’ is equal (this symbol ==
) to TRUE
. The code is fairly straightforward.
RULE: FORCE MERCY -- PRESIDENT
TEAM: ALL
PLAYER: ALL
EVENT: ONGOING-EACH PLAYER
CONDITIONS: PLAYER VARIABLE(EVENT PLAYER, M) == TRUE
ACTIONS:
START FORCING PLAYER TO BE HERO(EVENT PLAYER, HERO(MERCY))
This will ensure that the designated ‘president’ player has to pick or be mercy. Now for everyone else, we have to disallow mercy as a hero. This code is very similar to the previous rule. We invert our condition event so we operate on every player who is NOT the president. We use the operator !=
(this is read as NOT equal to. Basically when you see a !
think ‘NOT’). Then we take an array (an ordered list) of all heroes and remove the hero mercy from the array as our action. We then set this list as the EVENT PLAYER
's (anyone with M
set to FALSE
) allowed heroes.
RULE: RESTRICT TO NON-MERCY HEROES -- NON-PRESIDENTS
TEAM: ALL
PLAYER: ALL
EVENT: ONGOING-EACH PLAYER
CONDITIONS: PLAYER VARIABLE(EVENT PLAYER, M) != TRUE
ACTIONS:
SET PLAYER ALLOWED HEROES(EVENT PLAYER, REMOVE FROM ARRAY(ALL HEROES, HERO(MERCY)))
That’s it! Let me know if you have any questions.
Edit: Formatting
Thats a really good how-to explanation there @Timfoil !
You already got the first 2 rules that Timfoil explained right. I think you dont need to Stop Forcing Player To Be Hero. If you want to allow hero swaps you can do a seperate between rounds rule for the stop forcing player to be hero action. The reason why it is not working might be that you had the “Team 2 Force to have mercy” rule set to trigger only for players of Team 1. It should work if you set this to Team 2. You might aswell remove the “is waiting for players” condition, as I dont think it is needed.
Actually you want the force mercy rules to trigger only one time right? It might be better to use an ongoing - global rule for that.
Thank you so much for your detailed reply! I Just tried out your code and it doesnt seem to be working its disabling mercy every time. i am the only one in my lobby though. i think the issue with the code is its looking for empty slots as well as full slots in team 1 so should i change it to the array of all PLAYERS in Team 1 or is it already doing that?
SCP84
this is the code
EDIT: i just tried my way ad its giving me the same results so its not even registering the people tagged with variable M
Hey Sizzlin,
This took me a bit, but I found a few tricky bugs and I think I have something working!
The first thing I noticed was that the game-mode was set to elimination. I changed this to team death-match since you mentioned you wanted two teams of six and sometimes this can cause action statements about team 2 to be ignored.
The next thing I noticed was that your code in the DESIGNATE MERCY FOR EACH TEAM
rule has these two statements.
SET PLAYER VARIABLE(RANDOM VALUE IN ARRAY(TEAM 1), M, TRUE)
SET PLAYER VARIABLE(RANDOM VALUE IN ARRAY(TEAM 2), M, TRUE)
The problem is extremely easy to overlook because the code looks correct at first glance. The issue lies in the fact that TEAM 1
and TEAM 2
are not actually arrays in this case. What you want is an array containing all players in the team, ALL PLAYERS(TEAM 1)
& ALL PLAYERS(TEAM 2)
in this case. The fixed lines should look like this.
SET PLAYER VARIABLE(RANDOM VALUE IN ARRAY(ALL PLAYERS(TEAM 1)), M, TRUE)
SET PLAYER VARIABLE(RANDOM VALUE IN ARRAY(ALL PLAYERS(TEAM 2)), M, TRUE)
Side note: I was curious as to what TEAM 1
& TEAM 2
's actual values were in this scenario. I set them to a global variable so I could view them in the inspector it seems as though they are both strings (text) of TEAM 1 and TEAM 2 respectively. Nice to know I guess.
The last part was the trickiest and hardest bug to solve. I’m not extremely happy with the solution since it’s hacky and temperamental, but it gets the job done. I took a look of what variables were being set to after I loaded in, inside the workshop inspector (this option is visible in the custom game esc menu). My player variables didn’t seem to be getting updated, (they’re usually visible in the variable section if they have been changed). I figured this was due to the mercy designation rule being run before I loaded in as a player.
One of the things I found is that if something isn’t running or working to how you expect it to in the Overwatch Forge a good idea is to add some wait actions for your rules. So that’s what I did ¯\(ツ)/¯. Here are the updated rules with the wait actions.
RULE: DESIGNATE MERCY FOR EACH TEAM
EVENT: ONGOING-GLOBAL
CONDITIONS: NONE
ACTIONS:
WAIT(1, IGNORE CONDITION)
SET PLAYER VARIABLE(ALL PLAYERS(ALL TEAMS), M, FALSE)
SET PLAYER VARIABLE(RANDOM VALUE IN ARRAY(ALL PLAYERS(TEAM 1)), M, TRUE)
SET PLAYER VARIABLE(RANDOM VALUE IN ARRAY(ALL PLAYERS(TEAM 2)), M, TRUE)
RULE: FORCE MERCY -- PRESIDENT
TEAM: ALL
PLAYER: ALL
EVENT: ONGOING-EACH PLAYER
CONDITIONS: PLAYER VARIABLE(EVENT PLAYER, M) == TRUE
ACTIONS:
WAIT(0.250, RESTART WHEN TRUE)
START FORCING PLAYER TO BE HERO(EVENT PLAYER, HERO(MERCY))
RULE: RESTRICT TO NON-MERCY HEROES -- NON-PRESIDENTS
TEAM: ALL
PLAYER: ALL
EVENT: ONGOING-EACH PLAYER
CONDITIONS: PLAYER VARIABLE(EVENT PLAYER, M) != TRUE
ACTIONS:
WAIT(0.250, RESTART WHEN TRUE)
SET PLAYER ALLOWED HEROES(EVENT PLAYER, REMOVE FROM ARRAY(ALL HEROES, HERO(MERCY)))
You can play around with the wait times a bit if they are not to your liking. I found however, that it can be temperamental and will break easy if you try to minimize too small. The 1 second wait time isn’t even noticeable to me at the hero select so I assume that it finishes before I load to completely to the selection screen.
If I had to guess why these wait times are needed I would say it was because the DESIGNATE MERCY FOR EACH TEAM
rule is running before I loaded into the select hero screen as a player. This would cause it to receive an empty array for the players in TEAM 1
& TEAM 2
. The other wait statements are even more of a mystery. But they seem to make the CONDITIONS
list check for changes instead of only checking the conditions once at the start.
Anyways, I hope this write-up helped you.
Here’s a game-code for the working code: GYXXG
It is people like you that restore my faith in this community. I can not put how much i appreciate you helping me into words! I have been working on this all day and i gave up around the end! I can finaly work on my game thanks to you!!!
EDIT: Theres acctually one tiiinnny problem. Everything is working great, its just allowing all heros for the players who are not mercy. Which i only want a handful of. everything else is working great tho
So if I’m reading your post correctly it sounds like you would like to limit the heroes even further for the non-president players besides just ‘not Mercy’.
To do this we’ll take a look at our existing code in RULE: RESTRICT TO NON-MERCY HEROES -- NON-PRESIDENTS
. After our wait action is the
SET PLAYER ALLOWED HEROES(EVENT PLAYER, REMOVE FROM ARRAY(ALL HEROES, HERO(MERCY)))
This is how we our currently restricting the hero list for non president players. Lets take a look at the documentation for this action. We can view this by mousing over the action in the ‘EDIT ACTION’ popup window. (All documentation is also viewable in the workshop wiki at WIKI: Workshop Syntax & Script Database - #2 by Kaedi-11739)
Sets the list of heroes available to one or more players. If a player’s current hero becomes unavailable, the player is forced to choose a different hero and respawn at an appropriate spawn location.
Definitions:
- Player - The player or players whose hero list is being set. Can use most Player based Value Syntax for this value.
- Hero - The hero or heroes that will be available. If no heroes are provided, the action has no effect. Can use most Hero based Value Syntax for this value including compatible Arrays.
Neat! So the first thing we notice is that there are two bullet points for each value we can change for this Action. Programmers refer to these changeable values as either ‘arguments’ or ‘parameters’ (these terms may or may not be used interchangeably in other computer programming languages for any nit-pickers out there reading this post).
So what this action wants is a “player or players” to set a hero list for as the first ‘argument’ and a “Hero or heroes” the aforementioned player can pick from as the second. What this tells us is that the value both of these ‘arguments’ expects can either be a singular value or an array (a list of values).
Still with me? Alright! Now back to our case! Lets look at what we are currently ‘passing as’ (putting down as) the action’s arguments. For the player argument, we are passing the EVENT PLAYER
value that this rule has filtered out with our CONDITIONS
. This is a singular value of one player, in other words, not an array. If we wanted to though, we could put an array value like ALL LIVING PLAYERS
here which funnily enough is an array containing the names of all the players that are currently alive (shocker right?). We only want to set it for players with the ‘M
’ variable set to TRUE
which our rule is filtering for already, so let’s leave it be as EVENT PLAYER
.
The second argument expects a ‘hero or heroes’. We are currently passing an array value here!
REMOVE FROM ARRAY(ALL HEROES, HERO(MERCY))
What we are doing with this line is creating our own list of heroes from an already known array, ALL HEROES
. The ALL HEROES
array probably looks something like this…
["Tracer", "Winston", "Mercy", "Gengu", "Handsoap", ... , "Secret Hero #31 please do not release early"]
Another quick programming learning aside, square brackets ‘’ or sometimes curly brackets ‘{}’ are used by programmers to indicate that something is an array. All the quoted values inside are the ‘elements’ inside the array. Again, an array is a list, but I’m getting sidetracked!
What we wanted originally was the player to be able to chose any character except Mercy. So, we’ll need to give the second argument of the SET PLAYER ALLOWED HEROES
action an array containing all heroes BUT Mercy. The easiest way to create this is to take a list of all the heroes in the game and just remove the “Mercy” hero value. Which we can do with the previously mentioned line. (I won’t post it here since this is getting long but you can take a look at the documentation at WIKI: Workshop Syntax & Script Database - #2 by Kaedi-11739)
REMOVE FROM ARRAY(ALL HEROES, HERO(MERCY))
This will create an altered copy of the array from before that looks something like this.
["Tracer", "Winston", "Gengu", "Handsoap", ... , "Secret Hero #31 please do not release early"]
So one way we could further limit the list of allowed heroes is to continue on with our current method of removing heroes from the array. Let’s say another hero we did not want the player to be was tracer. We could accomplish that by ‘nesting’ (continuing on by putting actions inside each other) REMOVE FROM ARRAY
actions like so.
REMOVE FROM ARRAY(REMOVE FROM ARRAY(ALL HEROES, HERO(MERCY)), HERO(TRACER))
The resulting array would look like this…
["Winston", "Gengu", "Handsoap", ... , "Secret Hero #31 please do not release early"]
At some point though, nesting starts to affect the readability of your code so its better to break these actions out and chain them together by using a temporary global variable. I use ‘T
’ as the global variable in this example for temporary.
SET GLOBAL VARIABLE(T, ALL HEROES)
MODIFY GLOBAL VARIABLE(T, REMOVE FROM ARRAY BY VALUE, HERO(MERCY))
MODIFY GLOBAL VARIABLE(T, REMOVE FROM ARRAY BY VALUE, HERO(TRACER))
SET PLAYER ALLOWED HEROES(EVENT PLAYER, GLOBAL VARIABLE(T))
This code accomplishes the equivalent as the nested code from above, AND it’s way easier to read. I said earlier the global variable T
is temporary. That is, we don’t care about storing it’s value after we’re done using it in this rule, so it can be overwritten as a temporary variable for other rules. NEAT!
Now this is one way to accomplish the goal of creating an available list of desired heroes. Taking a full list of all 30 heroes in Overwatch and removing the ones we do not want one at a time. BUT! the key word you mentioned in your post is that you only wanted a handful of heroes. This is not the most efficient way to create your desired list if you only want to allow a few heroes.
Unfortunately it’s getting really late and I won’t be able to finish answering this question tonight. However, I’ll finish answering tomorrow night and I bet you can probably guess where I’m headed with this.
EDIT: I accidentally a word
@Timfoil sorry I didnt read your last wall of text (shame on me) so I dont know wether you have mentioned it, but the easiest way to limit the available heros would be in the non-workshop settings, like @SizzlinMelon you already did in your first version.
I was hinting last night the way you can make a limited list of heroes for your game-mode is by creating your own array of your handful of heroes. Instead of removing heroes from a full list, we’ll create our own array from scratch.
We’ll store this array in a temporary variable T
so we can reference it as we are building it. First we create the array with SET GLOBAL VARIABLE(T, EMPTY ARRAY)
. Then all we need to do is add the heroes we want to allow with the APPEND TO ARRAY
action. Say we only want to allow the player to play as Tracer, Winston, and Ana. Our code should look like this…
SET GLOBAL VARIABLE(T, EMPTY ARRAY)
MODIFY GLOBAL VARIABLE(T, APPEND TO ARRAY, HERO(TRACER))
MODIFY GLOBAL VARIABLE(T, APPEND TO ARRAY, HERO(WINSTON))
MODIFY GLOBAL VARIABLE(T, APPEND TO ARRAY, HERO(ANA))
Then all we have to do is replace this with our old array value in the SET PLAYER ALLOWED HEROES
action at the RESTRICT TO NON-MERCY HEROES -- NON-PRESIDENTS
rule.
SET PLAYER ALLOWED HEROES(EVENT PLAYER, GLOBAL VARIABLE(T))
Anyways TLDR:
old code
RULE: RESTRICT TO NON-MERCY HEROES -- NON-PRESIDENTS
TEAM: ALL
PLAYER: ALL
EVENT: ONGOING-EACH PLAYER
CONDITIONS: PLAYER VARIABLE(EVENT PLAYER, M) != TRUE
ACTIONS:
WAIT(0.250, RESTART WHEN TRUE)
SET PLAYER ALLOWED HEROES(EVENT PLAYER, REMOVE FROM ARRAY(ALL HEROES, HERO(MERCY)))
new code
RULE: RESTRICT TO NON-MERCY HEROES -- NON-PRESIDENTS
TEAM: ALL
PLAYER: ALL
EVENT: ONGOING-EACH PLAYER
CONDITIONS: PLAYER VARIABLE(EVENT PLAYER, M) != TRUE
ACTIONS:
WAIT(0.250, RESTART WHEN TRUE)
MODIFY GLOBAL VARIABLE(T, APPEND TO ARRAY, HERO(**ADD WANTED HERO HERE**))
MODIFY GLOBAL VARIABLE(T, APPEND TO ARRAY, HERO(**ADD WANTED HERO HERE**))
....
MODIFY GLOBAL VARIABLE(T, APPEND TO ARRAY, HERO(**ADD WANTED HERO HERE**))
SET PLAYER ALLOWED HEROES(EVENT PLAYER, GLOBAL VARIABLE(T))