Unmapped error

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

Unmapped error

Post by R2dical »

I am consistently getting the error flag ERR_UNKNOWN thrown by AIError from either/and AITile.RaiseTile and AITile.LowerTile:

Code: Select all

			// Raise if lower.
			if (corner_height < desired_corner_height) {
				if(!AITile.RaiseTile(tile, slope_array[corner_index]))
					// Error handler.
					::main.ErrorHandler(this, "LandscapeSlope");              // See below....
				else
					landscape_success = true;
			}
			
			// Lower if higher.
			else if (corner_height > desired_corner_height) {
				if(!AITile.LowerTile(tile, slope_array[corner_index]))
					// Error handler.
					::main.ErrorHandler(this, "LandscapeSlope");              // See below....
				else
					landscape_success = true;
			}
			

/*
 *	Generic error handler which displays the latest error in log and breaks.
 *	For errors to be detected GetLastError must be called literally as the next thing
 *		after a DO COMMAND, no variables assignments in squirrel, nothing! Eg:
 *			if(!DoCommand(param))
 *				// Error handler.
 *				::main.ErrorHandler(class, function_name);
 *		AIError.GetLastError() is called in here.
 *	@param caller_object The class pointer for the function that called this error handler function, used for name reporting.
 *	@param function_name String of calling function name, for reporting.
 */
function RadAI::ErrorHandler(caller_object, function_name) {...}
I recall a mention on the forums to report any unmapped errors?
krinn
Transport Coordinator
Transport Coordinator
Posts: 339
Joined: 29 Dec 2010 19:36

Re: Unmapped error

Post by krinn »

R2dical wrote:I am consistently getting the error flag ERR_UNKNOWN thrown by AIError from either/and AITile.RaiseTile and AITile.LowerTile:
I recall a mention on the forums to report any unmapped errors?
Never read that, unknown errors are common on the API. Only errors that are obvious return an error. Unexpect, uncommon... don't.

So generally, if the arguments pass are valid, still you can get an error. for Raise/LowerTile the two should be a tile and a corner, there's a check against tile validity, so must be corner at fault. Corner arg should be an uint of SLOPE_XXX. So passing a valid uint32 but not of SLOPE_XXX type, it will try run it and you'll get unknown error back.
I didn't check but from the preconditions and parameters doc, nobody is telling you that uint32 is really check if it's a valid SLOPE_XXX value.

And no, your partial code isn't of help, but you could check your slope_array[corner_index] value, just add it ::main.ErrorHandler(this, "LandscapeSlope"+" slope:"+slope_array[corner_index]+" index:"+corner_index) as i suppose the 2nd parameter is output in your error handler.
R2dical
Traffic Manager
Traffic Manager
Posts: 163
Joined: 18 Mar 2013 22:22

Re: Unmapped error

Post by R2dical »

Thanks for your reply.
krinn wrote:Never read that, unknown errors are common on the API. Only errors that are obvious return an error. Unexpect, uncommon... don't.
On the wiki:
wiki wrote:AIError.ERR_UNKNOWN: There has been an error which hasn't been mapped to NoAI. This can either mean 2 things, there is no StringID for this error or we forgot to map it. In the latter case please file a bug report and tell us about it so we can fix it.
Wasn't quite sure what this meant, so I report it here before a FS report...

Possibly due to the next part I have only seen ERR_UNKNOWN a handful of times:
krinn wrote:So generally, if the arguments pass are valid, still you can get an error. for Raise/LowerTile the two should be a tile and a corner, there's a check against tile validity, so must be corner at fault. Corner arg should be an uint of SLOPE_XXX. So passing a valid uint32 but not of SLOPE_XXX type, it will try run it and you'll get unknown error back.
I didn't check but from the preconditions and parameters doc, nobody is telling you that uint32 is really check if it's a valid SLOPE_XXX value.
I always have validation for ,y public member's parameters:

Code: Select all

	// Validate.
	if (!AIMap.IsValidTile(tile)) throw(this.class_name + "::LandscapeSlope: Param 1 must be valid tile!");
	if (typeof(desired_slope) != "integer" || !MapBuilder.IsValidSlope(desired_slope)) throw(this.class_name + "::LandscapeSlope: Param 2 must be valid slope!"); *
	* Checks true/false if the param is one of the AITile.SLOPE_XXX enums, AITile.SLOPE_INVALID returns false.
