New analytical AI for Contingency (Work in progress)

Did you create a mod, map, music, or a tool? Present them here and earn feedback!
Note: addon requests do not belong here.
Note, everything uploaded to this forum, MUST have a license!
User avatar
Shadow Wolf TJC
Regular
Regular
Posts: 1047
Joined: 16 Apr 2011, 05:12
Location: Raleigh, NC

New analytical AI for Contingency (Work in progress)

Post by Shadow Wolf TJC »

I recently started work on a new, adaptable, analytical AI that would originally be designed for use with the Contingency mod (and would give Nullbot a run for its money :lol2: ), though may later be adapted for vanilla Warzone 2100. So far, it looks like my AI will need to keep track of a ton of variables and constants, many of which are stored in arrays. Since I don't yet know how to directly access and process information from .txt or .ini files in a way as to be usable to me, I'm planning on recreating the data from Contingency and storing that data on various files that would be accessed via the include() function.

Here's what I've done so far.

Code: Select all

/*ShadowBot Goals:
- Attempt to adapt production towards whatever weapon-vehicle and weapon-structure combos the opponent is using.
- Attempt to fight the opponent on multiple fronts by building proxy factories.
- Be ready to rebuild elsewhere if main base is sacked (so that it's harder to kill off).
- Map-specific strategy support.
- Multiple personality support.
- Being able to work with human players in executing complex tasks, including building defenses where specified, and following waypoint paths to attack opponents from the side or rear.
*/

var unitID = []; //This is a list of all units' IDs currently owned by the AI.

var unitRole = []; //This is used by individual units to determine their behavior, both individually, and while working with other units as a team.

const UNIT_ROLE_TANK = 0; //This unit's role is to soak up damage for the other units in its group. Since it tends to be more expensive than others within its group, it'll try to retreat if at low health.
const UNIT_ROLE_DPS = 1; //This unit's role is to deal as much damage as possible. Typically, they're not very durable, so they must rely on tanks to protect them, though on the other hand, they tend to be inexpensive, and thus, expendable.
const UNIT_ROLE_HARASSER = 2; //This unit's role is to rush in, deal damage, and get out before trouble comes. While harassers can possess either short or long range weaponry, including Mortars, speed is of utmost priority.
const UNIT_ROLE_SIEGE = 3; //This unit's role is to accompany an assaulting force to lay down close-range fire support. Typically, they're armed with short-range artillery, such as Mortars.
const UNIT_ROLE_FIRESUPPORT = 4; //Same as the siege role, only they stay safely away from the battlefield, and use long-ranged artillery such as Howitzers or Ripple Rockets. While size or degree of protection doesn't matter for these units, speed is of little priority.
const UNIT_ROLE_COUNTERBATTERY = 5; //This unit's role is to stay within the safety of the base and provide counter-battery and counter-radar fire with their long-range artillery weapons. High rate-of-fire or durability is of little concern since they need to take out their targets ASAP, so they'll typically be armed with weapons such as Ripple Rockets or Ground Shakers. However, they'll typically prioritize higher rate-of-fire artillery, such as Mortars and Hellstorms, over lower rate-of-fire artillery, such as the enemy's own Ground Shakers or Ripple Rockets (which can be dealt with by those units assigned to the siege or fire support roles).
const UNIT_ROLE_PROBE = 6; //This unit's role is to attempt to see what the enemy's base is like. Often, this would be a cheap, fast, expendable unit such as a Cyborg Machinegunner, Bug Machinegun Hover, or Bug Machinegun VTOL, but sometimes, a heavy-bodied unit, a unit equipped with a high damage-per-shot weapon (such as a Lancer, MRA, or Bunker Buster), and/or a unit equipped with a Sensor Turret is used instead.
const UNIT_ROLE_INTERCEPTOR = 7; //This unit's role is to intercept and destroy enemy units, especially fast-moving ones like harassers and VTOLs. They tend to be fast-moving hovers or VTOLs themselves. May attempt to flank and attack enemies from behind. Will attempt to pursue fleeing enemies until they're low on health, or until they run into heavy opposition.
const UNIT_ROLE_DEFENDER = 8; //Same as the interceptor role, only that they won't pursue enemies outside their designated area. They tend to be slow-moving units such as Tracks or Super Cyborgs.
const UNIT_ROLE_CONSTBASE = 9; //This unit's role is to stay within their designated base and build new structures. Neither speed nor durability are a priority, so the AI would typically assign Combat Engineers this role.
const UNIT_ROLE_CONSTOIL = 10; //This unit's role is to capture oil resources as quickly as possible. As such, speed is important, so the AI would prefer to use hover trucks to accomplish this goal.
const UNIT_ROLE_CONSTOUTPOST = 11; //This unit's role is to build and maintain outposts close to the front lines, or sometimes, even behind enemy lines. As such, durability is a priority, so heavy bodies (along with heavy construction turrets if available) are preferred, though sometimes, Combat Engineers are used to drop behind enemy lines using Cyborg Transports.
const UNIT_ROLE_SPOTTER = 12; //This unit's role is to spot targets for artillery bombardment.
const UNIT_ROLE_CBSENSOR = 13; //This unit's role is to escort groups of units and help protect them from enemy artillery.
const UNIT_ROLE_RADARDETECTOR = 14; //Same as above, though it attempts to spot enemy sensors.
const UNIT_ROLE_REPAIR = 15; //This unit's role is to repair damaged units that arrive at its designated area. Oftentimes, they'll be Cyborg Mechanics.
const UNIT_ROLE_REPAIRCOMBAT = 16; //This unit's role is to repair damaged units as they're retreating from the battlefield. As such, high durability is a priority, since chances are that they'll be a high-priority target for enemy forces.
const UNIT_ROLE_TRANSPORT = 17; //This unit's role is to transport other units across the battlefield.
const UNIT_ROLE_COMMANDER = 18; //This unit's role is to provide a combat bonus to whatever troops are assigned to it. Often, new commanders tend to be built using cheaper, lighter bodies, while more experienced commanders are recycled and placed in more durable, more expensive bodies.
const UNIT_ROLE_EMP = 19; //This unit's role is to temporarily disable enemy units and structures so that its teammates can safely finish them off.
const UNIT_ROLE_NEXUS = 20; //This unit's role is to capture enemy units and structures. Often, it'll prioritize capturing more defenseless stuff, like isolated Oil Derricks and wandering trucks, though it can be used in rush attacks. Prioritizes speed over defense.

