AI concept questions

Discuss the new AI features ("NoAI") introduced into OpenTTD 0.7, allowing you to implement custom AIs, and the new Game Scripts available in OpenTTD 1.2 and higher.

Moderator: OpenTTD Developers

Post Reply
R2dical
Traffic Manager
Traffic Manager
Posts: 163
Joined: 18 Mar 2013 22:22

AI concept questions

Post by R2dical »

I am working on a new AI (and am enjoying it quite a bit I must say :) ) and have some questions regarding a few things. I thought I'd keep them all in one thread rather than possibly dig up old ones, etc. I apologise in advance if these questions have been answered already or are documented in the various other places of information, though I have looked in the wiki, noai docs, other AI code and other threads.

So first question; is there a way to get the actual cargo production a station will receive, based on the formula in the wiki?
As far as I can tell there is no way to derive this with the API, because you cannot evaluate other companies stations.
krinn
Transport Coordinator
Transport Coordinator
Posts: 342
Joined: 29 Dec 2010 19:36

Re: AI concept questions

Post by krinn »

Well, to evaluate, you still can get hints :
- GetLastMonthProduction - GetLastMonthTransported = remain to do
- GetAmountOfStationAround = clue for number of people there
- GetLastMonthTransportedPercent = clue on how stations there are doing a good/bad job.


It depend how you want handle that, simpleAI won't do it if TransportPercent is below a trigger value (60% if i remember well), and in my AI it depend on level settings and amount of competitors station around (the GetAmountOfStationAround less my stations).
I'm unsure for other AIs, but i don't think anyone has gone into high probabilistic heurist for this, as except for applying the math of the wiki for the fun, there's no real need to get it that close to real result : as the real issue is just can you make profit out of it or not.
R2dical
Traffic Manager
Traffic Manager
Posts: 163
Joined: 18 Mar 2013 22:22

Re: AI concept questions

Post by R2dical »

Thanks for the reply krinn.

I am trying to get it as accurate as possible because of my concept for the AI. The idea is to use some evolutionary algorithms to fine tune all the main function heuristics to the current game and to provide some variety. For example the pathfinder variables, and I have a genetic algorithm to solve the travelling salesman problem.

For some functions it is not really important, imo at least, to have great accuracy or it is not worth the time it takes to calculate. But I was hoping to get a good one for this because I will use it for town & industry station design as well as route selection based on competitors. I thought there was a way in API since for a human player that data is visible.

I took a look at your use of GetAmountOfStationAround in DictatorAI, the function to only get competitors ones, and think something close could work though. Thanks :)
R2dical
Traffic Manager
Traffic Manager
Posts: 163
Joined: 18 Mar 2013 22:22

Re: AI concept questions

Post by R2dical »

Ok, I have a few more questions...

Firstly, can the AI buy land?

Next, and related to my OP question, I noticed recently that stations have a monthly supply amount next to cargo and rating (I assume this is a recent addition, or else I never noticed before AI developing :lol: ). Is there a way to get this value in API? It seems an accurate monthly cargo amount and I am struggling quite a bit to get a good estimate for AI to decide how many vehicles will be optimal for a route, mainly for town to town passengers transport with buses.

Lastly, has anyone been testing AI's with the new cargodist? Seems like its going to be very difficult to get good numbers for cargo estimates, especially for towns, when networks and competition become more complex.
krinn
Transport Coordinator
Transport Coordinator
Posts: 342
Joined: 29 Dec 2010 19:36

Re: AI concept questions

Post by krinn »

R2dical wrote:Firstly, can the AI buy land?
Yes and no
No as you cannot use the buy land function,
And yes as you can buy land with any object to block it: a depot can do that, or an X rails (to disallow roads on it).
But both have maintenance costs the buy land don't have.
And i'm not sure a player may like that seeing plenty depot everywhere or X rails or anything you use : and this include seeing buy signs.
I'm sure player don't like seeing buy signs from other human player, but it's in the game they could accept it.
But once you remove the "human" term in <done by another human player>, player nerves tend to get hot.
- You can do it
- You cannot do it with buy land signs
- You shouldn't do it to not hurt player nerves and get your AI blackilist to play against.