In this case the corner param for the Raise/LowerTile is always valid anyway since I have this just above the Raise/LowerTile part:

Code: Select all

local slope_array =		[AITile.SLOPE_N,	AITile.SLOPE_E,		AITile.SLOPE_W,		AITile.SLOPE_S];
So my call "if(!AITile.RaiseTile(tile, slope_array[corner_index]))" will always have valid parameters :(
User avatar
Zuu
OpenTTD Developer
OpenTTD Developer
Posts: 4553
Joined: 09 Jun 2003 18:21
Location: /home/sweden

Re: Unmapped error

Post by Zuu »

When I run into problems like this one, I often look up the implementation details to see if that tells me something. If it is not obvious, I'll compile a copy of OpenTTD and run it with the Visual Studio debugger. Put a break point in the API cpp file and follow the execution path. This will usually give insights why I get the result I got.

Obviously this needs two things:
  • An AI/GS script that reproduce the API call situation that you want to debug. It is also helpful if this happen quite quickly and not 10 years into the game play. Especially if you use OpenTTD debug builds which are quite a bit slower than normal. But in Visual Studio you can invest some 30 seconds longer link time and get a release build that run quite fast and allow following the execution path within the OpenTTD code.
  • Having set up libraries + Visual Studio (or equivalent program(s) that offer compiler + debugger)
My OpenTTD contributions (AIs, Game Scripts, patches, OpenTTD Auto Updater, and some sprites)
Junctioneer (a traffic intersection simulator)
krinn
Transport Coordinator
Transport Coordinator
Posts: 339
Joined: 29 Dec 2010 19:36

Re: Unmapped error

Post by krinn »

R2dical wrote: In this case the corner param for the Raise/LowerTile is always valid anyway since I have this just above the Raise/LowerTile part:

Code: Select all

local slope_array =		[AITile.SLOPE_N,	AITile.SLOPE_E,		AITile.SLOPE_W,		AITile.SLOPE_S];
So my call "if(!AITile.RaiseTile(tile, slope_array[corner_index]))" will always have valid parameters :(
No it is not always :)

Code: Select all

if (corner_height < desired_corner_height) {
            if(!AITile.RaiseTile(tile, slope_array[corner_index]))
This mean that if corner_height=4 and desired_corner_height = 6 you will at fisrt iteration raise SLOPE_N (or EWS), and at second iteration reask exactly the same thing ; and this is clearly a case where you can get a "unknown error" typeof error.

While you were trying to end with a steep slope, and instead of asking SLOPE_N two times, you should have ask SLOPE_STEEP_N

In a more human language :
Set North corner high
>ok
Set North corner high
>WTF North corner is high already

Edit: Adding visual explain (i redig my slope link)
http://newgrf-specs.tt-wiki.net/wiki/NM ... ile_slopes
from a flat tile, asking to raise SLOPE_N two times, you will endup with #8+unknown and not like you think ending with #29 (that should be asked with SLOPE_STEEP_N)
R2dical
Traffic Manager
Traffic Manager
Posts: 163
Joined: 18 Mar 2013 22:22

Re: Unmapped error

Post by R2dical »

krinn wrote: In a more human language :
Set North corner high
>ok
Set North corner high
>WTF North corner is high already
Good eye! But I am getting errors with my calls for creating tiles suitable for building locks, always one of the 4 "flat-slope" tiles (I have a switch using SLOPE_NE, SLOPE_NW, SLOPE_SE, SLOPE_SW to call this MapBuilder function). In any case I did a quick test with a steep slope for this function and it works as expected, converting any tile slope to the desired SLOPE_STEEP_N.

(FYI, been avoiding posing the whole function as it is quite long, but it is viewable on the bitbucket repository (2014-04-07 revision).)
Zuu wrote:When I run into problems like this one, I often look up the implementation details to see if that tells me something. If it is not obvious, I'll compile a copy of OpenTTD and run it with the Visual Studio debugger. Put a break point in the API cpp file and follow the execution path. This will usually give insights why I get the result I got.
Thanks Zuu, think I need to do some of this to find out whats going wrong :)
Post Reply

Return to “OpenTTD AIs and Game Scripts”

Who is online

Users browsing this forum: No registered users and 13 guests