var unitBody = []; //The internal name of the body being used by the unit.

const BODY_CYBORG1 = 0;
const BODY_CYBORG2 = 1;
const BODY_CYBORG3 = 2;
const BODY_CYBORG4 = 3;
const BODY_SUPERCYBORG1 = 4;
const BODY_SUPERCYBORG2 = 5;
const BODY_SUPERCYBORG3 = 6;
const BODY_SUPERCYBORG4 = 7;
const BODY_VIPER = 8;
const BODY_COBRA = 9;
const BODY_PYTHON = 10;
const BODY_COUATL = 11;
const BODY_BUG = 12;
const BODY_SCORPION = 13;
const BODY_MANTIS = 14;
const BODY_ABADDON = 15;
const BODY_LEOPARD = 16;
const BODY_PANTHER = 17;
const BODY_TIGER = 18;
const BODY_SABRETOOTH = 19;
const BODY_FALCON = 20;
const BODY_WARHAWK = 21;
const BODY_EAGLE = 22;
const BODY_PHOENIX = 23;
const BODY_GLADIUS = 24;
const BODY_LONGSWORD = 25;
const BODY_CLAYMORE = 26;
const BODY_EXCALIBUR = 27;
const BODY_RETALIATION = 28;
const BODY_RETRIBUTION = 29;
const BODY_VENGEANCE = 30;
const BODY_NEMESIS = 31;
const BODY_WYRMLING = 32;
const BODY_SALAMANDER = 33;
const BODY_WYVERN = 34;
const BODY_DRAGON = 35;
const BODY_TRANSPORT = 36;
const BODY_SUPERTRANSPORT = 37;

var bodyEngine = []; //The engine power of the body after upgrades. Used by the AI to help keep itself from designing units that are either too heavy (especially) or too light for their engine power.

const bodyBaseEngine = [1080,1080,1080,1080,1000,1000,1000,1000,3000,6000,12000,24000,3000,6000,12000,24000,2381,4762,9524,19049,2381,4762,9524,19049,1890,3780,7560,15119,1890,3780,7560,15119,1500,3000,6000,12000,1000,24000]; //The base engine power of the body.

var engineMultiplier = 1;

const bodyWeight = [999,999,999,999,999,999,999,999,250,500,1000,2000,166,333,666,1333,250,500,1000,2000,166,333,666,1333,250,500,1000,2000,166,333,666,1333,250,500,1000,2000,0,0]; //The weight of the body. Used by the AI to help keep itself from designing units that are either too heavy or too light for their engine power.

var unitPropulsion = []; //The name of the propulsion system used by the unit.

const PROPULSION_WHEELS = 0;
const PROPULSION_HALFTRACKS = 1;
const PROPULSION_TRACKS = 2;
const PROPULSION_HOVER = 3;
const PROPULSION_VTOL = 4;
const PROPULSION_CYBORG = 5;
const PROPULSION_SUPERCYBORG = 6;

const propulsionWeightModifier = [8,6,4,12,1,1,1]; //The weight of the propulsion system. Used by the AI to help keep itself from designing units that are either too heavy or too light for their engine power.

const propulsionTerrainModifier = [
	[1,1.5,0,.5],
	[1,1.5,0,.5],
	[1,1.5,0,.5],
	[1,1,1.5,1],
	[1,1,1,1],
	[1,1.5,0,.5],
	[1,1.5,0,.5]
]; //The multiplier to apply to the engine power of units that are using X propulsion and traveling over Y terrain. Useful if the AI finds itself playing on a map that it recognizes possesses an abundance of one or more of the following terrain types:

