Page 1 of 3 1 2 3 LastLast
Results 1 to 10 of 24

Thread: August 24 Bot Update

  1. #1
    Valve Developer
    Join Date
    Sep 2011
    Posts
    1,704

    August 24 Bot Update

    Bot Pathing:

    • Added Action_MoveDirectly to move to a location while bypassing the bot pathfinder (uses normal pathfinding).
    • Added GeneratePath( vStart, vEnd, tAvoidanceZones, funcCompletion ) to the global bot script API. It takes a start location, and end location, a table with an array of packed avoidance zones (3-vectors of x, y, and radius), and a function to call when the pathfind completes. The specified function should two parameters: the overall length of the path and a table containing waypoints along the path. If the pathfind fails, it will call the function with an empty waypoint table.
    • Added AddAvoidanceZone( vLocationAndRadius ) and RemoveAvoidanceZone( iZone ) to the global bot script API. AddAvoidanceZone adds a packed avoidance zone (3-vector of x, y, radius) that GeneratePath() will not path through. It returns an index to the newly-created avoidance zone. Avoidance zones can be removed by calling RemoveAvoidanceZone with that index.
    • Added Action_MovePath( tWaypoints ) to the bot script API. It takes the waypoint table returned from GeneratePath() and paths a bot along it.
    • Added the queue and push variants of the above Action_ functions.


    Bot State Dumping:

    Servers can now be run with a -botworldstatetosocket <port> parameter. This will cause the server to generate a protobuf containing the full bot-visible worldstate to that team, and send it as binary array (SerializeToArray) to the specified localhost socket. Each of these data blocks is prefaced by 32-bit integer containing size of the block.

    This is intended for doing offline or external analysis of running games. The protobuf it generates is attached to this post.
    Attached Files Attached Files

  2. #2
    Basic Member
    Join Date
    Dec 2016
    Posts
    732
    Awesome stuff!!!

  3. #3
    Basic Member
    Join Date
    Dec 2016
    Posts
    732
    Unrelated to Bot-API (most likely) but related to Custom Game Addon API ... the
    Say() function API seems broken.

    This API Link says the 3rd parameter is a boolean for team versus all speak. But... it seems to be broken.

    When set to "false" I see the message double printed - once to (Allies) and once to (All).
    When set to "true" the game out-right crashes.

    The conditions are:
    - I initially load as the first player, but the code over-writes my hero to the bot
    Code:
    GameRules:GetGameModeEntity():SetCustomGameForceHero("npc_dota_hero_nevermore")
    hero = Entities:FindByName (nil, "npc_dota_hero_nevermore")
    Say(hero, "Getting Latest Model..", false)
    Last edited by nostrademous; 08-25-2017 at 05:18 PM.

  4. #4
    Basic Member
    Join Date
    Mar 2012
    Posts
    2,019
    Quote Originally Posted by ChrisC View Post
    Bot Pathing:

    • Added Action_MoveDirectly to move to a location while bypassing the bot pathfinder (uses normal pathfinding).
    • Added GeneratePath( vStart, vEnd, tAvoidanceZones, funcCompletion ) to the global bot script API. It takes a start location, and end location, a table with an array of packed avoidance zones (3-vectors of x, y, and radius), and a function to call when the pathfind completes. The specified function should two parameters: the overall length of the path and a table containing waypoints along the path. If the pathfind fails, it will call the function with an empty waypoint table.
    • Added AddAvoidanceZone( vLocationAndRadius ) and RemoveAvoidanceZone( iZone ) to the global bot script API. AddAvoidanceZone adds a packed avoidance zone (3-vector of x, y, radius) that GeneratePath() will not path through. It returns an index to the newly-created avoidance zone. Avoidance zones can be removed by calling RemoveAvoidanceZone with that index.
    • Added Action_MovePath( tWaypoints ) to the bot script API. It takes the waypoint table returned from GeneratePath() and paths a bot along it.
    • Added the queue and push variants of the above Action_ functions.
    Welcome back Chris! WOW ! I asked for custom avoidance zones support and now I have it And I think Platinum asked for more pathfinding support

    So please confirm I understand this correctly:
    Code:
    local customAZ = nil;
    local npcBot = GetBot()
    
    -- custom wp
    local function MyPath ()
    	local myWaypoints = {Vector(1, 2}, Vector(1, 4)};
    	npcBot:Action_MovePath(myWaypoints);
    end
    	
    -- generated wp
    local function EventNewPath (nLength, tWayPoints)
        if (tWaypoints == nil) then 
            print("Path is not reachable");
        else
            npcBot:Action_MovePath(tWaypoints);
        end
    end
    
    -- avoid this zone in generated wps
    local function AvoidPath ()
    	customAZ = AddAvoidanceZone(Vector(1.5, 2.5, 500));
    end
    
    -- test wp generation
    local function GenerateNewBotPath ()
    	GeneratePath( Vector(999999999999, 999999999999}, Vector(999999999999, 999999999999), nil, EventNewPath); -- should fail
    	GeneratePath( Vector(1, 2}, Vector(1, 4), nil, EventNewPath);	-- will avoid Vector(1.5, 2.5) within 500 units
    	RemoveAvoidanceZone(customAZ);
    	GeneratePath( Vector(1, 2}, Vector(1, 4), {Vector(1.5, 2.25, 500), Vector(1.5, 2.5, 500)}, EventNewPath);
    end
    Is this the correct way to use them?

    Regarding #1, what is the difference between "normal" and "bot" pathfinding? Does MoveDirectly() behave like the player-controlled rightclick ? (meaning that the action completes EVEN IF the actual location is not reachable but it is ALMOST reachable) ATM bots will hang the queue trying to complete a move-to queued action if the target path is not reachable but it is almost reachable (meaning if a waypointed path would execute for a player controlled hero, it won't for bots because they expect to reach the actual coordinates - those were the results in some of my tests); this is where IsLocationReachable(vLocation) would be useful
    Regarding #3, will the custom AZ be returned by GetAvoidanceZones() ? If not, how do we iterate through them? Also, how long are the zones available for? I was thinking that maybe an expiration delay (0 meaning never, unless we call RemoveAvoidanceZone() manually) might help? For example areas where we know a sentry or observer was just planted. But if it complicates the code maybe it's not worth it. Not sure if it will be needed but is there a way to differentiate between them? If I understood how GetAvoidanceZones() works, it returns marked zones resulting from abilities (such as ice path, freezing field, black hole etc.) correct? And in addition it will return custom ones, right?
    Regarding #1 and #4, what is the action returned by those 2 commands? Is it still BOT_ACTION_TYPE_MOVE_TO?
    Last edited by The Nomad; 08-26-2017 at 01:08 AM.
    Explanations on the normal, high and very high brackets in replays: here, here & here
    Why maphacks won't work in D2: here

  5. #5
    Valve Developer
    Join Date
    Sep 2011
    Posts
    1,704
    Code-wise: I think you want EventNewPath as the fourth parameter in all your calls to GeneratePath, but yeah other than that it looks right. You also probably need to cache off the bot that you're generating a path for because when that pathing callback is called I don't believe GetBot() is accessible.

    Bot pathfinding uses a first-pass pathfind though the bot's pathing grid, using the weights from the built-in bot avoidance system -- it makes pathing through towers, etc more expensive. "Normal" is just a straight-up right-click.

    These avoidance zones (completely avoided by GeneratePath) are entirely independent of the default bot avoidance zones (which are used for weighting when bot pathfinding). Yes, it's kind of confusing. :-/

    The intention of the default-bot avoidance zones is that they're applied to all bots on a team, and have some information contained within them ("does physical damage", "does magical damage") etc, and different bots would react to them differently based on their details (tanky guy can ignore physical damage, if you have bkb active you can ignore the magic ones, etc). In practice, I don't think this actually works that well because they don't really capture the full breadth of the circumstances of avoidance for a given bot. I suspect that managing a moment-to-moment "absolutely do not path through this zone" list for each bot, along with a few generic "this is so bad that one one should go through it" zones works better for the specific details of what each bot wants to avoid. So that's the idea behind these new avoidance zones (and if I had the built-in ones to do over, I think that's how I'd write them). So I guess my recommendation is to punt on the old avoidance stuff entirely.

    There's no way to iterate through them currently other than you building a table of them as you add them. If it would be useful, I could add an iterator.

    Currently they last forever, but yes I could definitely add an expiration duration that you could supply when you added one. I could definitely see that being useful.

    Oh, yes, there's a new action for them, it's...um...BOT_ACTION_TYPE_MOVE_TO_DIRECT I think? I can check on Monday, but it's definitely added to the API.

  6. #6
    Basic Member
    Join Date
    Dec 2016
    Posts
    180
    Bot pathing is awesome. previously i create 2 classes( of course they are not actually class ) for creating and moving along the path. but this update may make coding easier.

    Many thanks to Chris for Bot State Dumping but 2 question comes to my mind( may be silly ):

    1- Is this table ( CMsgBotWorldState ) global for bot_generic? what i mean can we take all its parameters at any time?
    2- Is there anyway to add our own parameters to this table, for example i want to track variables that i used in my last hit function for specific hero( like antimage )?

    Hope we see some more updates about decision making

  7. #7
    Basic Member
    Join Date
    Mar 2012
    Posts
    2,019
    Quote Originally Posted by ChrisC View Post
    Code-wise: I think you want EventNewPath as the fourth parameter in all your calls to GeneratePath, but yeah other than that it looks right. You also probably need to cache off the bot that you're generating a path for because when that pathing callback is called I don't believe GetBot() is accessible.
    oops, copy-paste error as I was writing it before bed (corrected in case others want it as a reference). As you prolly guessed, it was just notepad scribbling without an actual test for a PoC. And you're right, the callback context wouldn't have the handle, so I corrected the PoC with the classic npcBot to make more sense

    Quote Originally Posted by ChrisC View Post
    Bot pathfinding uses a first-pass pathfind though the bot's pathing grid, using the weights from the built-in bot avoidance system -- it makes pathing through towers, etc more expensive. "Normal" is just a straight-up right-click.
    Aha, so, that sounds like for certain modes or states where fighting would not be an issue (in certain situations - like "afk" jungling) it could reduce overhead and improve performance

    Quote Originally Posted by ChrisC View Post
    These avoidance zones (completely avoided by GeneratePath) are entirely independent of the default bot avoidance zones (which are used for weighting when bot pathfinding). Yes, it's kind of confusing. :-/

    There's no way to iterate through them currently other than you building a table of them as you add them. If it would be useful, I could add an iterator.
    Thought so

    Quote Originally Posted by ChrisC View Post
    Currently they last forever, but yes I could definitely add an expiration duration that you could supply when you added one. I could definitely see that being useful.
    TYVM. The idea is, you keep adding events every few patches and this makes us improve code by deleting IF checks that are performed every frame. I had the damage event done in Think(), before you added it so it is a huge help. While we could manage expiration with frame-by-frame checks as well, an expiration param would deffinitely be faster and better so thank you for considering it

    Quote Originally Posted by ChrisC View Post
    Oh, yes, there's a new action for them, it's...um...BOT_ACTION_TYPE_MOVE_TO_DIRECT I think? I can check on Monday, but it's definitely added to the API.
    No hurry moddota will prolly scan the _G table for it and publish it. It was just a fyi matter mostly
    Explanations on the normal, high and very high brackets in replays: here, here & here
    Why maphacks won't work in D2: here

  8. #8
    Then how we can get the binary array (SerializeToArray) from the server when running with a -botworldstatetosocket <port> parameter ?

  9. #9
    Basic Member
    Join Date
    Dec 2016
    Posts
    32
    great addition to the api thank you, i just want to report a visual bug relating DebugDraw* functions (the same for
    dota_bot_debug_team) the lines and circles are drawn with a huge offset and the entier thing is croped in the right and bottom, (it may be related to my local machine because no one reported this).

    EDIT:

    Quote Originally Posted by The Nomad View Post
    Try this command in the console:
    Code:
    mat_viewportscale 1
    Last edited by DzeeRay; 08-26-2017 at 11:00 AM.

  10. #10
    Thank you Chris!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •