AIs need as much information as possible, if anything it is useful in order to run predictive algorithms to determine future states in the game economy to guide decision making.
I also think ti is important to know that a resource should be avoided, rather than reversing the value so its negative or some other mathematical kludge. An AI developer may wish to treat this particular resource differently, and its not immediately obvious either.
[UnitDef] {     [customparams] {         //these can stretch the truth to be semi-accurate when it's complex         //assume any not present are 0         [resource 1 name]_store = float;         [resource 1 name]_cost = float;         [resource 1 name]_make = float;         [resource 1 name]_use = float;         [resource 1 name]_upkeep = float;         //repeat for all lua resources     } }
[WeaponDef] {     [customparams] {         //assume 0 if not present         [resource 1 name]_cost = float;         //repeat for all lua resources     } }
for _,unit in pairs(unitResources) do     SetUnitRulesParam(unit.id, 'monies_income', unit.moniesin)     SetUnitRulesParam(unit.id, 'power_income', unit.powerin)     SetUnitRulesParam(unit.id, 'power_drain', unit.powerout)     SetUnitRulesParam(unit.id, 'panic_amount', unit.paniclevel)     -- the rest are implicitly false end
This whole thing should be completely abstracted. Most of this stuff isn't even AI specific. This is like the whole "balance formula" discussion. There is no way you can just give the AI a bunch of values and expect it to play a mod it wasn't specifically written for.
If the purpose of this stuff is to remove performance bottlenecks from Lua then why not abstract as follows:
Code:
-- var name -- min value -- max value -- start value Spring.AddWatchVar('team_1_free_energy',0,10000,1000)
-- var name -- comparison type -- trigger value -- repeat -- callback -- custom args Spring.AddWatchVarCallback('team_1_free_energy','gt',3000,true,OnSurplusEnergy, arg1,arg2)
function OnSurplusEnergy(var_name,var_value,...) { -- do stuff }
-- Direct access to watchvars: local fm = Spring.WatchVars['team_1_free_metal'] Spring.WatchVars['team_1_free_metal'] += 200 -- may trigger callbacks
The var is stored in a lua table accessible to both the engine and lua. The engine pre-populates any watch variables that are always available (ie, 'unit_count', 'game_time'). Writes to the table fall through a metatable which checks for registered callbacks.
This allows efficient three-way mod, AI and engine sharing of useful variables without making a special case for resources or worse, particular types of resources.
if i get it somehow.. then i think i though of something similar somehow.. once my though went so: if eg UnitDef would have just a properties map, instead of a few hundred member variables, it would make coding life easier (at least from my perspective). The AI interface would not need a special function for each UnitDef member, but just had one function returning a properties value, simply said, eg:
Code:
UnitDef.getProperty(string propName)
in addition to fewer inter-version incompatibility problems (maybe), this would make coding easier, project wide, but surely degrade performance as well, and it would be a lot of work to change the whole engine to be like this... plus possibly a lot of other things i did not think of yet.
in short... it seemed not like a thing that will ever happen. +1 from me ouh and.. as this would be like a total rewrite of spring anyway.. could we also do the switch from C/C++ to Java at the same time? kthx
Joined: 08 Jan 2007, 06:13 Location: Don't be silly. If there's no machine heaven, where do all the toasters go?
I don't know if that would be a great idea across spring, but if you take the bit of effort to add such a map just for AIs you could use it to simplify lua unitdefs too.
If the UnitDef becomes a simple property map, this means that communicating information about Units to an AI becomes incredibly easy, because the one populating the map can just plug in whatever values they want, and tell the AI to fetch. Of course, the AI will need to know what there is to fetch, and what the values mean.
My question is, who determines what goes into the UnitDef properties? My guess would be, the mod developer?
Mod developers can already add custom vars to unitDefs. AI devs can already read them. None of it has any affect on the engine though. None of it makes life easier because a variable only has meaning if it is being used. Once it's being used then any 3rd-party changing the variable would still have to give thought to its effect on gameplay/AI/animation etc.
Exposing variables really won't make anyones life easier. What it will do is allow more complex mods and AI to emerge which will actually make many AI tasks harder (since you can never be sure if a given mod will have 2 resources or 10). There's also issues where the engine exposes a variable that for practical purposes is really read-only (because the engine has cached it internally or used it to create some static data).
All my suggestion does is move a fairly common polling operation into the engine where it will have slightly less impact on CPU and make it easier to share "public" variables (those a mod or the engine expect to be accessed and changed). It's not going to solve any other problems.
As I said you're not going to be able to create a AI that can play all mods competitively. If you accept that then all that's missing is communication between mod authors and AI writers as to what kinds of data should be exchanged via customParams or some other method. The proposal above is simply an "other method".
Joined: 01 Jun 2005, 10:36 Location: The Netherlands
That watch stuff sounds like an interesting idea.
As for multiple resources inside the engine, I would suggest to just change all places where resources are used to use an array (vector, possibly) of resources instead of the current 2 values (metal, energy).
Alternatively, the vector could be wrapped similar to the DamageArray (e.g. ResourceArray), this might increase readability compared to just throwing around std::vectors everywhere.
Ask the people who wrote Age of Empires. It has 6 resources (food, wood, stone, iron, gold and pop. cap). As does its descendants like Empire Earth. It's also conceivable that a mod would use this to handle squad resources like S44's morale and ammo variables. Although I wouldn't call this a high priority it does make sense for the engine not to enforce gameplay contraints on mods. Allowing a mod to essentially create and manage custom trigger levels and drains for a range of counters is a good thing. Some potential uses:
Yes the engine does many of these things already but what it doesn't do is allow a lot of mod or AI interaction after the initial modrules declaration. The behaviour tends to be fixed to what was declared at startup or what the engine feels is needed. This is fine while gameplay follows the legacy of TA but not if Spring is serious about being a more general RTS engine.
I believe for a given resource "X" a mod should be able to:
Create X Set and get min, max and current level for X Start a constant drain or gain of X Block read or write access to X from Synced/Unsynced/AI/Gaia code Lock X against changes (read-only) Make X private to a Team ID Add and remove callbacks against conditions of X
I believe that long-term this will actually make things easier for engine development as well since you'll essentially have a re-usable tracking object that can be reused for a number of limits/timers etc that currently use dedicated tracking code. It will also reduce the number of feature requests since mods should be able to reach in and reconfigure a tracker to suit their requirements.
SpliFF, what i meant with "it will make life easier inside the engine aswell" was: now, UnitDef has like 300 member variables plus there is the ability to share custom variables between AI/Lua/Engine/... . often, new variables are added to the engine class (eg UnitDef) as member variables. to make this accessible to an AI, a lot of code is needed, which will usually not be done by the person that creates this var, as it is usually not someone with a lot of interest in AI, or just does not know that something had to be done ot make it available to AI and .. more reasons. if ALL properties of UnitDef would exist as name->value pairs in a container, this problem would not exist, and it definatly would make life easier for engine coders (assuming they want to do it right -> give AIs the possibility to handle the var). it would make code easier, AI interface maintanance, and i guess also Lua interface maintenance. i though about what you said aswell.. like.. that there are variables only interesting to Lua, or only engine internal, and not to AIs. my first idea was to make an interface, eg IAIUnitDef, which contianas only the stuff of UnitDef that AIs might be interested in. but this would of course mean that someone adding a field in UnitDef possibly had to edit this file aswell -> again not good. an other idea would be annotations. i know them form java, dont know if that exist for C aswell, but if not, it could easily be simulated with comments. if we had all properties in a map, this would be easy again: we could have a map that accosiates a bitfield options value to each property, which we could check against & INTERESTING_FOR_AIS. and/or we could also add a map with a description for each property. -> this makes it possible for a new AI dev to use a property, and he would not have to know if it is engine internal or mod specific. he would also not have to contact any mod devs, and the mod devs do not have to explain their special properties to all the AI devs, as there would be a perfect place to describe it, and where everyone could get the description from. the only downsides i see, are the time needed to convert the engine, and lower performance because of the map queries. then again, we should be bale to optimize this with C style techniques :D (eg, query an index-int for a property-name once -> eg. O(n), and from then on use this int to access the value, description, options, ... -> O(1))
resources: for those who have not yet seen it, there are two classes for resource abstraction already, using the same mechanism that is used for teams eg. (Team & TeamHandler -> Resource & ResourceHandler). so far, they are only in use in the AI Interface. rts/Sim/Misc/Resource* The resourceMapAnalyzer is what was known as MetalMapParser for AIs -> not relevant here.
One point Id like to make is that Id rather have a generic value pair system that works and needs updating, than a hypothetical system in a forum thread and no actual functionality.
We're in an advantaged position that the only people directly using the C API are engine dvelopers of some sort anyway, the actual AIs all use legacy wrappers or intermediary wrappers of some sort.
Users browsing this forum: No registered users and 1 guest
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot post attachments in this forum