If a human wants buy an intercon, it will need to clicks 11x9 times to buy each tiles. With an AI that can do that in 1 tick.
100 towns x tiles to buy : human need 100*11*9 : 9900 clicks : needed various time to accomplish.
an AI can buy the 9900 tiles in what 100 ticks ?
I noticed recently that stations have a monthly supply amount next to cargo and rating (I assume this is a recent addition, or else I never noticed before AI developing :lol: ). Is there a way to get this value in API? It seems an accurate monthly cargo amount and I am struggling quite a bit to get a good estimate for AI to decide how many vehicles will be optimal for a route, mainly for town to town passengers transport with buses.
It looks like per station result of : http://wiki.openttd.org/Game_mechanics# ... o_stations
a rought GetLastMonthProduction * station_rating, more precise because if in the month your rating has move the amount can change every 2.5 days.
Lastly, has anyone been testing AI's with the new cargodist? Seems like its going to be very difficult to get good numbers for cargo estimates, especially for towns, when networks and competition become more complex.
yep, without a good result :)
http://bugs.openttd.org/task/5673
Brumi
President
President
Posts: 921
Joined: 18 Jul 2009 17:54

Re: AI concept questions

Post by Brumi »

Lastly, has anyone been testing AI's with the new cargodist? Seems like its going to be very difficult to get good numbers for cargo estimates, especially for towns, when networks and competition become more complex.
I haven't tested it yet actually, but I suppose cargodist simply doesn't affect SimpleAI with its point-to-point connections :)
R2dical
Traffic Manager
Traffic Manager
Posts: 163
Joined: 18 Mar 2013 22:22

Re: AI concept questions

Post by R2dical »

Thanks for the reply krinn.

I did consider the rail X as a way to reserve land, as you can sell it again quickly before use for some money back. The problem ended up coming down to the maintenance, because I wanted to use this to reserve good tiles in a town to expand stations in early game, also for airports. Over a few towns this started adding up, and yeah I think a human player will have little tolerance for this tactic...
So I gave up on the concept but remained curious as to if it was possibly for AI to buy land.
krinn wrote:a rought GetLastMonthProduction * station_rating
The problem with this is for towns, where as far as I can tell production is dependant on the number of houses you cover (couldn’t find much info on this). I know a lot of the AIs build a small number of initial vehicles, then modify count based on a few rules and heuristics. Why I avoid this is because I want a competitive AI able to start with and keep high ratings. Building too many on the other hand can cause major traffic jams if the town is big and the overestimate large :shock:
krinn wrote:yep, without a good result :)
http://bugs.openttd.org/task/5673
Hmm, I'm interested to see what will happen when this goes live with the stable, because I'm seeing problems with some multi-connection town networks even on my very basic AI. Maybe a push for other developers to update AI's from older APIs and mechanics :)
svetovoi
Engineer
Engineer
Posts: 87
Joined: 12 Oct 2007 14:07

Re: AI concept questions

Post by svetovoi »

R2dical wrote: The problem with this is for towns, where as far as I can tell production is dependant on the number of houses you cover (couldn’t find much info on this). I know a lot of the AIs build a small number of initial vehicles, then modify count based on a few rules and heuristics. Why I avoid this is because I want a competitive AI able to start with and keep high ratings. Building too many on the other hand can cause major traffic jams if the town is big and the overestimate large :shock:
You can't really accurately predict/calculate cargo flow, only react to it and its fluctuations(even for industries btw). Hence the runtime vehicles amount approximation. In the end this method works very well, that's why most AIs are using it I think.
Initial amount is not all that important. Unless you first guess is terribly wrong, like REALLY wrong(4-5x times or something), the stuff will easily catch up to near optimal values in one or two iterations.
R2dical
Traffic Manager
Traffic Manager
Posts: 163
Joined: 18 Mar 2013 22:22

Re: AI concept questions

Post by R2dical »

Yeah you are right I think, I am having some success with my current initial estimate algorithm, counting houses in station coverage then multiplying by (total town production / total town house count), but not sure if it will work as nice with grfs. A few iterations of another monitoring algorithm gets it pretty close to optimal before the ratings drop significantly.

I was hoping to avoid calling a monitoring function too often, at least with towns which are fairly predictable, so to allow more game time for intensive path finding or high level planning routines. Although generator functions or incremental search and save might work there...
R2dical
Traffic Manager
Traffic Manager
Posts: 163
Joined: 18 Mar 2013 22:22

Re: AI concept questions

Post by R2dical »

carl_06 wrote:Nice post !
Uhmm, thanks? :)

---

Ok another question along a new direction...how important is it to incorporate flexibility in the AI in terms of reading data off the map as well as from different AI or even old versions of your same AI? Passed in from the internal "load" function I mean.

I'm busy adding in save support now and been reading through some old posts in this subforum, early on it seemed quite important to allow for on-the-fly data structuring based of what your company has on the map after load, rather than relying strictly on what is saved. This makes sense if you can't depend on loading always giving you appropriate data.

It seems to me that with the bananas content system and how the game loads AIs, it is quite reasonable to rely solely on saving/loading via internal method and skip rebuilding with map scanning entirely. This saves effort and allows for more intricate record keeping... :)
krinn
Transport Coordinator
Transport Coordinator
Posts: 342
Joined: 29 Dec 2010 19:36

