quantumstate Posted April 8, 2012 Author Report Share Posted April 8, 2012 Here is an example of how to use the new API. The new API is almost completely backwards compatible with the old one with the only breaking change being the removal of ownEntities.if (!this.allWorkers){ var filter = Filters.or(Filters.byMetadata("role", "worker"), Filters.byMetadata("role", "militia")); this.allWorkers = gameState.getOwnEntities().filter(filter); this.allWorkers.registerUpdates()}When filtering from an existing entity collection the new collection will inherit the filters of the parent.This will make this.allWorkers contain an entity collection of all units with a role of either worker or militia which will be efficiently updated. For the updating collections to work you should use the filters provided by Filters.The special ownEntities case has been removed since this is easily implemented using Filters.byOwner.qBot's gamestate.js gives examples of how this new system could be used Quote Link to comment Share on other sites More sharing options...
wraitii Posted April 9, 2012 Report Share Posted April 9, 2012 I'm really wondering how much I should update Marilyn with the new persistent entityCollection system... It seems to rely on basically the same principle as my "unitInfoManager" (keeping track of units and adding/removing them as they appear/die). Did you do any specific optimization? I might just use it for the enemy and the attack plans/ "micromanager" managers which I plan to implement. Quote Link to comment Share on other sites More sharing options...
Almin Posted April 10, 2012 Report Share Posted April 10, 2012 I don't know, whether that's a bug or a feature, but you are aware of gameState.countFoundationsWithType(type) giving back the number of the foundations +1? Is this behavior intented? And just because I'm a little bit confused, this function returns only the number of foundation as not finished buildings. It does NOT include the number of buildings of the same type, which are already finished, does it? Quote Link to comment Share on other sites More sharing options...
gudo Posted April 10, 2012 Report Share Posted April 10, 2012 (edited) [EDIT]Never mind, answered my own question.[/EDIT] Edited April 10, 2012 by gudo Quote Link to comment Share on other sites More sharing options...
Relish Posted April 13, 2012 Report Share Posted April 13, 2012 what do you think about adding a couple of external interface functions to UnitAI.js to let the entity object know which entity it is attacking and which are attacking it?to enable something like this:entity.underAttackByEntities() that returns an array with the ids of the entity attacking itandentity.attackingEntity() that returns the id of the entity that it it is trying to attackthis would make it a lot easier to develop any kind of morale system Quote Link to comment Share on other sites More sharing options...
wraitii Posted April 15, 2012 Report Share Posted April 15, 2012 I've gotten a bug with the "Gamestate.getentitybiID" function as used by qBot... Apparently, you changed something, and now the Entity function wants to access "entity.template" when, in that case, it should access "entity._template._parent", unless I'm mistaken... Any information? Quote Link to comment Share on other sites More sharing options...
quantumstate Posted April 15, 2012 Author Report Share Posted April 15, 2012 I don't know, whether that's a bug or a feature, but you are aware of gameState.countFoundationsWithType(type) giving back the number of the foundations +1? Is this behavior intented? And just because I'm a little bit confused, this function returns only the number of foundation as not finished buildings. It does NOT include the number of buildings of the same type, which are already finished, does it?Returning the number of foundations +1 is not intended, however I am looking at the function and it looks fine to me.[b]GameState.prototype.countFoundationsWithType = function(type) { var foundationType = "foundation|" + type; var count = 0; this.getOwnEntities().forEach(function(ent) { var t = ent.templateName(); if (t == foundationType) ++count; }); return count;};[/b]It is just meant to count the number of in progress foundations. Quote Link to comment Share on other sites More sharing options...
Echelon9 Posted April 16, 2012 Report Share Posted April 16, 2012 No off-by-one in there? Quote Link to comment Share on other sites More sharing options...
wraitii Posted April 16, 2012 Report Share Posted April 16, 2012 Confirmed: you have introduced a bug between qBot and the common-api-v2: the gamestate GetEntityById function no longer works: this is because when creating an entity, it tries to access "entity.template", when it should try to access "entity.templateName" in that particular case (I think the other cases work properly). Quote Link to comment Share on other sites More sharing options...
quantumstate Posted April 16, 2012 Author Report Share Posted April 16, 2012 what do you think about adding a couple of external interface functions to UnitAI.js to let the entity object know which entity it is attacking and which are attacking it?to enable something like this:entity.underAttackByEntities() that returns an array with the ids of the entity attacking itandentity.attackingEntity() that returns the id of the entity that it it is trying to attackThis information is basically available to the AI. There are two different concepts of a unit attacking.The UnitAI controls each unit, and is now exposed to the AI's, so you should be able to use a combination of UnitAIState and UnitAIOrderData to work out what target a unit is attacking or trying to attack. You can read simulation/components/UnitAI.js for details. This won't tell you directly which units are attacking a unit, this information isn't stored by the game, but you could construct it yourself.Secondly there is a set of events sent each turn to the AI's, this is found in this.events if you are inheriting from the baseAI and contains a new set of events every time OnUpdate() is called. This will have an event for every time one unit does damage to another in an attack. You would again need to do some manipulation to get this information into the form you want.Confirmed: you have introduced a bug between qBot and the common-api-v2: the gamestate GetEntityById function no longer works: this is because when creating an entity, it tries to access "entity.template", when it should try to access "entity.templateName" in that particular case (I think the other cases work properly).Thanks, I have fixed this now.Edit:I'm really wondering how much I should update Marilyn with the new persistent entityCollection system... It seems to rely on basically the same principle as my "unitInfoManager" (keeping track of units and adding/removing them as they appear/die). Did you do any specific optimization? I might just use it for the enemy and the attack plans/ "micromanager" managers which I plan to implement.The updating entity collections handle updates to properties, not just unit creation/death, this will be especially important when we have unit conversion happening since most of the time you filter by owner. There isn't an real optimization currently, but if it runs too slowly then I was thinking of adding a hierarchical system to help with filtering. Quote Link to comment Share on other sites More sharing options...
Jubalbarca Posted April 16, 2012 Report Share Posted April 16, 2012 I'm not sure if morale would be an efficient system for an AI to use; what I'm working on is a system whereby it can run at the start of a battle, but if it commits it commits. Running away mid-battle is likely to lead to heavier losses for less gain/pain on the part of the enemy. Morale-based retreats happen in real life where people don't want to die; the AI has no such considerations really, it cares about whether its losses are efficient but not the life of any individual trooper.(This is incidentally why apparently, when a team of computer gamers controlled the enemy in a war-simulation to train US officer staff, the gamers won by miles. The US officers, trained to fight a real war, were careful to avoid un-necessary losses. The gamers, only used to playing games where efficiency trumps loss of life, happily ran some of their best squads in on a suicide mission, losing most of their best fighters but managing to destroy all the US supply bases and thus effectively winning the war as their opponents had no supply lines). Quote Link to comment Share on other sites More sharing options...
Mythos_Ruler Posted April 16, 2012 Report Share Posted April 16, 2012 (This is incidentally why apparently, when a team of computer gamers controlled the enemy in a war-simulation to train US officer staff, the gamers won by miles. The US officers, trained to fight a real war, were careful to avoid un-necessary losses. The gamers, only used to playing games where efficiency trumps loss of life, happily ran some of their best squads in on a suicide mission, losing most of their best fighters but managing to destroy all the US supply bases and thus effectively winning the war as their opponents had no supply lines).It's amazing what you can do when your soldiers have no fear of death. Quote Link to comment Share on other sites More sharing options...
Relish Posted April 17, 2012 Report Share Posted April 17, 2012 I'm not sure if morale would be an efficient system for an AI to use; what I'm working on is a system whereby it can run at the start of a battle, but if it commits it commits. Running away mid-battle is likely to lead to heavier losses for less gain/pain on the part of the enemy. Morale-based retreats happen in real life where people don't want to die; the AI has no such considerations really, it cares about whether its losses are efficient but not the life of any individual trooper.(This is incidentally why apparently, when a team of computer gamers controlled the enemy in a war-simulation to train US officer staff, the gamers won by miles. The US officers, trained to fight a real war, were careful to avoid un-necessary losses. The gamers, only used to playing games where efficiency trumps loss of life, happily ran some of their best squads in on a suicide mission, losing most of their best fighters but managing to destroy all the US supply bases and thus effectively winning the war as their opponents had no supply lines).In my AI I've tried a very simple approach (mainly to test how efficient my agent system was), making units escape a fight if engaged in an unfair fight (by number of enemy units) or if severely injured.The agent's plan was to escape into a safe location like a base, a tower or a regroup point with another group of units.In all the tests I did once the units escaped a difficult fight with minimal losses and their retreat to buildings or friendly units not only scattered my army but also turned the fight in their favour.What you are saying may be right in a clean contest where no other factors come into play, but in a game like this, where you can exploit buildings and movement, I think it could work. Quote Link to comment Share on other sites More sharing options...
wraitii Posted April 17, 2012 Report Share Posted April 17, 2012 Thanks for the answer Quantumstate... I guess I'll have to copy the code in a modified way for my unit/building managers, but i'll use entitycollections for the enemyWatchers.Retreat must be dealt with for small raids if you want to keep the army... For anything else, unless a specific unit must be preserved, it can be overlooked, I think. Quote Link to comment Share on other sites More sharing options...
wraitii Posted April 19, 2012 Report Share Posted April 19, 2012 I suggest, in entity.js, replacing the "ressourceSupplyAmount" and "RessourceCarrying" function by those, who check whether those parameters are defined: resourceSupplyAmount: function() { if(this._entity.resourceSupplyAmount == undefined) return undefined; return this._entity.resourceSupplyAmount; }, resourceCarrying: function() { if(this._entity.resourceCarrying == undefined) return undefined; return this._entity.resourceCarrying; }, Quote Link to comment Share on other sites More sharing options...
quantumstate Posted April 19, 2012 Author Report Share Posted April 19, 2012 I suggest, in entity.js, replacing the "ressourceSupplyAmount" and "RessourceCarrying" function by those, who check whether those parameters are defined: resourceSupplyAmount: function() { if(this._entity.resourceSupplyAmount == undefined) return undefined; return this._entity.resourceSupplyAmount; }, resourceCarrying: function() { if(this._entity.resourceCarrying == undefined) return undefined; return this._entity.resourceCarrying; },You have used a weak equality check so null, 0, ""and false will be changed to undefined, is that intentional and why would you want that to happen? If it wasn't intentional then you have basically inserted a null operation (though from a quick search we do seem to have some of these checks in the entity.js file already). Quote Link to comment Share on other sites More sharing options...
wraitii Posted April 19, 2012 Report Share Posted April 19, 2012 (edited) Mh, no, actually, should either be === "undefined" or === undefined, not sure which one works.I did that because if it is undefined, it will send a warning. It's not a huge problem ,I think it still works properly, but it can be a bit baffling. Edited April 19, 2012 by wraitii Quote Link to comment Share on other sites More sharing options...
quantumstate Posted April 20, 2012 Author Report Share Posted April 20, 2012 Mh, no, actually, should either be === "undefined" or === undefined, not sure which one works.I did that because if it is undefined, it will send a warning. It's not a huge problem ,I think it still works properly, but it can be a bit baffling.Interesting, I didn't think that would happen but it does as you say. I will make the changes you suggest. It is === undefined.Edit: I also think I have introduced a save/load bug with the new api, I will try and get this fixed soon. Quote Link to comment Share on other sites More sharing options...
quantumstate Posted April 20, 2012 Author Report Share Posted April 20, 2012 Fixed a problem with save/load so now it works. Quote Link to comment Share on other sites More sharing options...
feneur Posted April 20, 2012 Report Share Posted April 20, 2012 Fixed a problem with save/load so now it works. Quote Link to comment Share on other sites More sharing options...
wraitii Posted April 27, 2012 Report Share Posted April 27, 2012 (edited) Hi Quantumstate... A few more questions about the API.First, I'd recommend adding the "NOT" filter. It can be useful to check something like "Not a worker".Filters["not"] = function(filter1){ return {"func": function(ent){ return !filter1.func(ent); }, "dynamicProperties": filter1.dynamicProperties};};Secondly: you give every entity collection a "this._ai" property... It works as a reference and not as a copy, right? Javascript is messing with my brain about those things.Third: I sometimes get a "length NAN" error with entity collections if I don't ask for the length immediately after the entityCollection's creation. I guess that's an initialization error somewhere.Finally, and this is perhaps more of a general question, it seems that after some times, using a lot of entity collections, I get a "out of memory" error in GUI/sessio.js, in an (eval) or something... It doesn't always happen, and judging from the profiler, the AI script doesn't seem to overload. And there is no following crash. Any idea what this error is?edit: oh, and any ETA on AI support for technologies? Edited April 27, 2012 by wraitii Quote Link to comment Share on other sites More sharing options...
quantumstate Posted May 2, 2012 Author Report Share Posted May 2, 2012 Hi Quantumstate... A few more questions about the API.First, I'd recommend adding the "NOT" filter. It can be useful to check something like "Not a worker".Thanks I added this.Secondly: you give every entity collection a "this._ai" property... It works as a reference and not as a copy, right? Javascript is messing with my brain about those things.Yes, all assignments with objects or array in javascript are by reference.Third: I sometimes get a "length NAN" error with entity collections if I don't ask for the length immediately after the entityCollection's creation. I guess that's an initialization error somewhere.Thanks, I have fixed this. It happened when the entity collection had a unit added or removed before the length was requested. Trying to increment or decrement 'undefined' is a bad idea.Finally, and this is perhaps more of a general question, it seems that after some times, using a lot of entity collections, I get a "out of memory" error in GUI/sessio.js, in an (eval) or something... It doesn't always happen, and judging from the profiler, the AI script doesn't seem to overload. And there is no following crash. Any idea what this error is?Out of memory is a nasty one to debug, currently there isn't a good way I know to debug them. One that I came across before which hit some GUI javascript was a mismatched profiler start/stop which lead to the profiler tree continuously growing.edit: oh, and any ETA on AI support for technologies?Not currently, I am fairly busy at the moment. I also don't know quite how ti will be implemented. Quote Link to comment Share on other sites More sharing options...
wraitii Posted May 5, 2012 Report Share Posted May 5, 2012 Yes, all assignments with objects or array in javascript are by reference.Good to know, thanks!Out of memory is a nasty one to debug, currently there isn't a good way I know to debug them. One that I came across before which hit some GUI javascript was a mismatched profiler start/stop which lead to the profiler tree continuously growing.Allright, I'll keep watching.No problem about the technologies, take all the time you need, better done well than rushed.Another thing about the API: I see you use "VectorDistance" for "ByDistance" filtering... I've done checks in the past, and at least on my computer (but I'd expect on most), it was faster using SquareVectorDistance, even with the added multiplying (though by very little). Since afaik this will trigger for every position change for every entity in any entitycollection that requires it, I think it could be a, however little, welcome addition (if for some reason, one comes to do it 1000 times per turn in some extreme cases, it could make a difference). Quote Link to comment Share on other sites More sharing options...
quantumstate Posted May 9, 2012 Author Report Share Posted May 9, 2012 Another thing about the API: I see you use "VectorDistance" for "ByDistance" filtering... I've done checks in the past, and at least on my computer (but I'd expect on most), it was faster using SquareVectorDistance, even with the added multiplying (though by very little). Since afaik this will trigger for every position change for every entity in any entitycollection that requires it, I think it could be a, however little, welcome addition (if for some reason, one comes to do it 1000 times per turn in some extreme cases, it could make a difference).Thanks. I have changed my local copy. I will not commit right now because we are in feature freeze. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.