View Full Version : Modding AI
fenwe
11th Oct 06, 9:39 PM
Hello all, I am currently working on the skirmish AI. I started with Axis because it is what I like to play. It seems as parts and pieces of this AI are largely unfinished. One of the things that I can't find to fix it, is where a unit would be "reinforced" and the name of of the variable that I would assume would contain "reinforcements_ability". I am assuming that where the calculations take place for this would be in player_abilities.ai. A comment in that file says "-- s_player_ability_list (set in strategy_command_tree.ai and defined in player_ability_defs.ai)"
But I can't find player_ability_defs.ai, so if I am just over looking it, that would probably point me in the right direction.
Any help on this would be greatly appreciated!
Oh, and when I mean unfinished, probably a better word would be unpolished, or rough.
Kyranzor
11th Oct 06, 11:56 PM
i saw a section in one of the AI files that mentioned allocating funds to reinforcing squads etc. did you want to limit or increase that?
Mr. Bildo
12th Oct 06, 5:42 AM
What you want to do is increase or decrease the demand for a particular unit to be reinforced. I'm not going to try to explain it in this post, but if you look at data\ai\strategy_unit_purchase.ai it should give you some idea as to what I'm talking about.
As far as the overall ai and SCAR, part of the problem is that many of the functions that are being called appear to be buried in the .dll's, probably WW2Mod.dll. Without an SDK, it's difficult to do much.
--Mr. Bildo
fenwe
12th Oct 06, 7:42 AM
I'm trying to increase the probability that the AI will buy replacement troopers for squads that have been damaged in combat. I also want the AI to stop using the medkits so often. I have been able to trace, by eye, the fact that 80-90% of this stuff is actually being done in the whole AI section of code with only some of it being "hidden". My main problem though is that without some documentation I just can't figure out what some of the variables need to look like so that I can call them or use them directly. As an example, when you look through the individual units to decide what the AI is deciding the priority of what to build it is ebp.AXIS_HVYMGP (I'm at work, so this is from mmemory). If I knew what the variable name was for the reinforce ability, I could find when it was being evaluated in the player_ability code and go from there.
OK, lets take a half step back. There are debug statements that are being "printed" out. Do you guys know where those staements are being "printed to" so that I can trace them? How about some way to set break points? This whole lua thing is new to me.
Also, does anyone need some sample code for how to mod more of the AI than just playing with the default parameters? I have been able to successfully play with strategic unit purchase stuff, the build order(s), and the tech stuff.
Thanks for your help!
Mr. Bildo
12th Oct 06, 10:33 AM
I have been able to trace, by eye, the fact that 80-90% of this stuff is actually being done in the whole AI section of code with only some of it being "hidden".
The more I look at it, the more I think that while there is a lot of script in the AI, most of the stuff that is actually telling the units to perform specific tasks is more or less being done in WW2Mod.dll.
My main problem though is that without some documentation I just can't figure out what some of the variables need to look like so that I can call them or use them directly. As an example, when you look through the individual units to decide what the AI is deciding the priority of what to build it is ebp.AXIS_HVYMGP (I'm at work, so this is from mmemory). If I knew what the variable name was for the reinforce ability, I could find when it was being evaluated in the player_ability code and go from there.
I totally agree. The problem is that A LOT of the consts, variables and functions are not in the scar. I would bet the farm they are defined in WW2Mod.dll. In fact, anything you can't find defined anywhere in script, do a simple binary search for the string and you'll most likely find references to it in WW2Mod.dll. It's going to be hard to go a lot further without a proper SDK.
OK, lets take a half step back. There are debug statements that are being "printed" out. Do you guys know where those staements are being "printed to" so that I can trace them?
No, the few times I tried to use them nothing appeared in the console or files. I cheat and push my debug output through the "stinger" code.
How about some way to set break points?
Again, with an SDK, you could probably run in debug. It would be great if Relic provide their debug files. As far as the script, I believe it is an interpreted language and it's doubtful you'd be able to debug it directly, but I may be underestimating their engine.
This whole lua thing is new to me.
If you know any high-level programming languages, you won't be guessing for long. LUA is very simple.
Also, does anyone need some sample code for how to mod more of the AI than just playing with the default parameters? I have been able to successfully play with strategic unit purchase stuff, the build order(s), and the tech stuff.
Unless someone out there is really sandbagging their knowledge, I'm pretty sure that's about as far as most of us have gotten. You start to hit a wall after awhile when you realize that there are function calls and variables that are not being defined anywhere in the script.
--Mr. Bildo
fenwe
12th Oct 06, 11:15 AM
Can you give me an example of some of the functions that that you think are in the dll? I know that they have some initialization functions that are hidden from us, but for the things I have been looking at, and I always start small so please excuse my ignorance, I have been able to find and flesh out a lot of stuff. The biggest problem has been the fact that it is obvious that they use what amounts to "global" function pointers, so some of this stuff looks like it is completely unconnected. I could just be missing something because I don't know what I am looking for yet :) Of course, the fact that I haven't been able to actually find the struct that defines the list of abilities as constants like a lot of this other stuff more than likely means you are correct.
What is "stinger" and how do you use it?
The language itself is cake, the problem comes in when your trying to de-engineer existing "sample" code and you don't know the difference between an inbuilt function, a defined function that you can play with, and one that may or may not be hidden from you because you just didnt' search for it correctly, but then this kind of the is always a labor of love.
What is startling though is how unfinished the existing code actually is though. Just comparing the Allie vs Axis code shows that they just stopped doing any AI work after a certain point, and that is just for the things that we can see. Have you looked at the strategy_unit_purchase stuff yet? At least a 1/4 of the Axis stuff wasn't evaluated at all in their own tables and the ones that are aren't correct. By their rating system the absolute best unit in the game against all types of units is the officer, followed very closely by the Stormies and Grens, so when you finally get the AI to actually start building them, they spam them for ever. *shrug* And then they run back to to get healed like they are "supposed to" only to mill a round like sheep waiting to get "healed". *sigh*
Did you do DOW AI stuff? Do you know if they helped out at all with the AI mod community?
naradaman
12th Oct 06, 3:33 PM
My main problem though is that without some documentation I just can't figure out what some of the variables need to look like so that I can call them or use them directly. As an example, when you look through the individual units to decide what the AI is deciding the priority of what to build it is ebp.AXIS_HVYMGP (I'm at work, so this is from mmemory). If I knew what the variable name was for the reinforce ability, I could find when it was being evaluated in the player_ability code and go from there.If I follow you correctly, you can find these under scar/luaconstants.scar (or is it luaconsts.scar?).
For SCAR functions, as far as I know you can find all their defintions in the SCAR folder. Most functions are prefixed something like this: "Squad_functioname" or "Util_functionname". They can be found under scar/squad.scar and scar/util.scar respectively.
On AI processes. I don't know if you've figured it out yet, but it all 'starts' with this file: ai/default.ai. If you have programming languae experience it shouldn't be too hard to follow the AIs flow of control, considering that you can find the definitions for functions. There's a few functions that are called in intervals, AIThink (1-4 or something) and AIAnalyze (1-4 too I think). I reckon what you're looking for is in this file.
fenwe
12th Oct 06, 8:18 PM
OK Gents, progress has been made thanks to you both. Looking at the combat medic stuff and the info about the squad_ stuff and being able to eliminate what I had thought was the reinforce stuff, I was able to narrow down this line
GameData["squad_reinforce_ext"] = Reference([[sbpextensions\squad_reinforce_ext.lua]])
Now I just need to find out where to call this in the code and I am half way there. Thanks much!
**
know what to search for and you can strike gold
function AccumulateReinforceDemand( availableResources )
-- run through all the squads that need reinforcements and see if they could use
-- a reinforcement - or we can allocate money to them
if (Task_CountProduction( s_selfplayer, PITEM_SquadReinforce ) == 0 and AIProduction_AnyReinforcementsNeeded( s_selfplayer )) then
located in strategic_unit_purchase.ai
naradaman
12th Oct 06, 10:46 PM
Good to hear you solved your problem :)
Taita
23rd Oct 06, 11:16 PM
It's true that the AI is only partially script-driven. Having said that, there is a great degree of control even within script to affect game flow through purchasing, target choices, demands, etc.
fenwe
23rd Oct 06, 11:30 PM
Taita- Yes sir. Once you get under the covers there is a whole bag of goodies you can get into. The tough part is in figuring out the function calls for stuff and how to do specific things. I talked to the DoW folks and they gave me a leg up. I wasn't able to use any of their stuff directly, but while the names have been changed and some of the stuff has been moved a round, It definitely helps.
Taita
24th Oct 06, 11:20 AM
One thing you could do is compile a list of functions exposed to script. If you do a search for function calls starting with AIPlayer_, AISquad_, Request_ (task), Purchase_, etc you may find what you are looking for.
Mr. Bildo
24th Oct 06, 12:34 PM
One thing you could do is compile a list of functions exposed to script. If you do a search for function calls starting with AIPlayer_, AISquad_, Request_ (task), Purchase_, etc you may find what you are looking for.
Yeah, I kept meaning to do that... I stink. :(
--Mr. Bildo
naradaman
24th Oct 06, 5:15 PM
Don't worry guys, my SCARWiki is nearing completion. It's very useful for browsing functions!
fenwe
25th Oct 06, 1:35 AM
The functions that you can search for and find in the .ai files are simple to find, tougher to figure out what they do when you find it, though all that takes is patience.
It is for calls that I can't find anywhere that make me want to grind my teeth, because you know they control everything that goes on :)
Request_Sniper(s_selfplayer, TGROUP_SpecialUnit, TPRIORITY_SpecialUnit, SNIPER_Defend)
Request_FinishIncompleteStructure( s_selfplayer, TGROUP_Tech, TPRIORITY_Tech_IncompleteStructure )
or when there is obviously something I am missing like how does one create a new "special_unit_type=ai_special_unit_sniper" type of association and exaclt how much can you do with it? I can see parts and pieces under the type_ stuff, but when you look at the lua it doesn't say much but GameData = Inherit([[]])
.
or when you see how they did something in DoW and there doesn't seem like an equivalent way in CoH
if (gmt > 4 * 60 and self:CanRepair()) then
self:RepairBuilding()
else
self:GoToNextPost()
end
This could almost look like the help_tactic in a round about way, since I haven't figured out exactly what it does yet, but so far no luck in utilizing it. So either it isn't what I thought or I am doing it incorrectly.
So yes, while their is lots for us to play with and influence, there is also lots that is difficult to find or know how it works or change it. Which is why I was hoping for some dev support. Not to answer questions about LUA or even SCAR, but more about specifics.
*added clarification*
fenwe
25th Oct 06, 7:36 PM
AISquad_ConvertToSimSquad(squad)
AISquad_GetAnchorPos(squad)
AISquad_ThreatLevelToSquad( s_selfplayer, squad, posCover )
Squad_FindCoverCompareCurrent(sim_squad, AISquad_GetAnchorPos(squad), misc_taskAP, 2.5*misc_taskAP, true)
AISquad_HasBeenAttacked(squad, s_CombatHistoryTicks)
AISquad_GetClosestObstructionOfType( squad, s_ObstructionSearchRadius, s_enemy_barbwire )
Squad_FindCoverCompareCurrent(sim_squad, AISquad_GetAnchorPos(squad), misc_taskAP, 2.5*misc_taskAP, true)
AISquad_IsPosWithinDistOfAttackTarget(squad, posCover, 25 )
World_DistanceSquaredPointToPoint(AISquad_GetAnchorPos(squad), Entity_GetPosition(hold_ent))
Entity_GetPosition(hold_ent)
OK, here are the AISquad_ ones, and those functions that are used with or by them. Most of these are found in tactics.ai
Here are the Request_ ones. These are found scattered about and they setup the goals that the engine is going to attempt. The priorityies are found/being set in default.ini. Some of these like Request_production are used for more than one type of production.
Request_FinishIncompleteStructure( s_selfplayer, TGROUP_Tech, TPRIORITY_Tech_IncompleteStructure )
Request_Secure( s_selfplayer, TGROUP_DefenceSecure, TPRIORITY_DefenceSecure, pbg, secure_params )
Request_Production( s_selfplayer, TGROUP_CommandTree, TPRIORITY_CommandTree, PITEM_PlayerUpgrade, command_item )
Request_Construction( s_selfplayer, TGROUP_DefenceSecure, TPRIORITY_DefenceSecure, pbg, demandTbl.buildstyle )
Request_Goliath(s_selfplayer, TGROUP_SpecialUnit, TPRIORITY_SpecialUnit, goliathData )
Request_Sniper(s_selfplayer, TGROUP_SpecialUnit, TPRIORITY_SpecialUnit, SNIPER_Defend)
Request_Combat(s_selfplayer, TGROUP_Attack, TPRIORITY_Attack, combatOrderParams)
Request_Capture(s_selfplayer, groupID, group_priority, captureOrderParams)
Request_Occupy( s_selfplayer, TGROUP_Tech, TPRIORITY_Tech, demandTbl.entity )
fenwe
26th Oct 06, 9:25 AM
I'll do some more tonight. All these functions are "hidden" somewhere. They are not accessible to us, though we can use them, though some of it will be trial and error. I am currently working on one to make tanks retreat from enemy foot soldiers, as an example. I'll let you know when/if I get it working.
Mr. Bildo
26th Oct 06, 11:49 AM
If you haven't checked already, there is a wealth of stuff in tactics.ai. I picked up on how to make my medic find injured soldiers by looking at some code there. I'm still a bit fuzzy on how it all works, but it's there none the less.
--Mr. Bildo
fenwe
26th Oct 06, 3:46 PM
Yep - I have been spending time their trying to get the squad_ai_ext->avoid_tactic stuff working. Unfortunately it looks like what ever sits on top of this isn't using it at all. The TacticFilter_Avoid function, as simple as it is, is never being called, where as the TacticFilter_TankMove on the vehicle_tactic is. Do you think we are allowed to open bugs on this?
I'd love to see the code you used/wrote for that medic. Your flare thing is gorgeous :)
fenwe
26th Oct 06, 10:35 PM
OK, remember the whole question about how to get the AI to repair? Well, I found what seems to be a major influencing factor, though I just found it so I have not tested it thoroughly.
Under attrib/abilities/repair_ability.rgd there is
ai_tactic.Priority
As well as what looks like the tageting functions used for that ability - TacticFilter_HealthLow, EntityTargetFilter_FirstFriendlyStructure_LowHealth, SquadTargetFilter_FirstFriendlyVehicle_LowHealth.
It doesn't though have a position_target_filter, so I am not sure if it will walk a round searching for thing to heal.
What I did was bump up priority to 10000, get a bike damaged, run it over to a standing engineer close enough so that the bike touched him/it and low and behold repairing. Obviously this is not the approved method and that number is high enough to break things, but it is a place to start.
@Mr Bildo - Did you get your medic to walk to folks and heal them? Mind shooting me the code for that, because it should work exactly the same way, assuming the function is called at all. Please let me know.
Mr. Bildo
27th Oct 06, 1:07 AM
@fenwe -- Here's what I know:
1. Priority is a value between 0 and 100 (or 1000?). There is a spot in the code (TODO: add actual reference) where it checks the priority of an ability. In that code it sets any value < 0 to 0. This is because it will eventually develop a demand value between, you guessed it, 0 and 100 (or is it 1000?).
2. The code I use for the medic is based on the functions you referenced, First_FriendlyStructure_LowHealth, etc. I just added new functions that searched for infantry. I also added my own variable for the health threshold, because I wanted it a little higher than vehicles.
3. To date, my development medic (not the one I've released) will heal nearby units the same as engineers, with the following "issues":
A. Because the medic only heals, the only AI tactics I have enabled are "hold", "cover" and the heal ability. This means that the medic, when controlled by the AI, will generally find a bunker to hide in, run from bad guys and heal squads in close proximity. This can be replicated with engineers by turning off their construction and cap tactics. They'll just hang out at your HQ and do nothing until someone shows up that is injured.
B. I tried adding build logic that was based on troop level demand. I could never tell how well it was working, but sometimes the AI would build a medic and sometimes not. I know I could just burn a medic into the build orders, which I did to test him, but I wanted the AI to not build one until it had a lot of infantry and started engaging in combat. I never felt I had that working exactly the way I wanted.
C. And this is the big one. Like with the engineers, for whatever reason, the medic only heals when the AI is set to (I think) Hard or Expert. In any case, it doesn't work on Easy. If I set the AI to Easy, the Engineers (with a repair of 100) will not repair. The same goes for the medic. I would REALLY appreciate some kind of clarification on that by a dev. It is really killing me!!
Issue "C" is the reason I haven't released the AI code for the medic yet.
Assuming I can resolve issue C, what I really want to do is tweak the "squadai" for the medic. I want him to search out "clumps" of allied soldiers and stay close to them. Ideally I'd like to combine clump logic with the isBeingAttacked logic. BTW, clump logic is how the AI determines where best to lob artillery, air strikes, etc. In any case, I want the medic to go out into the field instead of just stand there. The difficulty is that as far as I can tell all the AI is based on either capping points or attacking the enemy, neither of which the medic does. :hmm:
*note: if I'm wrong about any of the above, PLEASE correct me. The last thing I want is mine or any one's assumptions about this stuff to become accepted truth.
--Mr. Bildo
Kyranzor
27th Oct 06, 1:20 AM
wow sounds like some pretty full-on stuff boys!!! getting ai to build and use squads abilities? how cool is that!!??
fenwe
27th Oct 06, 8:46 AM
*nods* Yep, the assumptions are what kills you. I got the AI to repair on normal, by the way. I'll have to find where you saw the priority thing. All I did was move the damaged jeep so that it touched the enemy and poof, pioneer started welding.
So your saying that without "movement" code the AI would use/move the medic to heal? Does that mean that the "movement" code is for over riding default behavior of moving straight at someone?
I have code that will "reliably" pump AC and Stugs depending on the level of how many AC vs Stugs the AI controls. The main "problem" is that the AI will prioritize the unit build stuff according to the other priorities so that even if you have a unit set to build at 9999 multiple times (it is all weight based), it has a tendency to "research" and "build" first. Also, the ETA stuff is both a curse and a blessing because the longer it has to make a decision about something the longer it takes, or so it seems. That I haven't tested enough to satisfy myself about.
The one bad thing is that right now I am having to be very heavy handed to get the AI to do what I want it to, which probably means I am doing it incorrectly.
Oh and yes, I know we can play with the priorities set in default.ai, but I am just pointing out (learning) about what I perceive the default behavior to be. And yes, if anyone knows something different than what I am saying, please correct me.
Powered by vBulletin® Version 4.2.0 Copyright © 2013 vBulletin Solutions, Inc. All rights reserved.