Transport Tycoon Forums

The place to talk about Transport Tycoon
It is currently Sun May 26, 2013 2:08 am

All times are UTC




Post new topic Reply to topic  [ 16 posts ] 
Author Message
PostPosted: Mon Jul 06, 2009 1:42 am 
Offline
Director
Director
User avatar

Joined: Tue Jan 22, 2008 4:33 pm
Posts: 564
Hi all,

I'm trying to get my AI up to date so I can release the next version (which is now ready, except for this), but the changes made for 0.7.1 have defeated me somewhat!

I can't call Sleep() or DoCommand() from any function. It says...

You are not allowed to call Sleep in your constructor, Save(), Load(), and any valuator.

and

You are not allowed to execute any DoCommand (even indirect) in your constructor, Save(), Load(), and any valuator.

However I'm not TRYING to do that from any of those restricted functions. I call Sleep() in the Start() function, and my first DoCommand (planting a tree) is triggered ultimately thought the Start() function (nested aout 5-6 function calls deep) and NOT in a valuator.

Since I missed the party when these changes were made to OpenTTD, are there any obvious things I can try before I start dumping huge volumes of code into this thread for you to look at?

Thanks :)

_________________
PathZilla - A networking AI - Now with tram support.


Top
 Profile  
 
PostPosted: Mon Jul 06, 2009 3:54 am 
Offline
OpenTTD Developer
OpenTTD Developer
User avatar

Joined: Mon Jun 09, 2003 6:21 pm
Posts: 3988
Location: /home/sweden
I also did my conversion long after the changes was made. And I do remember it took quite some time to fix all instances. Since sometimes a valuator call another function that then call Sleep or makes a DoCommand.

For valuators I'd recommend Yexos solution which is the variant of valuator replacement that has different call statements for different number of parameters, and then having just enough variants to cover all needed number of parameters.


Yet, if what you say is true, then you don't directly or indirectly call Start() from a Valuator or the Load/Save functions. So I can't really give you any specific advice, just wish you good luck. :-D

_________________
My OpenTTD contributions (AIs, Game Scripts, patches, OpenTTD Auto Updater, and some sprites)
Junctioneer (a traffic intersection simulator)


Top
 Profile  
 
PostPosted: Mon Jul 06, 2009 12:03 pm 
Offline
OpenTTD Developer
OpenTTD Developer

Joined: Thu Dec 20, 2007 12:49 pm
Posts: 3653
If you really get that message when calling Sleep from Start, please post your AI here.


Top
 Profile  
 
PostPosted: Mon Jul 06, 2009 12:31 pm 
Offline
Transport Coordinator
Transport Coordinator
User avatar

Joined: Fri Dec 19, 2008 5:03 am
Posts: 305
Location: Indonesia
That is why I've requested "here", to ease debugging :lol:

_________________
Correct me If I am wrong - PM me if my English was bad :D

**[OpenTTD AI]** Image
***[NewGRF] *** Image


Top
 Profile  
 
PostPosted: Mon Jul 06, 2009 1:15 pm 
Offline
Director
Director
User avatar

Joined: Tue Jan 22, 2008 4:33 pm
Posts: 564
Ok here is the code thats causing the problems...

Attachment:
pathzilla.tar [651 KiB]
Downloaded 53 times


I've managed to narrow down at least one problem. I have commented out some code to emphasize whats going on.

In the main loop in the Start() function the method ServiceManager.FindNewServices() is called. In there I have commented out most of everything except the following snippet...

Code:
targets.Filter(function (target, cargo) {
   return !target.ProducesCargo(cargo);
}, cargo);


If I also comment out this the error goes away. Note that the Sleep() call that triggers the error is not connected to this code in any way... it just follows it. targets is an instance of Map which has the following Filter() method, which uses acall.

Code:
function Map::Filter(filterFn, ...) {
   // Build an array of arguments for the filter function
   local argv = [];
   for(local i = 0; i < vargc; i++) {
      argv.append(vargv[i]);
   }

   // Select the keys for items to be removed
   local toRemove = [];
   foreach(key, item in this.data) {
      local args = [this, item];
      args.extend(argv);

      if(filterFn.acall(args)) {
         toRemove.append(key);
      }
   }

   // Remove them
   foreach(r in toRemove) {
      this.RemoveKey(r);
   }
}


So the ProducesCargo() method is called from within an acall...

