Scripting - Basics [Calibas Tutorials #7]

edited March 2016 in Tutorials

This tutorial will introduce you to the real meat & potatoes of Dota 2 modding, scripting. I'll go over where to begin, and give you a simple example of what you can do through scripting.

enter image description here

Dota 2 custom games are controlled through a programming language called Lua, and if you want to create anything other than a very simple addon, you'll need to know how to use Lua. Luckily, it's not a very complicated language and if you already know the basics of computer programming you shouldn't have much trouble learning it.

Central to any custom game is the addon_game_mode.lua file, which is generated automatically when you create a new addon. The example I'm going to show below is from a new addon created through the Create Empty Addon option, and if you use Create New Addon From Existing Addon the initial contents of the addon_game_mode.lua file may be different.

You'll need to load the script in a text editor (I recommend Notepad++) and you'll need to find the file's location. On my computer it's located at: C:\Program Files (x86)\Steam\steamapps\common\dota 2 beta\game\dota_addons\YOUR_ADDON_NAME\scripts\vscripts

Here's the initial contents of my addon_game_mode.lua:

-- Generated from template

if CAddonTemplateGameMode == nil then
    CAddonTemplateGameMode = class({})

function Precache( context )
        Precache things we know we'll use.  Possible file types include (but not limited to):
            PrecacheResource( "model", "*.vmdl", context )
            PrecacheResource( "soundfile", "*.vsndevts", context )
            PrecacheResource( "particle", "*.vpcf", context )
            PrecacheResource( "particle_folder", "particles/folder", context )

-- Create the game mode when we activate
function Activate()
    GameRules.AddonTemplate = CAddonTemplateGameMode()

function CAddonTemplateGameMode:InitGameMode()
    print( "Template addon is loaded." )
    GameRules:GetGameModeEntity():SetThink( "OnThink", self, "GlobalThink", 2 )

-- Evaluate the state of the game
function CAddonTemplateGameMode:OnThink()
    if GameRules:State_Get() == DOTA_GAMERULES_STATE_GAME_IN_PROGRESS then
        --print( "Template addon script is running." )
    elseif GameRules:State_Get() >= DOTA_GAMERULES_STATE_POST_GAME then
        return nil
    return 1

It may look intimidating to the beginner, but there's nothing too complicated there. CAddonTemplateGameMode is your addon's main class, which is created if it doesn't already exist. It goes through precaching any files your addon may need, though at the moment it doesn't load anything since it's all commented out. There's a little more about precaching here if you're interested and there's some good supplemental info there about how the addon_game_mode.lua file works.

Next it activates your game mode, which executes all the code within the Activate() function when the game first starts. The first line within Activate() tells Dota 2 to use the CAddonTemplateGameMode class in your game, then it runs the InitGameMode() function which contains all the useful code for initializing your game mode.

The last part of the code has to do with setting up a thinker function, which is code that can be run repeatedly while the game is going. SetThink( "OnThink", self, "GlobalThink", 2 ) is what starts the thinker function, where the argument "OnThink" is the function called, self is the context of the thinker function, "GlobalThink" is the name of the thinker slot and 2 is initial delay in seconds before OnThink() is first called.

The OnThink() function is fairly straightforward, all it's doing at the moment is checking the game's state to see if it's still in progress or not. Whatever number the thinker function returns is the delay in seconds before it runs again. If the game is over, it returns nil, which ends the thinker function and unregisters it, otherwise it returns 1 and OnThink() runs again after 1 second. For more on thinker functions, see this article.

Now let's get into how to actually change the code around. As of the Reborn beta, when a custom game first starts you see a team select UI by default. This is called the Custom Game Setup phase, and it can be used for a whole lot more than just team select. I wont go too deep into how that works at the moment, in fact I'm just going to show you how to disable it, but if you want to learn more about how Custom Game Setup works, you can go here.

Skipping the phase is easy, within your InitGameMode(), you can set the length of time you stay in this phase to 0 with the SetCustomGameSetupTimeout() function. Of course, if you do this no team will be assigned, and players will enter the game as spectators, so you'll want to also use SetCustomTeamAssignment() to set the player's team. Here's how to use both of those functions:

function CAddonTemplateGameMode:InitGameMode()
    print( "Template addon is loaded." )
    GameRules:GetGameModeEntity():SetThink( "OnThink", self, "GlobalThink", 2 )

    PlayerResource:SetCustomTeamAssignment( 0, DOTA_TEAM_GOODGUYS )
    GameRules:SetCustomGameSetupTimeout( 0 )

Update your code with those new lines, save it, then you can build your map again with Hammer and have it launch the game. However, if you're just editing the code and you don't need to build your map again, you can use the console to make things easier. Open up the console, and enter this command:

dota_launch_custom_game YOUR_ADDON_NAME template_map

Your addon's name is whatever you entered when you first created it, and it's also the name of the folder your addon lives in. You can enter in a different map too if you want, template_map is simply a blank map created by default.

Upon launching your game you should now skip the team select screen. This is useful for creating something like a cooperative game mode, or if you want to write your own code for team selection. If you do want players to be able to select their own teams, you can simply remove the two lines of code we added.

This part of a series of 7 tutorials that are designed to help the beginner get familiar with the Workshop Tools and they end with showing how to write a very simple script.

1. Getting Started, Your First Dota 2 Addon

2. Creating A Basic Dota-style Map

3. Level Design - Adding Terrain & Decorations

4. Level Design - Tilesets, Material Sets & Transitions

5. Level Design - Meshes & Materials

6. Material Editor - Creating New Materials and Overlays

7. Scripting - Basics


  • Posts: 1,670

    Two things I'd change/improve on:

    1. The Lua manual is not recommended for a read-through manual. It's too long, has irrelevant sections and often doesn't have good examples. I'd recommend learn lua in Y minutes and checking many popular addons on GitHub.
    2. Notepad++ is not recommended either. Use Sublime + Dota Lua + Dota KV as your IDE.
    3. SetThink is inefficient/leaks and Barebones Timers should be used pretty much every time instead. In the same way, when starting a new mod, it is recommended that you grab the newest version of BMD's Barebones, as it will really ease your entry point in the development of a clean addon.

    A good follow up to this guide, focusing on scripting, is my own Beginners Guide to Scripting

    Happy modding!

    The concept of Modding Community doesn't go well together with Competitive Business
    My Project Page || My GitHub Profile ||