User:ArthurAutomaton/sandbox: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
(added a rambling account of a trigger problem)
mNo edit summary
Line 19: Line 19:
* [[Dota 2 Workshop Tools/Scripting/API/Global.CreateUnitByName|CreateUnitByName]]
* [[Dota 2 Workshop Tools/Scripting/API/Global.CreateUnitByName|CreateUnitByName]]
* [[Dota 2 Workshop Tools/Scripting/Built-In Unit Names|Built-In Unit Names]]
* [[Dota 2 Workshop Tools/Scripting/Built-In Unit Names|Built-In Unit Names]]
= Unofficial Dota 2 Modding Tools =
These tools have been created by members of the modding community and are not supported by Valve.


== Triggers and shared mutable state ==
== Triggers and shared mutable state ==

Revision as of 01:19, 24 August 2014

Sandbox

Some notes to myself about modding DotA 2.

Creating a unit that's controllable by a specific player

This code creates a mud golem at (0, 0, 0) on the Radiant team and makes it controllable by player 0:

unit_team = DOTA_TEAM_GOODGUYS
unit_name = "npc_dota_neutral_mud_golem"
player = PlayerResource:GetPlayer(0)
point = Vector(0, 0, 0)

unit = CreateUnitByName(unit_name, point, true, nil, nil, unit_team)
unit:SetControllableByPlayer(player:GetPlayerID(), true)


Relevant links:

Triggers and shared mutable state

Problem

I have two triggers, trigger_get and trigger_set. When trigger_set is triggered, I want to save some information in a certain variable. When trigger_get is triggered, I should be able to access that information.

An approach that doesn't work

Warning.pngWarning:Here is a common approach that DOES NOT WORK

1. Create scripts/vscripts/trigger.lua with the following content:

 FOO = 0
 
 function SetSharedVar ()
    FOO = 1
    print("SetSharedVar called; FOO = " .. FOO)
 end
 
 function GetSharedVar ()
    print("GetSharedVar called; FOO = " .. FOO)
 end

2. In Hammer, edit the properties of trigger_get as follows:

  • Set Entity Scripts = trigger.lua.
  • Add an output like this:
My Output Target Entity Target Input Parameter Delay Only Once
Io11.png OnStartTouch trigger_get CallScriptFunction GetSharedVar 0.00 No

3. In Hammer, edit the properties of trigger_set as follows:

  • Set Entity Scripts = trigger.lua.
  • Add an output like this:
My Output Target Entity Target Input Parameter Delay Only Once
Io11.png OnStartTouch trigger_set CallScriptFunction SetSharedVar 0.00 No

The expected outcome: When a unit steps on trigger_set and then afterwards steps on trigger_get, we expect to see the following output in the console:

SetSharedVar called; FOO = 1
GetSharedVar called; FOO = 1

What really happens: What we actually see in the console is this:

SetSharedVar called; FOO = 1
GetSharedVar called; FOO = 0

This shows that the assignment FOO = 1 made by SetSharedVar is NOT visible to trigger_get.

My guess about why this happens: When you "bind" some Lua code to an entity by setting its Entity Scripts property, that code is "private" to the entity: The entity initially has ITS OWN "blank" Lua environment (with only the library functions and the game API visible), which no other entity can access. When the map is loaded, the game engine populates this environment by running the Lua file specified by the Entity Scripts property. In our case, we set Entity Scripts = trigger.lua on both triggers, but they both get THEIR OWN COPIES of the global variables in trigger.lua. So the assignment FOO = 1 made by trigger_set is not visible to trigger_get since it just changes trigger_set's copy of FOO.

An approach that works

Follow steps 1-3 above but replace Step 2 with this:

2'. In Hammer, edit the properties of trigger_get as follows:

  • DO NOT SET THE Entity Scripts PROPERTY
  • Add an output like this (note that we now use trigger_set as the target):
My Output Target Entity Target Input Parameter Delay Only Once
Io11.png OnStartTouch trigger_set CallScriptFunction GetSharedVar 0.00 No

With this solution we get the expected output in the console. Why? If the guess above is correct, it's because we're now using trigger_set as the target, hence GetSharedVar now accesses trigger_set's copy of FOO.