Jump to content
Sign in to follow this  
galzohar

Impossible "undefined variable" error?

Recommended Posts

On very rare occasions, player get an error "undefined variable in expression".

Game logic init line:

hNil = [] call compile preprocessFile "preinit.sqf"; preInitDone=true;

preinit.sqf has:

// Create a mission entry for the server and client RPT file, easier to debug when you know what mission created the error
diag_log text ""; 
diag_log text format["|=============================   %1   =============================|", missionName]; // stamp mission name
diag_log text "";

ace_sys_wounds_no_medical_gear=false;

// F2 - Process ParamsArray Modified by Galzohar
// Credits: Please see the F2 online manual (http://www.ferstaberinde.com/f2/en/)
// ====================================================================================

for [ { _i = 0 }, { _i < count(paramsArray) }, { _i = _i + 1 } ] do
{
_paramName =(configName ((missionConfigFile >> "Params") select _i));
_paramValue = (paramsArray select _i);
missionNameSpace setVariable [_paramName, _paramValue];
};

// ====================================================================================

init.sqf has:

waitUntil {!isNil "preInitDone"}; // just to make sure, even though game logic should run first anyway

// some more code

execVM "idf_assigngear.sqf";

Then the error says the variable (same name as one of the classes from description.ext, like it's supposed to be) is undefined, in script idf_assigngear.sqf. 99% of the time the error doesn't occur and everything works fine, so there probably isn't anything fundamentally wrong with the way the variables are being defined...

Any ideas for what can be causing this error?

Edited by galzohar

Share this post


Link to post
Share on other sites
99% of the time the error doesn't occur and everything works fine, so there probably isn't anything fundamentally wrong with the way the variables are being defined...

My experience with errors like this would make me think it's some kind of timing issue. Something (probably an array) is not being initialised completely before being referenced.

Share this post


Link to post
Share on other sites

However as you can see there is a waitUntil to make sure things run in order (other than the fact that they should run in order regardless). My only guess would be that the parameter reading script simply fails randomly...

Share this post


Link to post
Share on other sites

!isNil preInitDone -> !isNil "preInitDone"

Share this post


Link to post
Share on other sites

You're correct, however the error is only in the post. The script had it in the correct form. Edited original post accordingly.

Share this post


Link to post
Share on other sites

whats the exact rpt error

Share this post


Link to post
Share on other sites

What if you put preInitDone = true into preinit.sqf?

This shouldn't be the problem I am just curious if it makes any difference.

Share this post


Link to post
Share on other sites

Please include the exact rpt error, without it it turns into a guessing game.

Share this post


Link to post
Share on other sites

I don't have it anymore, and it's quite rare to be able to reproduce it, but it was pretty much:

Undefined variable in expression "isBox"

Where that variable is defined in preinit.sqf (description.ext has a parameter class called isBox).

And again testing solutions is very difficult because I play this mission with friends on a regular basis and so far only got the error happen once to a single guy (and when he re-joined the mission everything worked fine).

Placing the preInitDone=true; in the preinit.sqf script gives an even more strange error:

Error in expression <hNil = [] call compile preprocessFileLineNumb>
 Error position: <= [] call compile preprocessFileLineNumb>
 Error Generic error in expression

When the script is just what is quoted in the original post, everything works (well, 99.9% of the time). Usually those errors happen when there's a waitUntil or sleep in un-interruptible code, but this isn't the case...

Edited by galzohar

Share this post


Link to post
Share on other sites

As you are using ACE anyway, means you also use CBA...

Why not make use of the Extended Eventhandlers in your mission ?

You can add all available XEH handlers to your description.ext and make use of preinit EH (which runs before anything else and is executed only once).

For example:

class Extended_PreInit_EventHandlers {
class galzMission {
	init = "call compile preprocessFileLineNumbers 'XEH_preInit.sqf'"; // will be executed on server and clients
	serverinit = "call compile preprocessFileLineNumbers 'XEH_preServerInit.sqf'"; // server only
	clientinit = "call compile preprocessFileLineNumbers 'XEH_preClientInit.sqf'"; // clients only
};
};

// just as another example
class Extended_GetIn_EventHandlers {
class Air {
	class galzMission {
		clientGetIn = "if ((_this select 2) == player) then {_this call getin_fnc_whatever}";
	};
};
};

Adding actions to vehicles, with an Extended_Init_Eventhandler in description.ext and the right class, totally easy.

As you can see, you can limit EHs to clients or server only.

Edit:

In preinit you can precompile functions, setup variables and so on. They are then available in inits (editor, vehicle inits).

Xeno

Edited by Xeno

Share this post


Link to post
Share on other sites

OK, thanks, I'll try that, though I'm not really sure that it actually is a timing issue (because the waitUntil should verify order of running things).

Share this post


Link to post
Share on other sites

Well it seems like something is wrong with this part of the code:

for [ { _i = 0 }, { _i < count(paramsArray) }, { _i = _i + 1 } ] do
{
_paramName =(configName ((missionConfigFile >> "Params") select _i));
_paramValue = (paramsArray select _i);
missionNameSpace setVariable [_paramName, _paramValue];
};

Since when commenting it out, commands added after it no longer cause the weird "generic error in expression" error.

I have however absolutely no idea what can be wrong with this simple loop, especially when it does work most of the time if (and only if) there is no code following it.

EDIT: Seems like replacing the first line in the above code with

for "_i" from 0 to ((count paramsArray)-1) do

fixes the "generic error in expression" problem. Quite weird indeed.

Edited by galzohar

Share this post


Link to post
Share on other sites

for [ { _i = 0 }, { _i < count(paramsArray) }, { _i = _i + 1 } ] do

The square brackets shouldn't be there!

Share this post


Link to post
Share on other sites
http://community.bistudio.com/wiki/for

According to the wiki they should, at least if you use that form of "for" loop. And it was working mostly, aside from the weird issues described in previous posts.

Actually yes...you're right! Lol! ....and I use that all the time. It just looked strange there for some reason. Sorry!

Share this post


Link to post
Share on other sites

The difference between

for [ { _i = 0 }, { _i < count(paramsArray) }, { _i = _i + 1 } ] do

and

for "_i" from 0 to ((count paramsArray)-1) do

is that the first form uses a variable in the outer scope whereas the second introduces a new private variable. It's very hard to see how this could lead to errors though unless you are calling some code later on which assumes that _i (or even _paramName/Value) has a particular initialisation value.

Still, it would be interesting to see if you still get the error if you try changing the name of the variable to something less likely to collide with others or change the form of the code to

setvars ={

private ["_i","_paramName","_paramValue"] ;

for [ { _i = 0 }, { _i < count(paramsArray) }, { _i = _i + 1 } ] do

{

_paramName =(configName ((missionConfigFile >> "Params") select _i));

_paramValue = (paramsArray select _i);

missionNameSpace setVariable [_paramName, _paramValue];

};

};

call setvars ;

Share this post


Link to post
Share on other sites

My guess would then be that the original form, for JIP players (who might run that loop at the same time as other scripts, unlike non-JIP players), might get the _i value overridden by some other script. I guess all more of a reason to make sure to use private ["..."] commands. I never really understood all that "leaking" issue.

Remember that this code is called from a game logic, meaning it might have limitations that we wouldn't normally expect :(

---------- Post added at 05:09 PM ---------- Previous post was at 03:29 PM ----------

Hmm, seems that still any code that runs after the for loop will cause a "generic error in expression".

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×