const TERRAIN_DEFAULT = 0;
const TERRAIN_ROAD = 1;
const TERRAIN_WATER = 2;
const TERRAIN_MUD = 3;

var unitTurret = []; //The internal name of the primary turret that the unit is equipped with.

var turretWeight = []; //The turret's weight.

var weaponDamagePerShot = []; //The weapon's base damage-per-shot, modified by weapon upgrades. This is used to determine what targets units armed with this weapon should prioritize over others.

const weaponBaseDamagePerShot = []; //The weapon's base damage-per-shot.

var weaponROF = []; //The weapon's rate-of-fire.

const weaponBaseROF = []; //The weapon's base rate-of-fire.

var weaponDamagePerSecond = [{{}}]; //3D array that determines X weapon's predicted damage-per-second against Y designated target body and Z propulsion type.

const weaponType = []; //The weapon's class, also used to determine what targets units armed with this weapon should prioritize over others.

const WEAPON_TYPE_ANTIPERSONNEL = 0;
const WEAPON_TYPE_ALLROUNDER = 1;
const WEAPON_TYPE_ANTITANK = 2;
const WEAPON_TYPE_BUNKERBUSTER = 3;
const WEAPON_TYPE_ANTISTRUCTURE = 4;
const WEAPON_TYPE_FLAMER = 5;

const weaponClass = []; //Whether the weapon deals kinetic or thermal damage. Used in tertiary target prioritizing.

const WEAPON_CLASS_KINETIC = 0;
const WEAPON_CLASS_THERMAL = 1;

const weaponSubclass = []; //The subclass that the weapon belongs to.

const WEAPON_SUBCLASS_MACHINEGUN = 0;
const WEAPON_SUBCLASS_CANNON = 1;
const WEAPON_SUBCLASS_ROCKET = 2;
const WEAPON_SUBCLASS_FLAMER = 3;
const WEAPON_SUBCLASS_MORTAR = 4;
const WEAPON_SUBCLASS_HOWITZER = 5;
const WEAPON_SUBCLASS_ANTIAIR = 6;
const WEAPON_SUBCLASS_BOMB = 7;
const WEAPON_SUBCLASS_LASER = 8;
const WEAPON_SUBCLASS_RAILGUN = 9;
const WEAPON_SUBCLASS_MISSILE = 10;
const WEAPON_SUBCLASS_SPECIAL = 11; //Reserved for special weapons such as NEXUS Link Turrets, EMPs, and the LasSat.

var subclassDamageModifier = []; //The multiplier to apply to the damage-per-shot of a weapon belonging to a certain weapon line.

var subclassROFModifier = []; //Used to help determine which weapons the AI should prioritize production/construction over others.

var groupList = []; //This determines which droids belong to a certain group.

var groupPrice = []; //This is the cost (in power) that was used to create the entire group. Used to determine when the group should retreat for repairs.

var groupStrength = []; //This is a measure of the group's remaining health. It is calculated as this: groupStrength = the sum of each individual unit's cost times the unit's remaining health percentage.

var groupObjective = []; //This determines the group's objective, whether it's to build a base, look for oil, perform raids on enemy oil, lay siege upon the enemy's base, etc.

//Create lists of components that will be useful for target prioritizing purposes.

include("multiplay/skirmish/component-definitions.inc");

function eventStartLevel()
{
	
}
Now this code is far from being final. In the future, many parts of this code will probably be stored in external files in case others would want to more easily modify them. However, this is just the tip of the iceberg in terms of what variables and constants my AI would need to keep track of. My AI would be required to perform some fairly complex math in order to determine which unit templates to build to take on various needs.

Since I'll probably want to create and use arrays that keep track of what each of the AI player's units' and structures' stats are in-game, I'll probably be using the array.splice function liberally whenever one of the AIs own units or structures is destroyed.

By the way, has anyone ever tried to create a 3D array? For example:

Code: Select all

myArray = [[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]],[[13,14,15],[16,17,18]]]
where myArray[2][0][1] would output "14"

Would such an array work on JavaScript?

Edit: Nevermind. I tested it, and 3D arrays seem to work just fine.
Last edited by Shadow Wolf TJC on 17 Nov 2012, 04:48, edited 1 time in total.
Creator of Warzone 2100: Contingency!
Founder of Wikizone 2100: http://wikizone2100.wikia.com/wiki/Wikizone_2100
User avatar
aubergine
Professional
Professional
Posts: 3459
Joined: 10 Oct 2010, 00:58
Contact:

Re: New analytical AI for Contingency (Work in progress)

Post by aubergine »

Ok let me start by saying I'm creaming my pants over the possibility of getting something like that for vanilla WZ stats in 3.1. It would massively boost what an AI is capable of.

However, my gut feeling is that it's "death by globals" -- like massive overkill on the number of constants.

For example, let's take a handful of constants:

Code: Select all