Code:
function Target::ProducesCargo(cargo) {
   // Pre-condition - Check that the target is still valid
   if(!this.IsValid()) return false;
   
   // If the target is a town check each tile in its influence for production
   if(this.type == Target.TYPE_TOWN) {
      if(AICargo.GetTownEffect(cargo) == AICargo.TE_NONE) return false;
      
      local searchRadius = min(AIMap.DistanceFromEdge(this.tile) - 1, PathZilla.MAX_TOWN_RADIUS);
      local offset = AIMap.GetTileIndex(searchRadius, searchRadius);
      local tileList = AITileList();
      tileList.AddRectangle(this.tile - offset, this.tile + offset);
      tileList.Valuate(function(tile, id) {
         return AITown.IsWithinTownInfluence(id, tile);
      }, this.id);
      tileList.KeepValue(1);
      tileList.Valuate(function(tile, cargo) {
         return AITile.GetCargoProduction(tile, cargo, 1, 1, 0);
      }, cargo);

      return ListSum(tileList) > 0;
   }

   // Otherwise check the list of cargos for the appropriate industry type
   local indType = AIIndustry.GetIndustryType(this.id);
   if(!AIIndustryType.IsValidIndustryType(indType)) return false;
   return AIIndustryType.GetProducedCargo(indType).HasItem(cargo);
}


However this method doesn't Sleep or have any DoCommands. There are two things about this that confused me.

1) Why in an error thrown when I call Sleep(), when the error seems to be linked to an acall elsewehere?
2) Why is the acall triggering the error?

Is it the code within the acall, or just he use of acall itself? Am I allowed to use acall at all anymore?

I suppose I can get around this with Yexo's thingy, but I prefer to fix the root cause (if possible) or at least understand why this is going wrong.

Thanks very much guys :)

_________________
PathZilla - A networking AI - Now with tram support.


Top
 Profile  
 
PostPosted: Mon Jul 06, 2009 1:22 pm 
Offline
Engineer
Engineer

Joined: Mon Jun 01, 2009 8:13 pm
Posts: 49
I checked your AI out from your SVN to have a look, and while your code is way too advanced for me to understand completely I did notice that the first error (about the Sleep command) dissapeared when this.Sleep(workInterval) was commented out:
Code:
   // Start the main loop
   while(!this.stop) {
      // Try to keep the amount of funds available around FLOAT, by borrowing
      // or repaying the loan.
      FinanceManager.MaintainFunds(PathZilla.FLOAT);
      
      // Check for events
      this.HandleEvents();
      
      // Maintain existing services
      if(ticker % maintenanceInterval == 0) {
         this.serviceManager.MaintainServices();
      }
      
      // Look for some new services that we can implement
      this.serviceManager.FindNewServices();
      
      // Wait until we have a fair bit of cash before building a new line
      if(noServices || (ticker % expansionInterval == 0
          && FinanceManager.GetAvailableFunds() >= (AICompany.GetMaxLoanAmount() / 4))) {
         this.serviceManager.ImplementService();
         noServices = false;
      }

      // Advance the ticker
      ticker += workInterval;
      this.Sleep(workInterval);
   }


Then 2nd error (about the DoCommand) seems to come through the:
FinanceManager.MaintainFunds(PathZille.FLOAT);
-> line 77: success = FinanceManager.EnsureFundsAvailable(float)
-> line
-> line 54: success = AICompany.SetMinimumLoanAmount(requiredLoan);

that loan command is a DoCommand IIRC


Top
 Profile  
 
PostPosted: Mon Jul 06, 2009 1:25 pm 
Offline
OpenTTD Developer
OpenTTD Developer

Joined: Thu Dec 20, 2007 12:49 pm
Posts: 3653
Chruker wrote:
Then 2nd error (about the DoCommand) seems to come through the:
FinanceManager.MaintainFunds(PathZille.FLOAT);
-> line 77: success = FinanceManager.EnsureFundsAvailable(float)
-> line
-> line 54: success = AICompany.SetMinimumLoanAmount(requiredLoan);

that loan command is a DoCommand IIRC

Any function that changes the gamestate in any way (for example changing the loan amount) is a DoCommand.

Zutty: I'll download your AI tonight and see what I can find if you haven't fixed it by then.


Top
 Profile  
 
PostPosted: Mon Jul 06, 2009 1:59 pm 
Offline
Director
Director
User avatar

Joined: Tue Jan 22, 2008 4:33 pm
Posts: 564
Thanks Yexo. I'll try to replace all acalls with your workaround, but I'd still like to know whats going on.

Chruker - Thanks for taking a look. I forgot that taking out a lon is a DoCommand, which means that it is NOT the first DoCommand that causes problems as the AI is able to borrow money without throwing an error.

I'm not certain but it may be that its the first DoCommand after an acall which sets things off.

_________________
PathZilla - A networking AI - Now with tram support.


Top
 Profile  
 
PostPosted: Mon Jul 06, 2009 2:26 pm 
Offline
Engineer
Engineer

Joined: Mon Jun 01, 2009 8:13 pm
Posts: 49
Zutty wrote:
Chruker - Thanks for taking a look. I forgot that taking out a lon is a DoCommand, which means that it is NOT the first DoCommand that causes problems as the AI is able to borrow money without throwing an error.