Re: AI concept questions

Post by krinn »

The more you read from the map, the less you save.
It seems you didn't yet reach it, but there's a time limit to save. If your AI cannot save within that limit, it won't save anything.

Sure you can save stationID, but when your AI have 300 station, you will need to save 300 stationID, and the time to do that.
Or when your AI is loading, it can read map/query API to find what are your station and go on.

After seeing you have X values that you cannot read from map and that you must save, you'll go on lowering amount of datas you are saving to higher the amount of criticals datas you really need to save and higher your chance to avoid the time limit.

Save/load is easy to do when you are building your AI, as you save all you need. And this will work, but once you're AI advance, your tests push the AI farer : bigger maps, and more years of playing : all this raise the amount of datas need to save as you have more stations, more vehicles... everything gets high : and than you see saving all vehicles wasn't a problem with 30 vehicles, but with 500 "your AI tooked to long to save..."
In fact, the better your AI perform, the faster you'll hit the time limit.

GS also have that time limit.

For the AI reading older saving : there's no rules there, except your users patience : user start a map with GS/AI v1 save, update to new v2 AI/GS and his happy to get bug fixes and new stuff. But if your GS/AI cannot read the save format from v1 : user must restart a map and cannot play the savegame they were playing.
remember :
love to quote myself wrote:- You shouldn't do it to not hurt player nerves and get your AI blackilist to play against.
Brumi
President
President
Posts: 921
Joined: 18 Jul 2009 17:54

Re: AI concept questions

Post by Brumi »

My AI is fully backwards compatibile regarding savegames, the newer versions usually save more data, so loading a savegame from an older AI isn't hard, just some data are missing. I use the save() function to save my data, which I think is easier, but, for example, Zuu reads everything from the map in his AIs. His approach may be more robust.
I don't think you should care about continuing games started by other AIs, no AI supports loading games from other AIs afaik. You can be the first with such a feature, I just think it's not worth the effort :)
R2dical
Traffic Manager
Traffic Manager
Posts: 163
Joined: 18 Mar 2013 22:22

Re: AI concept questions

Post by R2dical »

Thanks for your thoughts.

I had considered the save time limit, but did not realise that it was short enough to be so common... Indeed that complicates things a bit. What generally takes longer data building or data transfer?

Maybe it can work if you preprocess and prepare a data table to save? I took a nice idea from Admiral which does this on main instance constructor (call an Init function with what you would normally have in the constructor as first thing in Start) as well as Load which copies the data table to main instance variable to process using an AfterLoad function. These were done to avoid the "taking too long" error. Maybe the same thing will work for a preprocessed data table which the Save function only has to copy. It would be a bit of a pain as it would require updating every time a saveable class objects variables are changed, also slowing these down a bit...maybe worth it though.
krinn
Transport Coordinator
Transport Coordinator
Posts: 342
Joined: 29 Dec 2010 19:36

Re: AI concept questions

Post by krinn »

R2dical wrote:What generally takes longer data building or data transfer?
building.
if data are in a compatible format, you just push the data to the save. The transfert itself doesn't count at all, as it is done by returning the save table.
Maybe it can work if you preprocess and prepare a data table to save?
- You can use datas in a compatible format with the save table : https://wiki.openttd.org/AI:Save/Load
- Use datas as you like with a function that convert them while processing them as you suggest, so your savedata are ready when asked
- Convert them when saving: that's the biggest pitfall, but if you don't do that on a lot of datas, it's ok

The problem is really with instance, that cannot be push to the save table as-is.
There's another one high for AI that shouldn't be one for GS (bridge, road & rails).
svetovoi
Engineer
Engineer
Posts: 87
Joined: 12 Oct 2007 14:07

Re: AI concept questions

Post by svetovoi »

Yeah, the ticks limit was such a pain that I've reduced save/load points to:

Code: Select all

function Save()
{
	return {save_document = Terron.memento[0]};
}

function Load(v, data)
{
	this.save_data = data.rawget("save_document");
} 
R2dical wrote:Maybe it can work if you preprocess and prepare a data table to save?...
...It would be a bit of a pain as it would require updating every time a saveable class objects variables are changed, also slowing these down a bit...maybe worth it though.
Was totally worth it, IMO.
User avatar
Core Xii
Traffic Manager
Traffic Manager
Posts: 228
Joined: 08 Apr 2008 09:47
Location: Finland

Re: AI concept questions

Post by Core Xii »

I store everything that my AI needs to remember into a single table (containing nested tables of course). I convert floats into strings whenever writing to this table (and back to float when reading), because floats can't be saved. No object instances; all of my "objects" are just cloned Squirrel tables, and all of my "pointers" just keys to tables containing these "objects". Then in my Save() function, I just pass it the grand table containing everything, and likewise on Load() just set the loaded data as my data table. So basically I do no processing at all on save nor load.