const BODY_CYBORG1 = 0;
const BODY_CYBORG2 = 1;
const BODY_CYBORG3 = 2;
const BODY_CYBORG4 = 3;
const BODY_SUPERCYBORG1 = 4;
const BODY_SUPERCYBORG2 = 5;
const BODY_SUPERCYBORG3 = 6;
const BODY_SUPERCYBORG4 = 7;
....etc....
It would be better IMHO, if you did something like this...

Code: Select all

var body = {
    CYBORG1: 0,
    CYBORG2: 1,
    CYBORG3: 2,
    CYBORG4: 3,
    SUPERCYBORG1: 4,
    SUPERCYBORG2: 5,
    SUPERCYBORG3: 6,
    SUPERCYBORG4: 7,
    ....etc....
}

// elsewhere
body.SUPERCYBORG1 // 4
Basically, namespace the constants. I know the code above isn't actually making them constants, they are just properties of an object, but I have code that can make that object read-only / non-configurable if that's a worry.

And why not just have objects for the bodies, for example, that provide all the stats, eg:

Code: Select all

body = {};
// if referencing by name:
body.SUPERCYBORG4 = {id: 4, weight: whatever, favouriteFood: "tuna"}
// if referencing by id:
body.4 = {name:"SUPERCYBORG4", weight: whatever, favouriteFood: "tuna"}

// you could even have body be an array and then have both numeric and named refs to the objects
body = [];
body[4] = obj;
body[name] = obj;

// or...
body[4] = obj.name;
body[obj.name] = obj;
I'd also split them out in to smaller includes if possible, rather than one gigantic file. When it comes to debugging it's often helpful to comment out a bunch of includes to quickly narrow down to the problem area so you can focus on fixing it without loads of other stuff getting in the way.

All game objects will have a unique id - so instead of using array.splice(), why not allow the array to become sparse and use numeric keys that are the object ids? You can then delete someArray[gameObject.id] or someArray[gameObject.id] = gameObject, etc. ECMAscript 5, which the WZ JS env is veering towards does a very good job of dealing with sparse arrays with negligible performance issues. Functions like array.forEach(), array.filter() and array.some() all deal with sparse arrays transparently and make code super readable IMHO.

As for 3D arrays, yes they work, but IMHO they make the code insanely confusing. Maybe consider an object structure or bit masks?
"Dedicated to discovering Warzone artefacts, and sharing them freely for the benefit of the community."
-- https://warzone.atlassian.net/wiki/display/GO
User avatar
aubergine
Professional
Professional
Posts: 3459
Joined: 10 Oct 2010, 00:58
Contact:

Re: New analytical AI for Contingency (Work in progress)

Post by aubergine »

One last note - how are you going to determine the terrain of each tile on the map? Currently that's not exposed via JS API.
"Dedicated to discovering Warzone artefacts, and sharing them freely for the benefit of the community."
-- https://warzone.atlassian.net/wiki/display/GO
User avatar
Shadow Wolf TJC
Regular
Regular
Posts: 1047
Joined: 16 Apr 2011, 05:12
Location: Raleigh, NC

Re: New analytical AI for Contingency (Work in progress)

Post by Shadow Wolf TJC »

@aubergine: The reason why I had to structure it like that, with all those constants, is because I'll need for the AI to record information about its own units. For example, if the AI just produced a Machinegun Viper Wheels for the role of harassment, I'll need it to record what the droid's body, propulsion, and turret are upon creation, as well as which role the unit was created for. For example:

Code: Select all

function eventDroidBuilt(droid,factory)
{
	unitIndex[droid.id] = unitID.push(droid.id);
	unitRole[unitIndex.length-1] = droidRoleToProduce[factory.id];
	unitBody[unitIndex.length-1] = bodyToProduce[factory.id];
	unitPropulsion[unitIndex.length-1] = propulsionToProduce[factory.id];
	unitTurret[unitIndex.length-1] = turretToProduce[factory.id];
}
where, in the example above, droidRoleToProduce[factory.id] = UNIT_ROLE_HARASSER; bodyToProduce[factory.id] = BODY_VIPER; propulsionToProduce[factory.id] = PROPULSION_WHEELS; and turretToProduce[factory.id] = WEAPON_MACHINEGUN.

While I could try to use strings, such as the names of components, I doubt that they would work if used as an index of an array, so I instead opted to use constants in their place, since I know that their values can be used in array indexes. For example, if I wanted my AI to know how much damage per second its Machinegun turrets cause towards Viper-bodied Wheeled vehicles:

Code: Select all

