Shard 0.4/dev
Moderators: hoijui, Moderators
- Forboding Angel
- Evolution RTS Developer
- Posts: 14673
- Joined: 17 Nov 2005, 02:43
Re: Shard
Shard builds some crap, then goes totally dormant
Re: Shard
Fixing the construction placement issue and general taskqueue construction details
Ok the values being handed to the engine are bad, and it looks like it's failing to find positions to build things ( though this seems nonsensical for stuff built by factories, I really need to see how to detect if the unit is a factory or not, as the code from my old AI obviously isnt working under the new API ).
For those with a little lua know how, the taskqueuebehaviour ( in dun dun dun taskqueuebehaviour.lua ) uses shards Build function to build things, but it passes no position parameter, and assumes shard will figure out where to build things on its own.
If however, you pass a second parameter for the position, you can call the API yourself with your own values, bypassing the borked values in the shard c++ code completely.
To get the position, one would need to call this function, specified in preload/api.lua:
So, if we look in taskqueuebehaviour.lua, here is the code that does the actual building:
here, the progress value if true, means to execute the progress queue function and attempt the next task. If Build is successful it will return true, and since 'not true' is the same as 'false', progress is set to false and we can safely wait until the unit is idle again and progress is set to true and the cycle repeats.
You'll notice that the unit value isn't the one handed over by the Shard API. There's a Shard framework unit which is a lua object, and then there's the object passed from C++. To access this, you will do local u = self.unit:Internal(), and then you can perform all the operations that are listed in the api docs on 'u'.
Where did this self.unit come from? It isn't defined in the behaviour, rather when the behaviour is created, the behaviourmanager object then inserts the value afterwards.
So back to building. First you'll notice we already have a unit type object called utype which we got several lines up using:
GetTypeByName takes a string, for example, to grab the unittype object for a core commander ( unitname "corcom" ) we would do:
Then to build it we would do:
Here Shard will figure out where to build it, so to tell it where we want it to be built, we would pass in a position:
Where did positiontobuild come from? Before this line we need to define it and then set its value using map:FindClosestBuildSite.
So we have our unit type 'utype'. To get out builder position we do:
Giving us this to put on line 102 :
This will search within 600 points of the builders location for somewhere that a unit of type 'utype' can be built. This unit must be a minimum of 2/minimumdistance footprints away from any other unit. These 2 values need to be fiddled to find the best ratio. To determine distance 1 footprint square is 8 points, and if you mouse over the terrain ingame, the coordinates in the tooltip are in the same units.
Some work best for big units, others work best for small units. Remember, tiny minimum distance results in LLTs blocking factory exits and gaps too small to fit units through, but good placement for large structures. Big values means nice spacious bases that are a dream to live in, but result in a hellish time trying to find places to put large structures. The obvious answer is to raise the search radius, but this has a hefty performance cost, and is the reason 0.29 spikey was, well, spikey.
If you want to experiment with taskqueuebehaviours.lua, you can put a copy in your overrides folder for your game. If you meet with success, send me a copy so I can replace the default copy, as well as ammend the default values in the C++ code! This also allows you to use nondefault values that work better for your game, or to use them on a per unit basis for maximum effect.
Also of note is that the Build method has the following incarnations:
There is also CanBuildHere, which can be used to test if a unit type can be built at a certain position.
Possible improvements I would suggest from NTai experience with this kind of system, is to randomly offset the builders location by a small amount, say 40 or 50, this way the builder can turn and start building immediately for small structures, whereas keeping the builders location could lead to that position being a valid spot, and the builder having to spend time moving out of the way.
Ok the values being handed to the engine are bad, and it looks like it's failing to find positions to build things ( though this seems nonsensical for stuff built by factories, I really need to see how to detect if the unit is a factory or not, as the code from my old AI obviously isnt working under the new API ).
For those with a little lua know how, the taskqueuebehaviour ( in dun dun dun taskqueuebehaviour.lua ) uses shards Build function to build things, but it passes no position parameter, and assumes shard will figure out where to build things on its own.
If however, you pass a second parameter for the position, you can call the API yourself with your own values, bypassing the borked values in the shard c++ code completely.
To get the position, one would need to call this function, specified in preload/api.lua:
Code: Select all
function map:FindClosestBuildSite(unittype,builderpos, searchradius, minimumdistance) -- returns Position
So, if we look in taskqueuebehaviour.lua, here is the code that does the actual building:
Code: Select all
self.progress = not self.unit:Internal():Build(utype)
You'll notice that the unit value isn't the one handed over by the Shard API. There's a Shard framework unit which is a lua object, and then there's the object passed from C++. To access this, you will do local u = self.unit:Internal(), and then you can perform all the operations that are listed in the api docs on 'u'.
Where did this self.unit come from? It isn't defined in the behaviour, rather when the behaviour is created, the behaviourmanager object then inserts the value afterwards.
So back to building. First you'll notice we already have a unit type object called utype which we got several lines up using:
Code: Select all
utype = game:GetTypeByName(value)
if utype ~= nil then
-- stuff that uses utype
end
Code: Select all
local corecommandertype = game:GetTypeByName("corcom")
Code: Select all
local u = self.unit:Internal()
u:Build(corecommandertype)
-- or using the other version:
u:Build("corcom")
Code: Select all
u:Build(corecommandertype,positiontobuild)
So we have our unit type 'utype'. To get out builder position we do:
Code: Select all
local builderposition = u:GetPosition()
Code: Select all
local builderposition = u:GetPosition()
local searchradius = 600
local minimumdistance = 2
local positiontobuild = map:FindClosestBuildSite(utype,builderposition , searchradius, minimumdistance)
self.progress = not self.unit:Internal():Build(utype,positiontobuild)
Some work best for big units, others work best for small units. Remember, tiny minimum distance results in LLTs blocking factory exits and gaps too small to fit units through, but good placement for large structures. Big values means nice spacious bases that are a dream to live in, but result in a hellish time trying to find places to put large structures. The obvious answer is to raise the search radius, but this has a hefty performance cost, and is the reason 0.29 spikey was, well, spikey.
If you want to experiment with taskqueuebehaviours.lua, you can put a copy in your overrides folder for your game. If you meet with success, send me a copy so I can replace the default copy, as well as ammend the default values in the C++ code! This also allows you to use nondefault values that work better for your game, or to use them on a per unit basis for maximum effect.
Also of note is that the Build method has the following incarnations:
Code: Select all
-- the Build methods now return true if it worked, false if the command was bad
function Build(UnitType)
function Build(typeName)
function Build(typeName, Position)
function Build(UnitType, Position)
Code: Select all
function map:CanBuildHere(unittype,position) -- returns boolean
Possible improvements I would suggest from NTai experience with this kind of system, is to randomly offset the builders location by a small amount, say 40 or 50, this way the builder can turn and start building immediately for small structures, whereas keeping the builders location could lead to that position being a valid spot, and the builder having to spend time moving out of the way.
Re: Shard
I will be busy today and tomorrow morning. If anybody tries to do this, do post updates, and I'm here to answer questions by email etc ( tarendai@darkstars.co.uk ), but I wont have free time with access to a machine with spring installed or build tools till saturday afternoon, so I cannot experiment myself until then. But, what I outlined in the previous post is probably how I will fix it anyway.
Re: Shard
My tests here show progress, although my test setup is a little limited in that I cant run windowed or I get driver crashes, My current setup has just ran a game of evorts and won in 1v1 shards, with less than 5 seconds of cumulative cpu time from the 2 shard AIs.
Re: Shard
Its just easier to have everything in one central place. The NTai thread for example was a pain because even after posting on my site, I had to update links in 4 or 5 places, and even then some people found more links and got the wrong stuff
Re: Shard
True, I understand the reason to have the central point for information.
But for example I was turned off at first because the starting post of this thread neither states the license nor that the source-code is available and still gives the impression it's a windows-only AI.
But for example I was turned off at first because the starting post of this thread neither states the license nor that the source-code is available and still gives the impression it's a windows-only AI.
Re: Shard
I don't have a linux environment to test in, or the will to set one up. I implemented the changes needed to use Shards copy of lua in cmake rather than springs, which should fix linux support, but since I cant test this, and I assume nobody else has either, I cannot verify this.
edit: LGPL V2, updated the starting post
edit: LGPL V2, updated the starting post
Re: Shard
Honest answer:
I don't know, I do know how I would figure that out, but I'm unwilling to invest the time and effort. If I did have the time to invest, I would be investing it elsewhere, e.g. further Shard development, as has been the case in the past.
I'll endeavour to avoid windows specific stuff, and keep the code cross platform, but I cant test under linux, and wouldn't know how to fix it if it was broken when I finally got it building anyway. If people find issues in the code not building under linux, Ill try to do what I can there too, but I dont have a linux build environment, or the knowledge to debug the build system when it goes wrong. The pay off for taking the time and effort is not worth it.
New features performance boosts and bugfixes trump personally verified linux support.
I don't know, I do know how I would figure that out, but I'm unwilling to invest the time and effort. If I did have the time to invest, I would be investing it elsewhere, e.g. further Shard development, as has been the case in the past.
I'll endeavour to avoid windows specific stuff, and keep the code cross platform, but I cant test under linux, and wouldn't know how to fix it if it was broken when I finally got it building anyway. If people find issues in the code not building under linux, Ill try to do what I can there too, but I dont have a linux build environment, or the knowledge to debug the build system when it goes wrong. The pay off for taking the time and effort is not worth it.
New features performance boosts and bugfixes trump personally verified linux support.
Re: Shard
Shard changelog so far for next version:
- Minor performance tweaks
- Units weren't being cleane dup internally after death correctly, fixed
- Support for hooks
- A sleep module for delaying actions by x number of frames
- Shard now handles being given units
- Its now possible to specify delays and breaks inbetween tasks as follows:
Code: Select all
local factory = { "eengineer5", { action="wait",frames=32}, "eengineer5", "elighttank3", "elighttank3",
- Updated Evo taskqueues
- The keyword "next" has been added to signify move to the next task, mainly useful as a return value on a task function when you have nothing to return
Re: Shard
nice one you two!
i merged latest master into pureint branch of Shard. it should now work with spring master. at least i did not get a crash for the first few in-game seconds, though Evo only showed its menu, the AI was loading in the background.
i merged latest master into pureint branch of Shard. it should now work with spring master. at least i did not get a crash for the first few in-game seconds, though Evo only showed its menu, the AI was loading in the background.