There are a few exceptions to this:

All pending events must be polled and converted to table representation for saving. ET_ENGINE_PREVIEW and ET_COMPANY_ASK_MERGER events have to be handled before saving, because you need to call AcceptPreview() and AcceptMerger() on the event objects to respond to them, and because those are object instances which can't be saved, and OpenTTD does not persist pending events for you, those events can't be saved. (I really wish OTTD just transparently saved events)

Because OpenTTD may hijack the AI thread at any time to save, and it could have been in the middle of some calculation, but on Load() that calculation is lost, certain data in the table may be in an inconsistent state. Thus, after Load(), I invalidate certain cached values which may not be current.
R2dical
Traffic Manager
Traffic Manager
Posts: 163
Joined: 18 Mar 2013 22:22

Re: AI concept questions

Post by R2dical »

Thanks for all your thoughts, they have thankfully given me some ideas :)

Save/Load is definitely more intricate and complex than first look, I read some older discussions involving when the game calls the AI save function, and it happening at any time even between say building a vehicle and starting it.

So all these things have to be considered and built into the foundation of AI data structures and also how it loads again.

I like the idea of having one main table for all data, which would replace class member variables it seems, and passing this straight to save. This sounds best suited to "abstract" AI work like route planning and internal relationships.

I also read about using game names to store AI data, like vehicle, stations and group names. I think this would be well suited to the "physical" AI parts relating to the obvious, maybe a VERY limited number of signs can store things like path finding data and the player wont mind...I think a number of AIs do this already.
Using the point of naming these would divide the point of importance, so on load all unidentifiable vehicles are sold without issue for example...

I think a combination of these is maybe the most robust and convenient to work with, it will take some restructuring though :? I plan to take a look at your guys AIs for some more ideas :)
User avatar
Zuu
OpenTTD Developer
OpenTTD Developer
Posts: 4553
Joined: 09 Jun 2003 18:21
Location: /home/sweden

Re: AI concept questions

Post by Zuu »

R2dical wrote:I also read about using game names to store AI data, like vehicle, stations and group names. I think this would be well suited to the "physical" AI parts relating to the obvious, maybe a VERY limited number of signs can store things like path finding data and the player wont mind...I think a number of AIs do this already.
Using the point of naming these would divide the point of importance, so on load all unidentifiable vehicles are sold without issue for example...
Signs as in AISign.BuildSign are a bit unsafe, as players of opponent companies can remove your signs if they wish. If you want to make it permanent, it has to be a waypoint, station, vehicle etc. I believe you could (ab)use some empty vehicle groups and use their name for storage.

Though, yes my personal idea with using names for storage has been to store things related to the object that the data concerns. Station names has shown to be a bit sensitive to use, as some players dislike that AIs rename their stations. However, vehicle names should be more safe as they are not shown to opponent players unless they click on the vehicle.


Regarding having a table prepared for save. It may be good if your management methods use local storage and only when they are done, replace the old save data with the new one in one assignment. This way you reduce the risk of having the master data table in a broken state while Save is called.

Note the difference between these two solutions:

Code: Select all

this.master_table.vehicle_data = ManageVehicles();

Code: Select all

local data = ManageVehicles();
this.master_table.vehicle_data = data;
In the first case you will start to modify the master table earlier than you may think it will do! Squirrel does not work the way that ManageVehicles() must first return before it modify the master table in the first code example. By using the second code solution, you enforce the master table is left unchanged until ManageVehicles() has finished and do the assignment in one command. I'm not 100 % sure, but hopefully this assignment will not be split over multiple ticks. If you want to be even more sure that the assignment will not abort halfway through due to using up all oopcodes of the current tick, you could call AIController.Sleep(1) before the assignment to delay it into the beginning of next tick when you got 10 000 new fresh oopcodes. (note # of oopcodes can be changed in advanced settings. 10 000 is the default value)
My OpenTTD contributions (AIs, Game Scripts, patches, OpenTTD Auto Updater, and some sprites)
Junctioneer (a traffic intersection simulator)
R2dical
Traffic Manager
Traffic Manager
Posts: 163
Joined: 18 Mar 2013 22:22

Re: AI concept questions

Post by R2dical »

Thanks for the tips Zuu, very useful.

I should be able to keep all required info in station names in a very eye friendly and non-intrusive format, hopefully this is ok for most players...

For functions and assignment in squirrel, interesting I would never have expected that!
Post Reply

Return to “OpenTTD AIs and Game Scripts”

Who is online

Users browsing this forum: No registered users and 17 guests