function calculateDamagePerSecond(WEAPON_MACHINEGUN,BODY_VIPER,PROPULSION_WHEELS)
{
	weaponDamagePerShot[WEAPON_MACHINEGUN] = weaponBaseDamagePerShot[WEAPON_MACHINEGUN] * subclassDamageModifier[weaponSubclass[WEAPON_MACHINEGUN]];
	weaponROF[WEAPON_MACHINEGUN] = weaponBaseROF[WEAPON_MACHINEGUN] * subclassROFModifier[weaponSubclass[WEAPON_MACHINEGUN]];
	var d = weaponDamagePerShot[WEAPON_MACHINEGUN] * weaponTypeMultiplier[weaponType[WEAPON_MACHINEGUN]][PROPULSION_WHEELS];
	weaponDamagePerSecond[WEAPON_MACHINEGUN][BODY_VIPER][PROPULSION_WHEELS] = weaponROF[WEAPON_MACHINEGUN] * max((d - bodyArmor[BODY_VIPER][weaponClass[WEAPON_MACHINEGUN]]),(d/3),1)
}
Again, this is all just a work in progress, so it may change. Of course, several features present in 3.2 may make some of these variables and constants redundant or obsolete.
aubergine wrote:One last note - how are you going to determine the terrain of each tile on the map? Currently that's not exposed via JS API.
For now, I don't think I can. All I can do is give the AI some general "advice" on which terrain types are more abundant on certain maps by having it perform a check on which map it's playing in. For example, if the AI was playing on 2c-Vision, it would be informed that the map would contain high amounts of SLUSH tiles (which are treated the same as GREENMUD tiles in Contingency, in which both tiles slow down most units), and it could prioritize researching Hover Propulsion, and may even consider designing and building Wheeled, Half-Tracked, and Tracked vehicles that are light enough to be able to move through the mud and slush unhindered.
Creator of Warzone 2100: Contingency!
Founder of Wikizone 2100: http://wikizone2100.wikia.com/wiki/Wikizone_2100
User avatar
Goth Zagog-Thou
Regular
Regular
Posts: 1582
Joined: 06 Jan 2007, 08:08
Location: Delta Base
Contact:

Re: New analytical AI for Contingency (Work in progress)

Post by Goth Zagog-Thou »

I also recommend that your AI takes tile heights into consideration when building, whether they are along cliff tiles or not, and if they have visibility beyond x number of tiles past those cliff tiles. That could enable the AI to build along high ground for defensive purposes (?).

Just a quick thought. :D
User avatar
aubergine
Professional
Professional
Posts: 3459
Joined: 10 Oct 2010, 00:58
Contact:

Re: New analytical AI for Contingency (Work in progress)

Post by aubergine »

Taxi just arrived so will post more details later, but...

Code: Select all

var factoryOrders = {};
function makeDriod(factory,name,body,propulsion,unused1,unused2,turret1,turret2,turret3) {
  // keep record of the factory's production order
  // you could easily add role, etc., params and store those too
  factoryOrders[factory.id] = {
    name: name,
    body: body,
    propulsion: propulsion,
    turrets: [turret1, turret2, turret3];
  }
  // if you added additional params, you might need to manipulate arguments object
  // to remove them. to do that you can turn it in to a proper array using...
  // arguments = Array.prototype.splice.call(arguments); // arguments --> proper array
  buildDroid.apply(this, arguments); // start production
}

var myDroids = [];
function eventDroidBuilt(droid, structure) {
  myDroids[droid.id] = factoryOrders[structure.id];
}

// then you can get components for your droid at any time
// example:
function eventAttacked(obj, attacker) {
  if (obj.type == DROID) {
    var droidStats = myDroids[obj.id];
  }
}

function eventDestroyed(obj) {
  if (obj.type == DROID) {
    var droidStats = myDroids[obj.id]; // in case you want to produce another one
    // stuff
    delete myDroids[obj.id]; // free up some RAM
  }
}
"Dedicated to discovering Warzone artefacts, and sharing them freely for the benefit of the community."
-- https://warzone.atlassian.net/wiki/display/GO
User avatar
aubergine
Professional
Professional
Posts: 3459
Joined: 10 Oct 2010, 00:58
Contact:

Re: New analytical AI for Contingency (Work in progress)

Post by aubergine »

Ah, was taxi for next door neighbour, ours is late...

So... makeDroid() function above is what you'd use to get factories to make new droids. It stores the droid specs and anything else you want, then runs buildDroid() to actually start production.

On eventDroidBuilt() you find out the droid id that was produced, and then move the data over to myDroids[] where it can be easily referenced later.

out taxi arrived now, g2g
"Dedicated to discovering Warzone artefacts, and sharing them freely for the benefit of the community."
-- https://warzone.atlassian.net/wiki/display/GO
User avatar
Iluvalar
Regular
Regular
Posts: 1828
Joined: 02 Oct 2010, 18:44

Re: New analytical AI for Contingency (Work in progress)

Post by Iluvalar »

I know I'm bashing an open door here. But you intentionality gave a quick easy option to any decent research line for an adapt. Since it's already there, there is not need of "analytical" skill to determine whether or not it need to be acquired and used.

Same for personalities, since one path will fall into a strictly dominant Nash equilibrium, a "good" AI would simply use that one. On the other hand, if you don't mind to code sub-efficient personalities, I fail to see why you'd code such huge analytical AI if you plan a random distribution of an handful of options. :hmm:
Heretic 2.3 improver and proud of it.
User avatar
aubergine
Professional
Professional
Posts: 3459
Joined: 10 Oct 2010, 00:58
Contact:

Re: New analytical AI for Contingency (Work in progress)

