Datadriven Units
This document covers every keyvalue of the npc_units_custom file
- General
- Boolean Values and Flags
- Selection Properties
- Sounds
- Abilities
- Stats
- Bounds
- Movement
- Health and Mana
- Armor and Attack Types
- Vision
- Lua VScript AI
- Creature Block
General
Most unit names start with "npc_" but this isn't necessary. A basic unit definition looks like this:
The definition of the default dota units can be found in npc_units.txt
Base Classes
There are a lot of classes for units, the complete list can be found in here, but as we don't have much control over their properties, only a few are really useful for custom units in general:
npc_dota_creature
The most useful baseclass, it doesn't have any critical hardcoded property so it's the go-to unit type for most units. It also allows the usage of the "Creature" block, which will is reviewed in the next section. It's linked to the
"DOTA_UNIT_TARGET_BASIC"
target type in abilities.There is however one simple property imposed to this unit type, which for the most part it's useful but it's good to keep in mind, and it's that abilities are automatically skilled up to the MaxLevel if possible (limited by the Level*2 of the creature, meaning a Level 1 creature will autolearn its abilities upto the 2nd rank). This can be of course modified through Lua
SetLevel
on each ability.npc_dota_building
Linked to
"DOTA_UNIT_TARGET_BUILDING"
, this baseclass can prove useful in many situations.It has the following properties imposed to it, which we have no control over them:
- Invulnerable by default. Very annoying, it can be removed through Lua with
building_handle:RemoveModifierByName("modifier_invulnerable")
- Visible through fog. This is troublesome, and forces any game that wants to have building strategies to use npc_dota_creature and define custom building damage, with some other downsides.
- No visual turning, even if internally the unit is actually changing its forward vector. Usually a good thing, the creature equivalent behavior for this is the stunned state.
Worth mentioningnpc_dota_tower
is a subclass of building, and is coded to trigger stuff like the announcers, team gold sharing and aggro AI. Use npc_dota_building with attack to make towers that aren't forced to use those mechanics.
- Invulnerable by default. Very annoying, it can be removed through Lua with
npc_dota_thinker
For dummy units. More on this later
For the rest of this guide, we'll be assuming a "BaseClass" "npc_dota_creature"
Level
"Level" "32"
This level can be accessed and modified with Lua though various creature functions.
Model and Scale
"Model" "models/heroes/dragon_knight/dragon_knight.vmdl"
"ModelScale" "0.8"
Self explanatory, get the models through the asset browser and set its size (it will use "1" by omission).
Creatures using models that are broken down for cosmetic equipment will be 'naked' unless we attach them wearables. More on this later.
Minimap Icons
"MinimapIcon" "minimap_candybucket"
"MinimapIconSize" "1000"
Produces:
Unit Label
"UnitLabel" "healing_ward"
This can be any name, its only useful purpose is to use with Lua GetUnitLabel()
which can work as an easy method of tagging units.
Boolean Values and Flags
"HasInventory" "1"
Associated Lua functions: HasInventory()
and SetHasInventory(bool)
Note: SetHasInventory(true)
won't work on units that didn't have "HasInventory" "1"
previously defined.
"IsSummoned" "1"
"CanBeDominated" "0"
Self explanatory, the default values are 0 for summoned (so the lua IsSummoned will always return false unless you set this), and 1 for dominated creaturesl
"ConsideredHero" "1"
"DOTA_UNIT_TARGET_FLAG_NOT_CREEP_HERO"
datadriven flag. Gives the unit a hero styled health bar:
"IsAncient" "1"
Associated Lua function: IsAncient()
"DOTA_UNIT_TARGET_FLAG_NOT_ANCIENTS"
datadriven flag.
"IsNeutralUnitType" "1"
Associated Lua function: IsNeutralUnitType()
"CanBeDominated" "0"
Helm of the Dominator specific. No associated Lua function, but it's easy to make one to read from this value if you wish.
"AutoAttacksByDefault" "0"
Ignores Auto Attack Behavior setting, forces to not autoattack. Used on Visage Familiars.
"ShouldDoFlyHeightVisual" "0"
Seems broken, no noticeable difference.
"WakesNeutrals" "1"
Unit won't aggro units on the Neutral team within their acquisition range.
Selection properties
"SelectionGroup" "string"
"SelectOnSpawn" "1"
"IgnoreAddSummonedToSelection" "1"
- SelectionGroup will make it so that all the units of this type are in a group which can be accessed through tab.
I pressed tab once and all these units got selected after defining them in the same control group
SelectOnSpawn forces the unit into the selection of the hero, even if the "Auto Select Summoned Units" setting is turned off. It's used on Visage Familiars.
IgnoreAddSummonedToSelection if set to 1, makes the "Auto Select Summoned Units" ignore this unit when it spawns. It's used on Brewmaster Primal Split units.
Sounds
"SoundSet" "Hero_DragonKnight"
"GameSoundsFile" "soundevents/game_sounds_heroes/game_sounds_dragon_knight.vsndevts"
"IdleSoundLoop" "Hero_DragonKnight.Tutorial_Intro"
SoundSet with the correct GameSoundsFile associated takes care of sounds like attacks and walking footsteps. The SoundSet string should be the first part of each of the hero sounds, which can be easily seen through the Dota 2 Sound Editor. Example
IdleSoundLoop will be played constantly after the unit spawns. Some heroes don't have a loop sound defined, but as in the example above it's possible to use this as an Spawn sound for the unit if you add the string of a non-loopable sound.
Abilities
"AbilityLayout" "4"
"Ability1" "" // Ability 1.
//"Ability2" ... up to "Ability16"
The unit can hold up to 16 abilities at any time being.
"AbilityLayout"
is used for the built-in Flash UI to change how many abilities it can display, and currently its limited to 4, 5 and 6 (anything else will malfunction)
Stats
Because of :valve: - reasons , unit stats aren't hover-able, but they are there.
Physical and Magical protection
"ArmorPhysical" "0"
"MagicalResistance" "0"
Attack Capabilities
"AttackCapabilities" "DOTA_UNIT_CAP_NO_ATTACK"
List of Attack Capabilities:
DOTA_UNIT_CAP_NO_ATTACK
DOTA_UNIT_CAP_MELEE_ATTACK
DOTA_UNIT_CAP_RANGED_ATTACK
Other Attack Stats:
"AttackDamageMin" "50" // Damage range min.
"AttackDamageMax" "40" // Damage range max.
"AttackRate" "1.7" // Speed of attack.
"AttackAnimationPoint" "0.75" // Normalized time in animation cycle to attack.
"AttackAcquisitionRange" "800" // Range within a target can be acquired.
"AttackRange" "600" // Range within a target can be attacked.
"AttackRangeBuffer" "250" // Extra range the target can move without canceling the attack
Ranged Attack Projectiles
"ProjectileModel" "particles/units/heroes/hero_lina/lina_base_attack.vpcf"
"ProjectileSpeed" "900"
Find hero/unit attack particles with the asset browser, filtering for the hero name + "attack vpcf"
If you have any "Melee to Ranged" mechanic, the unit definition should have a projectile speed, else it will default to 0, effectively making them never reach its target.
The things we could do...
"AttackDamageType" "DAMAGE_TYPE_ArmorPhysical"
This is seen in every unit file, but worthless/unsupported. In the future, we could see it being used to easily define Air/Ground attacks, Magic Attacks, etc, which currently require scripted abilities to simulate those behaviors.
Attribute Stats
Attributes are ignored for anything that isn't a hero unit, but because anything used to define units can also be used for npc_heroes_custom, these are the keyvalues, all self explanatory:
"AttributePrimary" "DOTA_ATTRIBUTE_STRENGTH"
"AttributeBaseStrength" "0" // Base strength
"AttributeStrengthGain" "0" // Strength bonus per level.
"AttributeBaseAgility" "0" // Base agility
"AttributeAgilityGain" "0" // Agility bonus per level.
"AttributeBaseIntelligence" "0" // Base intelligence
"AttributeIntelligenceGain" "0" // Intelligence bonus per level.
Bounty
If you want to make any complex rule for XP/Gold, for example, give less XP from this unit to heroes at a certain level, it's better to leave the values at 0 and grant it through lua.
"BountyXP" "0" // Experience earn.
"BountyGoldMin" "0" // Gold earned min.
"BountyGoldMax" "0" // Gold earned max.
Bounds
This defines the unit collision with other units.
"BoundsHullName" "DOTA_HULL_SIZE_HERO"
Bound Size Reference:
Value | Radius in Hammer units |
---|---|
DOTA_HULL_SIZE_SMALL | 8 |
DOTA_HULL_SIZE_REGULAR | 16 |
DOTA_HULL_SIZE_SIEGE | 16 |
DOTA_HULL_SIZE_HERO | 24 |
DOTA_HULL_SIZE_HUGE | 80 |
DOTA_HULL_SIZE_BUILDING | 81 |
DOTA_HULL_SIZE_FILLER | 96 |
DOTA_HULL_SIZE_BARRACKS | 144 |
DOTA_HULL_SIZE_TOWER | 144 |
- Lua
SetHullRadius(float)
can change this to any value in between or even above 144.
"RingRadius" "70"
The visible selection ring when the unit is selected
"HealthBarOffset" "250"
The height from the ground at which the Health Bar should be placed. By default this value is set to "-1" to use the models default height. The bigger the Model and ModelScale, this should be adjusted to a higher number so it doesn't look weird.
Movement
"MovementCapabilities" "DOTA_UNIT_CAP_MOVE_NONE"
"MovementSpeed" "300" // Speed
"MovementTurnRate" "0.5" // Turning rate.
List of Movement Capabilities
DOTA_UNIT_CAP_MOVE_NONE
DOTA_UNIT_CAP_MOVE_GROUND
DOTA_UNIT_CAP_MOVE_FLY
Less used movement-related values:
"HasAggressiveStance" "0"
Plays alternate idle/run animation when near enemies, e.g. Abaddon model
"FollowRange" "100"
Distance to keep when following. Healing Ward/Sigil have it set at 250.
Health and Mana
"StatusHealth" "150" // Base health.
"StatusHealthRegen" "0" // Health regeneration rate.
"StatusMana" "0" // Base mana.
"StatusManaRegen" "0" // Mana regeneration rate.
Notes:
- Negative Health/Mana Regen doesn't work.
- Setting StatusMana on 0 will make it not have a mana bar.
- There is currently no way of Setting MAX Mana in Lua! Unit mana pool modification has to be done with the Creature block and Levels.
Rarely used:
"StatusStartingMana" "-1"
-1 means default to full mana, which is the default. It can be changed to any integer value so the units don't spawn with a filled pool.
Armor and Attack Types
The Table of Physical Attacks vs Armor Types can be found here in this link to the dota wiki
"CombatClassAttack" "DOTA_COMBAT_CLASS_ATTACK_HERO"
"CombatClassDefend" "DOTA_COMBAT_CLASS_DEFEND_HERO"
Attack Types Table
Name | Dota Equivalent |
---|---|
Normal | DOTA_COMBAT_CLASS_ATTACK_BASIC |
Pierce | DOTA_COMBAT_CLASS_ATTACK_PIERCE |
Siege | DOTA_COMBAT_CLASS_ATTACK_SIEGE |
Chaos | DOTA_COMBAT_CLASS_ATTACK_LIGHT |
Hero | DOTA_COMBAT_CLASS_ATTACK_HERO |
Armor Types Table
Name | Dota Equivalent |
---|---|
Unarmored | DOTA_COMBAT_CLASS_DEFEND_SOFT |
Light | DOTA_COMBAT_CLASS_DEFEND_WEAK |
Medium | DOTA_COMBAT_CLASS_DEFEND_BASIC |
Heavy | DOTA_COMBAT_CLASS_DEFEND_STRONG |
Fortified | DOTA_COMBAT_CLASS_DEFEND_STRUCTURE |
Hero | DOTA_COMBAT_CLASS_DEFEND_HERO |
Vision
"VisionDaytimeRange" "1200" // Range of vision during day light.
"VisionNighttimeRange" "1800" // Range of vision at night time.
Vision on any unit can't exceed 1800, any value above that will just default to 1800.
Unit Relationship Class
This doesn't seem to make any difference, might be deprecated or just used for tagging stuff internally.
"UnitRelationshipClass" "DOTA_NPC_UNIT_RELATIONSHIP_TYPE_DEFAULT"
List:
DOTA_NPC_UNIT_RELATIONSHIP_TYPE_BARRACKS
DOTA_NPC_UNIT_RELATIONSHIP_TYPE_BUILDING
DOTA_NPC_UNIT_RELATIONSHIP_TYPE_COURIER
DOTA_NPC_UNIT_RELATIONSHIP_TYPE_DEFAULT
DOTA_NPC_UNIT_RELATIONSHIP_TYPE_HERO
DOTA_NPC_UNIT_RELATIONSHIP_TYPE_SIEGE
DOTA_NPC_UNIT_RELATIONSHIP_TYPE_WARD
Lua VScript AI
"vscripts" "path_to_ai_script.lua"
This will load a lua script file as soon as the unit is spawned. With a Spawn ( entityKeyValues ) function one can initiate a thinker to do any sort of logic, this is a very simple example for a unit that goes through a series of waypoints while casting spells anytime its possible: ai_tank_miniboss.lua.
Neutral Behavior
When you add a creep to the map and set it to the neutral team, the default is to turn it to a neutral. If you wan't to use a custom behavior, turn it off:
"UseNeutralCreepBehavior" "0"
"VisionDaytimeRange" "1200" // Range of vision during day light.
"VisionNighttimeRange" "1800" // Range of vision at night time.
Vision on any unit can't exceed 1800, any value above that will just default to 1800.
The concept of Modding Community doesn't go well together with Competitive Business
My Project Page || My GitHub Profile ||
Comments
The Creature Block
This KV is specific to the npc_dota_creature BaseClass, and goes inside the unit definition like this:
All the KeyValues detailed here go inside the Creature block. These were shipped/discovered with Holdout (as most of the first post KVs).
AttachWearables
An essential secondary block to make units use any cosmetics.
The numeric values for each
"IdemDef"
can be found in items_game.txt, by just opening the always-updated link provided or decompiling the file on the vpk at scripts/items/items_game.txt.Keep in mind that the latest cosmetic models aren't available in Source 2 yet, and attempting to use those codes will fail.
If you want to make sure a model exists, look it up on the model browser by its
"model_player"
name without the .mdl extension (Source 2 uses .vmdl)Level Up Parameters
Clumping Behavior
This should, in theory, improve the bump into each other behavior that all dota units have. In practice, it's kinda the same:
It was used on the Holdout Splitter golems.
Respawn
Doesn't seem to work, it didn't auto-respawn a ConsideredHero unit after any amount of time. In Holdout every unit has it at "0".
Disable Resistance
Cuts the disable duration of most stuns by a percentage.
These will be gained per each creature level.
Datadriven Creature AI
Its kinda useful for simple AI for AoE spells and Buffs, but more complex AI should be done through lua vscripts. The ability needs to be available on the units abilities definition.
State
**DefaultState* defines what will be the behavior based on the keys defined on the "States" secondary block.
Parameters:
Offensive Abilities AI
Example 1
Once the first skill goes on cooldown, it will attempt to use the Ability2 anywhere.
Example 2
This will use overpower and enrage when possible, and the 3rd ability when there are at least 2 targets in 275 radius.
Example 3
Attempts to not stack this unit debuff on a target that already has it
Example 4
Attempts to not stack this unit stun on a target that is already stunned (I don't think this ever worked :gaben: )
Defensive Abilities AI
The casting of this is tied to the
"Support"
value defined in the"States"
.Example 1
"Buff" "1"
will attempt to not stack the modifier on a target that already has it.Example 2
"UseSelfishly"
means to give priority on self-cast,"UseAtHealthPercent"
forces the usage of the skill after that threshold.Example 3
Cast the ability when there are at least 3 targets in 650 radius that can be Healed (?)
Escape Abilities AI
Will be used while in the Avoidance Flee mode.
Example
Items
Must have
"HasInventory" "1"
Example
The concept of Modding Community doesn't go well together with Competitive Business
My Project Page || My GitHub Profile ||
For the minimap icon stuff, those aren't all the MinimapIcon values. You can find more by looking at the minimap icon sprite sheets (.vmat files) in the asset browser (search asset browser for 'minimap').
Also, afaik the npc_dota_creature baseclass doesn't color the minimap icon to the owner's color, but npc_dota_creep will. Edit: Noya said that npc_dota_creature works
Treat everyday as if you are a student, not a master. The student learns, grows and sees beauty. The master becomes bitter, resentful, and stagnates.
I just tested and npc_dota_creature will color the minimap correctly when spawned through the datadriven
"SpawnUnit"
or LuaCreateUnitByName
as long as the Owner and ControllableByPlayer are defined correctly and put on the players team:(The pumpkin is a neutral)
The concept of Modding Community doesn't go well together with Competitive Business
My Project Page || My GitHub Profile ||
I have a lot of custom creeps (hundreds) walking around in my mod, and I found that literally a third of them would bug out, following their path at a snail's pace and even sometimes getting stuck inside each other and frozen in place. This also happens with just a few dozen creeps.
This fixed it, hands down, absolutely certain. Been running the map for over ten minutes and not a single creep has gotten stuck or slowed like before, and this was the only change I made.
EDIT: 25 minutes in, and it happened ONCE. Two creeps are stuck in place, endlessly trying to walk past one another. I stunned one of them and the other was able to walk around him so I'm certain they weren't even stuck inside each other like before.
EDIT2: 40 minutes - There are well over 500 creeps walking around now and my game is lagging like crazy but not a single creep is stuck, I'm stopping the test now. :gg:
There is no Datadriven to use items on target or self ?
We cannot solve our problems with the same thinking we used when we created them. The only source of knowledge is experience.
No, you'll have to use Lua AI for that.
The concept of Modding Community doesn't go well together with Competitive Business
My Project Page || My GitHub Profile ||
Having issues with "ConsideredHero" "1" Spells like Slarks pounce and Witch Doctors Death ward not targeting them. Is this just a issue I have or can people reproduce it?
Maybe there are some flags in the code you can change to suit your needs? @Joop
Played with it alot and it didnt work! I will keep trying
"ModelSize" doesn't seem to work in npc_heroes_custom.txt. However, I tried "ModelScale" and it worked just fine. Glad this works, because using hero:SetModelScale() in Lua doesn't transfer the new size to future illusions.
Invaluable guide, btw.
Sorry ModelSize was a typo (if you see the pastebin it already used ModelScale), it's always "ModelScale", fixed it now.
The concept of Modding Community doesn't go well together with Competitive Business
My Project Page || My GitHub Profile ||
Is there a way to use items, like the abilities??
The field "EquippedItems" is there to just add the item handles so they can be used on a lua vscripts later, check holdout_example in holdout_pudge_ai.lua there's good examples for item casting.
The concept of Modding Community doesn't go well together with Competitive Business
My Project Page || My GitHub Profile ||
I'm having some trouble attaching wearables.
Can I only attach wearables to a completely custom unit? I'm currently using
"override_hero" "npc_dota_hero_nevermore"
Yeah you can't attach to heroes, it needs to be a npc_dota_creature defined in npc_units_custom.txt
For hero cosmetic swapping you'll need Lua
The concept of Modding Community doesn't go well together with Competitive Business
My Project Page || My GitHub Profile ||
I'm having issues with DefensiveAbilities and OffensiveAbilities on non-hero units (ConsideredHero "0"). They just don't use any spells. When I set them to ConsideredHero "1" they do. Is this a bug or do I need to add something else to non-hero units?
Weird, my units on Warchasers seem to be casting correctly.
The concept of Modding Community doesn't go well together with Competitive Business
My Project Page || My GitHub Profile ||
I had this issue and I am sure it was to do with creature behaviours
is it possible to change the individual breakdowns for each attribute point? eg each 2 point in agi increases armor by 1 instead of each 7 point in agi increase armor by 1
It's possible but not directly through the datadriven unit definition. You have to use Lua for that, setting a timer to adjust the real stats every short intervals.
The concept of Modding Community doesn't go well together with Competitive Business
My Project Page || My GitHub Profile ||
This might be a super noob question, do bear with me. After I define the buildings in the .txt file, how do I put it on the map via hammer ?
i think this is how you do it, but i have not tried it before: use the entity tool to create 'npc_dota_building', then place it on your map. then click on it and change the 'Unit Name' property.
npc_dota_building works but it's better to just use
npc_dota_base
The concept of Modding Community doesn't go well together with Competitive Business
My Project Page || My GitHub Profile ||
Thanks for answering :), Noya, why is it so ? Doing so would require me to change the base class of the building in the script also right ?
Would anyone tell me if the "MinimapIcon" Key still works? I have tried several icons, inculding minimap_candybucket, but the map only shows a standard dot in the players color. Hope there is no interference with buildinghelper.
Probably doesn't work anymore because the sheet is gone, try this tutorial on minimap icons: https://moddota.com/forums/discussion/1067/custom-minimap-icons
The concept of Modding Community doesn't go well together with Competitive Business
My Project Page || My GitHub Profile ||
This tutorial still up to date? I have tried the described steps without success. I have worked with the example minimap_boat and was able to compile "minimap_boat.vmat_c" which was placed into /game/dota_addons/MY_ADDON/materials/vgui/hud/
(sources of the compiled output are placed in the corresponding "content" folder).
Afterwards I added
to my existing addon_hud_textures.txt file.
I was not sure about the path here. Should the key "file" be assigned with the path to the source file minimap_boat.vmat or the compiled file minimap_boat.vmat_c? - Tried both. No success. Finally I added
to my unit which is a npc_dota_creature. What is wrong? I dont have high demands to the minimap icons. If there are some basic icons that I can use without creating icons myself I´d be happy enough for the start.
Yeah it should still be up to date, or at least the minimap icons created via that method still work for me. Please redirect the question on that respective thread.
The concept of Modding Community doesn't go well together with Competitive Business
My Project Page || My GitHub Profile ||
i have this set-up, but my creature refuses to use ability2; does anyone know why?
Is it possible to make basic range attack targeting hero but in the way that projectile flying toward starting position and not following hero?