I'm not certain but it may be that its the first DoCommand after an acall which sets things off.


It does seems as if the game forget that it have exited the valuator, and then it causes problems.


Top
 Profile  
 
PostPosted: Mon Jul 06, 2009 8:42 pm 
Offline
OpenTTD Developer
OpenTTD Developer

Joined: Thu Dec 20, 2007 12:49 pm
Posts: 3653
I have no idea what causes this, but I can confirm it's a bug in OpenTTD.


Top
 Profile  
 
PostPosted: Wed Jul 08, 2009 12:17 am 
Offline
Director
Director
User avatar

Joined: Tue Jan 22, 2008 4:33 pm
Posts: 564
Thanks for taking the time to look into this Yexo.

I have replaced all my custom function valuators with foreach loops, but I still have a problem with the pathfinder.

The library pathfinder uses a DoCommand (AIRoad.BuildRoad) and so throws the same error, but I can't really remove this without breaking the pathfinder.

Has anyone else been able to use the library pathfinder with 0.7.1? What am I doing wrong?

This is really frustrating. I've spent MONTHS trying to get this ready to release (I haven't added any features since April) but it seems no matter how many buigs I fix there are always more. :(

_________________
PathZilla - A networking AI - Now with tram support.


Top
 Profile  
 
PostPosted: Wed Jul 08, 2009 1:43 am 
Offline
Transport Coordinator
Transport Coordinator
User avatar

Joined: Fri Dec 19, 2008 5:03 am
Posts: 305
Location: Indonesia
well, there is roadpath finder in viewtopic.php?f=65&t=41435 (you start it :)) if it is still not working, probably still your code contain some error (read: restricted by ottd ) have a nice debugging.

_________________
Correct me If I am wrong - PM me if my English was bad :D

**[OpenTTD AI]** Image
***[NewGRF] *** Image


Top
 Profile  
 
PostPosted: Wed Jul 08, 2009 3:34 am 
Offline
Transport Coordinator
Transport Coordinator
User avatar

Joined: Fri Dec 19, 2008 5:03 am
Posts: 305
Location: Indonesia
Which library you are using?
It seem official road pf ver3 depend on aystar.4 wich is safe. If your pathfinder using aystar.5 thats would be problem because use call.

_________________
Correct me If I am wrong - PM me if my English was bad :D

**[OpenTTD AI]** Image
***[NewGRF] *** Image


Top
 Profile  
 
PostPosted: Wed Jul 08, 2009 10:08 am 
Offline
Engineer
Engineer
User avatar

Joined: Mon Jul 06, 2009 12:39 pm
Posts: 1
Location: England
Hi, I can't use any AI in 0.7.1 because it crashes out mostly on 1st Jan 1952, but sometimes it'll be within Feb 1952. The game runs fine single player though.

This is dumped to my [Linux] console :-

Code:
dduke[games]$ ./openttd
dbg: [misc] Nested widgets give different results
terminate called after throwing an instance of 'AI_VMSuspend'
Aborted
dduke[games]$


I found the closed bug in the bug tracker and got it re-opened -> http://bugs.openttd.org/task/2703

For the record I am using Zenwalk Linux 3.0, gcc 3.4.6, SDL 1.2.11 and I have had this distribution installed since 2006, compiled 1000s of applications and games (I compile mostly everything I install except Firefox) and my setup is very stable.

I am posting here to record my experience. If you need me to test something, I have the time to get involved.

Regards.


Top
 Profile  
 
PostPosted: Wed Jul 08, 2009 3:05 pm 
Offline
Engineer
Engineer

Joined: Mon Jun 01, 2009 8:13 pm
Posts: 49
Zutty wrote:
I have replaced all my custom function valuators with foreach loops, but I still have a problem with the pathfinder.


Did you put those updates on the SVN? I just updated my copy and there didnt seem to be much change (just common.nut).

If it is the newest I would suggest trying to rewrite it to not use the acall/call/pcall methods as per: viewtopic.php?f=65&t=43792


Top
 Profile  
 
PostPosted: Wed Jul 08, 2009 4:02 pm 
Offline
Director
Director
User avatar

Joined: Tue Jan 22, 2008 4:33 pm
Posts: 564
fanioz wrote:
Which library you are using?
It seem official road pf ver3 depend on aystar.4 wich is safe. If your pathfinder using aystar.5 thats would be problem because use call.


You're absolutely right fanioz, thanks :mrgreen: :bow:

I've upgraded to AyStar v6 and it works nicely. Hooray!

Thanks to everyone for their help. I really appreciate it.

_________________
PathZilla - A networking AI - Now with tram support.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 16 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  

Powered by phpBB © 2000-2013 phpBB Group

Copyright © Owen Rudge/The Transport Tycoon Forums 2001-2013.
Hosted by Zernebok Hosting.