Post by aubergine »

I imagine that once an analytical AI is developed, it will be able to adapt to any research path. Obviously more stuff needs adding to the JS API to ultimately reach that goal, but once reached it means that an AI can deal with whatever mods are active and work out how best to take advantage of things it's never even encountered before.

Also, doing this analytical AI will highlight shortcomings of the current JS API and help prioritise future development.
"Dedicated to discovering Warzone artefacts, and sharing them freely for the benefit of the community."
-- https://warzone.atlassian.net/wiki/display/GO
User avatar
NoQ
Special
Special
Posts: 6226
Joined: 24 Dec 2009, 11:35
Location: /var/zone

Re: New analytical AI for Contingency (Work in progress)

Post by NoQ »

The "for contingency" part is least important, yeah. I'll adapt it to the base branch myself if necessary. This is not really what takes effort to develop.

And yeah, i'm looking forward to start the AI vs. AI competition (:
User avatar
Shadow Wolf TJC
Regular
Regular
Posts: 1047
Joined: 16 Apr 2011, 05:12
Location: Raleigh, NC

Re: New analytical AI for Contingency (Work in progress)

Post by Shadow Wolf TJC »

Sorry that it's late, but my internet was down for a few days while I typed this up:

@Iluvalar: Have you heard of the following saying:
Sun Tzu's Art of War wrote:So it is said that if you know your enemies and know yourself, you can win a hundred battles without a single loss.
If you only know yourself, but not your opponent, you may win or may lose.
If you know neither yourself nor your enemy, you will always endanger yourself.
Ideally, an analytical AI would be able to analyze what information it already knows about itself, as well as what it knows about its opponents, and even the map that it's fighting in, and make use of that information, including what resources it already has available at its disposal, to best turn the tide of battle to its advantage. Is the enemy attacking with more cyborgs than tanks? Build more droids armed with rapid-fire or wide area-of-effect anti-personnel weapons. Prioritize research into more effective anti-personnel weapons "if need be". Are you a Flamer specialist, and you're fighting on a map with lots of mud or slush (like 2c-Vision)? Secure what oil you can easily defend, then turtle until you've researched hover propulsion. Is your opponent building lots of defensive structures? Consider building more anti-structure weapons.

Personally, I doubt that there's a single tech path, in both vanilla Warzone 2100 and Contingency, that would work best for all maps. For example, a player that focuses on Flamers and Lasers would probably thrive on a map with lots of open space and pavement (which provides an engine power boost to all Wheeled, Half-Tracked, and Tracked droids), while a player that focuses on Artillery or VTOLs would probably struggle on said map. On the other hand, on a map with very little open space, and lots of mud and slush (which slows down all ground droids except for hovers), the Flamer player would probably struggle, while the Artillery and VTOL players would probably thrive.

While I am indeed planning for my AI to have multiple sub-personalities that prioritize different techs over others, regardless of map, I'm also planning on making them at least somewhat adaptable to certain kinds of maps. Moreover, I'm planning on creating a "supreme" personality that chooses one of its other sub-personalities based upon what it thinks is most effective on the map that it'll be playing on (similar to how, in Supreme Commander, the "Supreme AI" chooses one of 3 personalities, Horde, Tech, or Balanced, depending on what map it'll be playing in), though it'll probably come out later on, when Shadowbot is more mature. ;)
Creator of Warzone 2100: Contingency!
Founder of Wikizone 2100: http://wikizone2100.wikia.com/wiki/Wikizone_2100
User avatar
Shadow Wolf TJC
Regular
Regular
Posts: 1047
Joined: 16 Apr 2011, 05:12
Location: Raleigh, NC

Re: New analytical AI for Contingency (Work in progress)

Post by Shadow Wolf TJC »

It's been a while, but I have a progress report on ShadowBot's development:

I've been developing the AI gradually, one step at a time. So far, here's what I've gotten ShadowBot to do:

1. Assigned all starting trucks to group 0.
2. Ordered all droids belonging to group 0 to build a series of buildings (factory, lab, hq, lab, factory, generator).
3. Ordered the 1st factory that was built to produce a certain number of trucks.
4. Assigned some, but not all, of the trucks that were produced to group 0, and ordered them to help build the base up. (The ones that weren't assigned to group 0 are planned to attempt to rush to the center of the map, and either capture whatever oil resources were nearby, or set up Tank Trap barricades.)
5. Ordered the 1st research lab that was built to research Machinegun, followed by Tank Traps.
6. Display a bunch of console messages to help keep track of what the script's trying to do and what it's managed to do so far. (However, in the future, I'll probably have to start disabling some of these messages since they could flood the player with too much info.)

Here's a demo of ShadowBot if you'd like to see it for yourself:
shadowbot-contingency_pre_alpha.wz
(Don't mind all the cruft. Eventually, it'll either be put to use, or removed.)

Sometimes, I've been taking quick peeks at how NullBot did some things in order to get a better idea on what I needed to do in order to get ShadowBot to do what I want it to do. :hmm: As a result, I graduated from using multidimensional arrays to creating and using objects to handle data that would need to be created for each individual droid, structure, group, base, enemy player, etc. XD

As of now, these tests are currently being done on the map Vision, though in the future, I'll need to adjust the AI so that it'll function in any sort of map, including hover and VTOL only maps. Right now, however, I'm planning on meeting the following goals in the near-future:

1. Have some of the trucks that were produced from the factory start hunting for oil, starting from a certain location on the map (such as the center).
2. Have group 0 build additional Power Generators whenever the AI has more Oil Derricks (regardless of whether or not they're finished) than it has Power Generators to handle them.
3. Have the factory start producing Machinegun Viper Wheels as soon as the Machinegun is researched, as soon as the HQ is finished, and as soon as the factory has finished producing trucks.
4. Assign all the Machinegun Viper Wheels to a new assault group, and have them perform a sweep of the map.
5. Have the assault group retreat when it loses too many units.

From there, even I'm not certain what I'll plan next. :ninja:
Creator of Warzone 2100: Contingency!
Founder of Wikizone 2100: http://wikizone2100.wikia.com/wiki/Wikizone_2100
User avatar
Arreon
Trained
Trained
Posts: 324
Joined: 15 Feb 2009, 05:57
Contact:

Re: New analytical AI for Contingency (Work in progress)

Post by Arreon »

I figured, I'd post the most recent error log while trying to play with your new AI:

Code: Select all

--- Starting log [C:\Users\Ryan\Documents\Warzone 2100 3.1\logs\WZlog-1128_111107.txt]---
info    |11:11:07: [realmain:1133] Using C:\Users\Ryan\Documents\Warzone 2100 3.1\logs\WZlog-1128_111107.txt debug file
info    |11:11:11: [loadMapPreview:456] Loading map preview: "Sk-Rush" builtin t2
info    |11:11:13: [loadMapPreview:456] Loading map preview: "Sk-Startup" builtin t2
info    |11:11:13: [loadMapPreview:456] Loading map preview: "Sk-HighGround" builtin t2
info    |11:11:19: [resLoadFile:439] Hash collision "gnhhowtar.pie" vs "gnhhowtbb.pie"
info    |11:11:19: [resLoadFile:439] Assert in Warzone: frameresource.cpp:439 (strcasecmp(psRes->aID, pFile) == 0), last script event: '<none>'
info    |11:11:27: [createLimitSet:371] Too many structure stats
info    |11:11:27: [createLimitSet:371] Assert in Warzone: multilimit.cpp:371 (numStructureStats < 0xff), last script event: 'N/A'
info    |11:11:27: [loadMapPreview:456] Loading map preview: "Sk-HighGround" builtin t2
last message repeated 2 times
info    |11:11:36: [createLimitSet:371] Too many structure stats
info    |11:11:36: [createLimitSet:371] Assert in Warzone: multilimit.cpp:371 (numStructureStats < 0xff), last script event: 'N/A'
info    |11:11:41: [resLoadFile:439] Hash collision "gnhhowtar.pie" vs "gnhhowtbb.pie"
info    |11:11:41: [resLoadFile:439] Assert in Warzone: frameresource.cpp:439 (strcasecmp(psRes->aID, pFile) == 0), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Automated Manufacturing Mk2 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Automated Manufacturing Mk3 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Gas Turbine Generator Mk2 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Automated Repair Facility Mk2 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Improved Engineering Mk2 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Improved Engineering Mk3 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Robotic Engineering Mk2 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Robotic Engineering Mk3 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Nanoscale Engineering Mk2 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Nanoscale Engineering Mk3 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Reactive Armor Mk2 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Reactive Armor Mk3 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, High-Density Reactive Armor Mk2 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, High-Density Reactive Armor Mk3 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Ultra-High-Density Reactive Armor Mk2 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Ultra-High-Density Reactive Armor Mk3 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [getViewData:759] Message RES_V_B15 not found, run with --debug=wz to get a list of all known messages
info    |11:11:42: [getViewData:759] Assert in Warzone: message.cpp:759 (ptr), last script event: '<none>'
info    |11:11:42: [getViewData:759] Message RES_V_B16 not found, run with --debug=wz to get a list of all known messages
info    |11:11:42: [getViewData:759] Assert in Warzone: message.cpp:759 (ptr), last script event: '<none>'
info    |11:11:42: [getViewData:759] Message RES_V_B17 not found, run with --debug=wz to get a list of all known messages
info    |11:11:42: [getViewData:759] Assert in Warzone: message.cpp:759 (ptr), last script event: '<none>'
info    |11:11:42: [getViewData:759] Message RES_V_B18 not found, run with --debug=wz to get a list of all known messages
info    |11:11:42: [getViewData:759] Assert in Warzone: message.cpp:759 (ptr), last script event: '<none>'
info    |11:11:42: [getViewData:759] Message RES_V_B19 not found, run with --debug=wz to get a list of all known messages
info    |11:11:42: [getViewData:759] Assert in Warzone: message.cpp:759 (ptr), last script event: '<none>'
info    |11:11:42: [getViewData:759] Message RES_V_B20 not found, run with --debug=wz to get a list of all known messages
info    |11:11:42: [getViewData:759] Assert in Warzone: message.cpp:759 (ptr), last script event: '<none>'
info    |11:11:42: [getViewData:759] Message RES_V_B21 not found, run with --debug=wz to get a list of all known messages
info    |11:11:42: [getViewData:759] Assert in Warzone: message.cpp:759 (ptr), last script event: '<none>'
info    |11:11:42: [getViewData:759] Message RES_V_B22 not found, run with --debug=wz to get a list of all known messages
info    |11:11:42: [getViewData:759] Assert in Warzone: message.cpp:759 (ptr), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Turbo-Charged Engine Mk3 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Gas Turbine Engine Mk3 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, HEAP Bomb Shells Mk2 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, HEAP Bomb Shells Mk3 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Depleted Uranium Bomb Shells Mk2 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Depleted Uranium Bomb Shells Mk3 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Fin-Stabilized Cannon Rounds Mk2 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Fin-Stabilized Cannon Rounds Mk3 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Cannon Targeting Computer Mk2 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Cannon Targeting Computer Mk3 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Cannon Target Prediction Computer Mk2 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Cannon Target Prediction Computer Mk3 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, APDS Cannon Rounds Mk3 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, HVAPDS Cannon Rounds Mk3 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Laser Targeting Computer Mk2 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Laser Targeting Computer Mk3 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Laser Target Prediction Computer Mk2 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Laser Target Prediction Computer Mk3 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Machinegun Targeting Computer Mk2 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Machinegun Targeting Computer Mk3 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Fin-Stabilized MG Bullets Mk2 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Fin-Stabilized MG Bullets Mk3 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Machinegun Target Prediction Computer Mk2 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Machinegun Target Prediction Computer Mk3 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Chaingun Upgrade Mk2 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Chaingun Upgrade Mk3 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Rapid-Fire Chaingun Upgrade Mk2 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Rapid-Fire Chaingun Upgrade Mk3 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Chaingun Coolant System Mk2 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Chaingun Coolant System Mk3 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Target Prediction Ballistic Missiles Mk2 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Target Prediction Ballistic Missiles Mk3 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Railgun Targeting Computer Mk2 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Railgun Targeting Computer Mk3 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Cannon/Railgun Target Prediction Computer Mk2 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
info    |11:11:42: [loadResearch:280] This research should not have a message associated with it, Cannon/Railgun Target Prediction Computer Mk3 the message will be ignored!
info    |11:11:42: [loadResearch:280] Assert in Warzone: research.cpp:280 (research.techCode == TC_MAJOR), last script event: '<none>'
error   |11:11:43: [callFunction:109] 0 : <anonymous>()@multiplay/skirmish/shadowbot-contingency-main.js:394
info    |11:11:43: [callFunction:112] Uncaught exception calling function "eventStartLevel" at line 394: ReferenceError: Can't find variable: base
info    |11:11:43: [callFunction:112] Assert in Warzone: qtscript.cpp:112 (false), last script event: 'N/A'
Actually, I couldn't use the new AI because the menu was in the way because it was listed at the bottom.
OS: Windows 7 Home Premium 64-bit
Processor: AMD Phenom II X6 1045T (6 CPUs), ~2.7GHz
Memory: 8192MB RAM
User avatar
Shadow Wolf TJC
Regular
Regular
Posts: 1047
Joined: 16 Apr 2011, 05:12
Location: Raleigh, NC

Re: New analytical AI for Contingency (Work in progress)

Post by Shadow Wolf TJC »

Whoops. Must've accidentally uploaded an older version that had some bugs to work out. :oops:
shadowbot-contingency_pre_alpha2.wz
Better?
(8.66 KiB) Downloaded 261 times
Creator of Warzone 2100: Contingency!
Founder of Wikizone 2100: http://wikizone2100.wikia.com/wiki/Wikizone_2100
User avatar
Arreon
Trained
Trained
Posts: 324
Joined: 15 Feb 2009, 05:57
Contact:

Re: New analytical AI for Contingency (Work in progress)

Post by Arreon »

Shadow Wolf TJC wrote:Whoops. Must've accidentally uploaded an older version that had some bugs to work out. :oops:
shadowbot-contingency_pre_alpha2.wz
Nope, still doesn't work:

Code: Select all

error   |11:43:02: [callFunction:109] 0 : <anonymous>()@multiplay/skirmish/shadowbot-contingency-main.js:404
info    |11:43:02: [callFunction:112] Uncaught exception calling function "eventStartLevel" at line 404: ReferenceError: Can't find variable: base
info    |11:43:02: [callFunction:112] Assert in Warzone: qtscript.cpp:112 (false), last script event: 'N/A'
OS: Windows 7 Home Premium 64-bit
Processor: AMD Phenom II X6 1045T (6 CPUs), ~2.7GHz
Memory: 8192MB RAM
Post Reply