Vector targeting Lua library.

edited September 2015 in Tools

A Lua library for HoN-style vector targeted abilities in Dota 2.


  • DunDun
    Posts: 123

    Sweet. Drop dem Rumble ults!

    On the other note, I think people would be more motivated to try it out if you can attach a screenshot or gyfcat

  • Yep. I'll have one up in a second. I just finished fixing up the github readme

  • Updated with gif

  • That is Brilliant! What is that yellow bar thing and ball in the hud? :3

  • edited September 2015 Posts: 188

    I seem to have error. Tried with both table and just using defaults ("VectorTarget" "1") but both came with same error:

    [   VScript   ]: [VECTORTARGET] precaching assets
    [   VScript   ]: [VECTORTARGET] initializing
    [   VScript   ]: [VECTORTARGET] warning: PrecacheVectorTargetLib was not called.
    [   VScript   ]: [VECTORTARGET] registering event listeners
    [   VScript   ]: [VECTORTARGET] registering ExecuteOrderFilter (use noOrderFilter option to prevent this)
    [   VScript   ]: [VECTORTARGET] loading KV data
    [   Developer ]: scripts/vscripts/libraries/vector_target.lua:107: attempt to index local 'keys' (a number value)
    [   Developer ]:    scripts/vscripts/libraries/vector_target.lua:107: in function 'LoadKV'
    [   Developer ]:    scripts/vscripts/libraries/vector_target.lua:49: in function 'Init'
    [   Developer ]:    scripts/vscripts/gamemode.lua:190: in function 'InitGameMode'
    [   Developer ]:    ...ddons\dota2overflow\scripts\vscripts\addon_game_mode.lua:54: in function <...ddons\dota2overflow\scripts\vscripts\addon_game_mode.lua:52>
    [ W VScript   ]: Script Runtime Error: scripts/vscripts/libraries/vector_target.lua:107: attempt to index local 'keys' (a number value)
    [ W VScript   ]: stack traceback:
    [ W VScript   ]:    scripts/vscripts/libraries/vector_target.lua:107: in function 'LoadKV'
    [ W VScript   ]:    scripts/vscripts/libraries/vector_target.lua:49: in function 'Init'
    [ W VScript   ]:    scripts/vscripts/gamemode.lua:190: in function 'InitGameMode'
    [ W VScript   ]:    ...ddons\dota2overflow\scripts\vscripts\addon_game_mode.lua:54: in function <...ddons\dota2overflow\scripts\vscripts\addon_game_mode.lua:52>

    Only wrapping seemed to work. Even custom KV had issues.

    A feature I would like to request is way to determine what what end of spell is cast in cast filter. And also to dynamically choose PointOfCast (for example if I want the point of cast to be vector closest to the caster.).

  • edited September 2015 Posts: 12

    The yellow bar stuff is UI from my custom game. I was just too lazy to disable it for the demo gif. :P

    Whenever you get an error like that it's usually the result of a syntax error in your KV files. This also means that any incorrect syntax in your ability definitions could trigger this kind of error, since by default it directly loads from npc_abilities_custom.txt,

    What does your KV look like? Perhaps it wasn't clear in the documentation, but it expects the exact same structure as npc_abilities_custom.txt, so you need some kind of top-level block that contains all of your ability definitions, like this:

    "root"  // the name of this doesn't actually matter because LoadKeyValue ignores it
            "VectorTarget"  "1"
          "VectorTarget"    "1"

    It's designed this way so that all you have to do is drop "VectorTarget" keys into your dota ability KVs and it will just work.

    Based on the error message it seems like LoadKV isn't getting this top-level table of ability names, or there's a random number in the top-level of your npc_abilities_custom.txt somewhere. Not sure. The error handling in these cases should be improved I think.

    If you were passing a Lua table it should look like:

    VectorTarget:Init({ kv = {
        ability_1 = { VectorTarget = "1" },
        ability_2 = { },
        ability_3 = { VectorTarget = "1" }

    As for the feature requests: exposing the targeting information to CastFilters is probably a good idea, though it will take a bit of work.

    You can actually already dynamically choose PointOfCast by defining GetPointOfCast on a Lua ability, I just didn't document it. :P If you look at the WrapAbility code you can see that it checks for pre-existence of several methods and doesn't override those if they already exist.

    EDIT: Actually, overriding GetPointOfCast will not do what you expect currently because of the way the order filter is coded. In an older version it would have allowed overriding of the point of cast, but currently it doesn't. I'll work on adding this behavior.

    EDIT: Added here Basic tests seem to confirm that it works as expected.

  • What kind of cast filters did you have in mind? That's something I'm looking to improve in the options, for example, by enforcing things like min/max distance options. I'd rather add these kinds of things to the options rather than requiring people to write their own cast filters.


    I improved the error reporting a bit for the KV loading, and made it so that top-level junk in the KV will trigger a warning message instead of an error. This should help you in the future when debugging KV syntax issues.

    I also removed several debugging print statements that I had forgotten about (maybe later we can add them back in as a debugging option), and now the VERSION is encoded as an array of numbers rather than a single number (so that stuff like 0.5.1 can be encoded and checked)

    Consider the library unstable until I start tagging releases in git and writing changelogs. For now, everything is subject to breaking changes.

  • edited September 2015 Posts: 12

    EDIT: removed. information added to posts above

  • this is awesome

  • edited September 2015 Posts: 188

    The problem might have been in npc_abilities_custom.txt I had "Version" "1"
    I would like simple boolean value for cast filter part of my lua ability to use. self:IsTerminalVector() or something to return if the player is doing the first or the second part of the spell.
    Another thing that comes to mind would be let me use optional cast with this. I would like to redo my blink staff/support ability with this lib.

    2. On ctrl target call's for vector cast. (I need a way in my lua ability to opt-out from vector casting) And then you can select point to blink the target to. (with max distance)

    This would also mean that having control entity for client side particle's starting point.
    my custom kv (that also produced error) was this:

            "VectorTarget" "1"
  • BUG: Attempting to buy an item causes error at line:185 (you order filter)

  • Hm, okay. My custom game currently doesn't have any items yet so I guess I never ran into that case. Also, I'd prefer to use github's issue tracker for reporting bugs as it makes it easier to organize everything.

  • Also I'd need more information than just "an error"

  • edited October 2015 Posts: 188

    Didn't have time to re-produce the bug yet but some feedback from (while beta testing dota2overflow) @Perry and @Azarak indicated that they would like targeting method even closer to HoN (click and drag).
    Could it be possible to check client side if player holds the mouse button longer (0.25 seconds?) the game assumes click and drag. If player simply clicks then it assumes the current method (click, click again!).

  • edited October 2015 Posts: 12

    Yes that's something I wanted to implement at some point. There's different ways to go about it.

    For my game, I plan to create a custom options UI that has a "fast click-and-drag behavior for vector targeting" checkbox that you can enable, but by default it won't do that. Other people might want different behavior, or to always enforce the click-and-drag mechanic. So the three ways to enable the behavior that make sense to me are:

    1. An option to Init to enable it globally
    2. An option in the ability KV to enable it per-ability
    3. An option in the client-side API to enable it per-player

    I don't see a reason not to support all of these possibilities, with option 3 taking precedence over 2, and 2 over 1.

    As for the actual mouse button logic, it's fairly straightforward: all you have to do is detect a mouse click release while targeting is in-progress (e.g. if(eventKeys.abilId) ), and then make an ExecuteAbility call. But I likely won't have time to write any significant code in the next few days.

  • Added some basic client-side support for the feature, enabled by default. Unfortunately it doesn't work with quickcast though, because as far as I know you can't detect a key release event.