Jump to content

[my first script] need some help to understand how works scripting


Recommended Posts

Hi I try for hours now to understand how works scripting... I'm turning completely mad when I see I'm not able to even print a simple data...

so I ask for help.

I add two revelant files.

testbot.js :

function TestBotAI(settings){  BaseAI.call(this, settings);}TestBotAI.prototype = new BaseAI();TestBotAI.prototype.OnUpdate = function(){  var gameState = new GameState(this);  var test = gameState.updatingCollection("test", Filters.byOwners(this.player), gameState.entities);  var count = 0;  for each (var ent in gameState.entities.filter(Filters.byOwner(this.player) ) )  /* I also tried with : */  //for each (var ent in test ) )  {    var pos = ent.position();// not working why ??    ++count;  }	warn(count); // always print 20 whatever the number of units the AI own};

gamestate.js :

var GameState = Class({  _init: function(ai)  {    MemoizeInit(this);    this.ai = ai;    this.timeElapsed = ai.timeElapsed;    this.templates = ai.templates;    this.entities = ai.entities;    this.player = ai.player;    this.playerData = ai.playerData;	if (!this.ai._gameStateStore){		this.ai._gameStateStore = {};	}	this.store = this.ai._gameStateStore;  },  getPopulationLimit: function()  {    return this.playerData.popLimit;  },  getPopulationMax: function()  {    return this.playerData.popMax;  },  updatingCollection: function(id, filter, collection)  {    if (!this.store[id])    {      this.store[id] = collection.filter(filter);      this.store[id].registerUpdates();    }    return this.store[id];  },});

My goal is to read datas from entities. I don't like how scripting works... for example I have no idea what is saved in ent in the both cases of the for loops. Also I was struggling with how accessing a variable... I would like to know if it's possible to make a test if the variable exists or not, because if I write gameState.ProvencalLeGaullois there is no error/warning during the games...

Link to comment
Share on other sites

ok, after reading your answer I was able to get something "interesting" :

TestBotAI.prototype.OnUpdate = function(){  var gameState = new GameState(this);  var test = gameState.updatingCollection("test", Filters.byClass("Worker"), gameState.getEntities());  test.forEach(function(ent)  {    if( ent.owner() == gameState.player )    {      ent.setHitpoints(0); // see below      warn( ent.hitpoints() );    }  });  warn(test.length);};

this code create a collection (named test) of workers and then I set the hitpoints of each entity in test to 0 trough ent.setHitpoints(0).

The line,

warn( ent.hitpoints() );

print 0 as espected, but in game my entities hitpoints aren't updated. I guess it's because the collection copy the values, from the real "entity" value.

So now, my first question : it is possible to change hitpoints of an entity trough the AI script ? I guess no, I guess I have to write some code like cheat code and using Engine.PostCommand.

So this lead me to another qusetion, it would be more slow to read the true data of the entity ? I mean there is not possible to use a pointer to the true data ? in such case it would be possible to read and write in real time (I mean without having to update the collection).

Because right now, if we have to update each "turn" all collections, one for knowing the hitpoints of each entity, it would cost CPU time for nothing if in the game no hitpoints were modified.

and moreover collections are using memory (I guess not a big deal). I'm using JS since today, during my break time... so I guessed a lot...

  • Like 1
Link to comment
Share on other sites

AI's only have the same powers as normal users, so they can't set the health of a random unit to zero. There are some small exceptions though, like the AI can produce champion units from the barracks before it reached city phase. But that should be solved in the future.

Modifying direct data isn't possible due to possible Out-Of-Sync problems. When playing on a network, not all computers are equally fast, so one AI could have calculated something different than an other AI, or execute it on a different time, which causes different games for both players. This way, we just give an update to the AI every turn (200ms + lag) and require the AI to finish calculating before the next turn. So all the changes can be flushed at once.

Btw, for the specific case of setting hitpoints to zero, there should be some kill command.

Link to comment
Share on other sites

hi, sry for time to respond but I leaved my university to my mom house (America->Europe) and I forget my computer... so no 0AD until mid january...., there is a command to kill a unit but I use that one just for example. My aim is to create units or remove some units by events. I cannot check now without my computer :( but I guess it would be possible to write some commands like cheat code. After all if the human want to cheat in singleplayer it's not important...

you right about what you call a "small exception", because my proto AI built market/blacksmith... at the begining of the game in village phase... I asked myself if it's a bug.

it would be useful to get some commands to create/remove entity or setting the position of entity... by events for scenarii and for writting AI

Link to comment
Share on other sites

If you use one of the older AI APIs (only Aegis uses the most recent one), there are more of those exceptions. Like the ability to build buildings before the needed upgrade. But the more recent the API is, the less of those exceptions there should be.

Now, I don't think you want an AI, I think you really want triggers. We don't have triggers, and nobody is working on it. But in fact, it would need little less than a trigger editor. The maps can already contain scripts that can trigger events.

If you take a look at the Units Demo map. That map only has an XML file, but almost the entire XML file is JavaScript. The interesting part is that you can access the components. You can f.e. access the timer component and let it spawn some units 10 minutes after the map is loaded.

But as I said, we're not prepared for this. It would need a general design on how to structure the wanted triggers, probably in a trigger component.

This method is different per map though, but I think that's positive, as otherwise you could spawn your units in not-allowed places. You'll have to watch out for Atlas though. I've never tested what it does with in-map scripts. But I wouldn't be surprised if it just deletes the script when you save the map with Atlas.

Link to comment
Share on other sites

Is there a documentation about such .xml files (about it's structure and what can be done)?

Can they be used for random maps as well (and if, how)?

I have found this file by accident myself. It looks like it happens after the map initialisation (which is why that maps hangs a long time on 100%). I don't think you can use it for random maps, maybe via some ugly meta-scripting, but nothing nice. Apart from that, I think you'd want it to place the entities on the map, but that's not a very good idea, as the AI will be seriously confused when it starts its first turn without entities.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...