Jump to content
zapat

So what makes a variable undefined & how to define it?

Recommended Posts

Is there any way to disable this thing? I will try and check my own scripts to fix them but I can't say I am up for going through all scripts I use made by other people fixing everything in those too.

Share this post


Link to post
Share on other sites
Is there any way to disable this thing? I will try and check my own scripts to fix them but I can't say I am up for going through all scripts I use made by other people fixing everything in those too.

Not without turning off script errors, which seem to be permanently enabled in the dev build. I have to stress, errors being thrown for undefined variables is an extremely good thing as much as it bothers you. If it was there in the first place, you wouldn't be getting them because the author of such scripts would've fixed it themselves and it would result in better code and the code would perform as expected at all times.

It's horrible when something goes unexpectedly wrong with something you scripted because you misspelled a variable by accident and then you spend a few hours trying to figure out why your script isn't working.

It's as if you made your GF mad and your girlfriend goes "no, honey, everything is fine!" but you see something is wrong, that's Arma before this change

Now Arma behaves as if when you make a mistake and you notice something is wrong and ask your GF what is it and she goes "Yeah, you kinda ignored me back there, can we fix that?" and then you know what to fix and fix it in 5 minutes and everything is ok.

It's a switch from passive-agressiveness to being aware what's wrong.

Share this post


Link to post
Share on other sites

@ Sniperwolf572 .. love you analogies :)

it was taken from UPSMON line 337 in INIT_UPSMON.sqf

				
			_sharedenemy = 0;	
			_targets0 = [];
			_targets1 = [];
			_targets2 = [];
{
				if (!isnull _x && alive _x && !captive _x ) then {	
					_npc = _x;								
					_targets = [];

					switch (side _npc) do {
						//West targets
						case west: {
							_sharedenemy = 0;
							_enemyside = [east];
						};
						//East targets
						case east: {
							_sharedenemy = 1;
							_enemyside = [west];
						};
						//Resistance targets
						case resistance: {								
							_sharedenemy = 2;
							_enemyside = KRON_UPS_Res_enemy;
						};
					};		

					if (side _npc in KRON_UPS_Res_enemy) then {
						_enemyside = _enemyside + [resistance];
					};

					//Gets known targets on each leader for comunicating enemy position
					//Has better performance with targetsquery
					//_targets = _npc nearTargets KRON_UPS_sharedist;		
					_targets = _npc targetsQuery ["","","","",""];

					{
						//_target = _x select 4;      //Neartargets
						_target = _x select 1;        //Targetsquery							
						if ( side _target in _enemyside ) then {																									
						// if (KRON_UPS_Debug>0) then {player globalchat format["%1: knows about %2, enemies=%3",_npc getVariable ("UPSMON_grpid"),_npc knowsabout _target, _npc countEnemy _targets ]};

							if (!isnull _target && alive _target && canmove _target && !captive _target && _npc knowsabout _target > R_knowsAboutEnemy
								&& ( _target iskindof "Land" || _target iskindof "Air" || _target iskindof "Ship" )
								&& !( _target iskindof "Animal")
								&& ( _target emptyPositions "Gunner" == 0 && _target emptyPositions "Driver" == 0 
									|| (!isnull (gunner _target) && canmove (gunner _target))
									|| (!isnull (driver _target) && canmove (driver _target))) 									
							) then {
								//Saves last known position	
								//_knownpos = _x select 0;	//Neartargets							
								_knownpos = _x select 4;//Targetsquery
								_target setvariable ["UPSMON_lastknownpos", _knownpos, false];									
								// _npc setVariable ["R_knowsAboutTarget", true, false];	  // !R								

								call (compile format ["_targets%1 = _targets%1 - [_target]",_sharedenemy]);
								call (compile format ["_targets%1 = _targets%1 + [_target]",_sharedenemy]);						
							};	
						};
					sleep 0.01;	
					} foreach _targets;							
				};					
				sleep 0.01;				
			}foreach KRON_NPCs;

Edited by 1PARA{God-Father}

Share this post


Link to post
Share on other sites

Thanks. :)

Anyway, it looks like the error is coming from the fact that the script relies on "KRON_NPCs" global variable which is not defined in this script and won't be until some other script else defines it. The author of the script has been lulled into the false sense of "it's working" due to the quirk of the engine, because the engine never said that it doesn't know what KRON_NPCs is. It was easy to overlook before, but now it would be obvious.

Easy way to "ductape" fix it is to add in your init.sqf

KRON_NPCs = [];

Which would define the variable that it's looking for. But this is just a "ductape" fix that might not work or could cause other side effects due to the fact that I don't know what it controls, when does it define itself and on what machines it should be defined or if different machines hold different states of that variable.

Edited by Sniperwolf572

Share this post


Link to post
Share on other sites

or is there a KRON_initialized global variable that you could do thisbright before your code:

waituntil {!isnil "KRON_initialized" && {KRON_initialized}};

assuming it is boolean and named this way... well much assuming!

Share this post


Link to post
Share on other sites

it is defined at the start of the script as such

KRON_NPCs = [];

Thanks. :)

Anyway, it looks like the error is coming from the fact that the script relies on "KRON_NPCs" global variable which is not defined in this script and won't be until some other script else defines it. The author of the script has been lulled into the false sense of "it's working" due to the quirk of the engine, because the engine never said that it doesn't know what KRON_NPCs is. It was easy to overlook before, but now it would be obvious.

Easy way to "ductape" fix it is to add in your init.sqf

KRON_NPCs = [];

Which would define the variable that it's looking for. But this is just a "ductape" fix that might not work or could cause other side effects due to the fact that I don't know what it controls, when does it define itself and on what machines it should be defined or if different machines hold different states of that variable.

Share this post


Link to post
Share on other sites

the "new" system is total bullshit, If you have something like

private ["a"]

delete a (in case theres alrdy an "a")

a = "Carmera" blah blah bla

than youll get an ERROR.

Bohemia i dont know what youre guys are smokeing but you shouldnt have changed it.

its nonsense that you have to declare a variable befor that stuff goes on, i mean everything is working fine except that your game is freaking out with "ERROR"

//Edit to be more precisely watch this

if (!isNil "_target") then

{

_spectating = ctrlText _spectateButton;

if (_spectating == "Spectate") then {

_spectateButton ctrlSetText "Spectating";

player commandChat format ["Viewing %1.", name _target];

camDestroy _camadm; < YOULL GET AN ERRRRRROOOOOOORRRRRR

_camadm = "camera" camCreate ([(position vehicle _target select 0) - 5,(position vehicle _target select 1), (position vehicle _target select 2) + 10]);

_camadm cameraEffect ["external", "TOP"];

_camadm camSetTarget (vehicle _target);

_camadm camCommit 1;

_rnum = 0;

while {ctrlText _spectateButton == "Spectating"} do {

switch (_rnum) do

{

if (daytime > 19 || daytime < 5) then {camUseNVG true;} else {camUseNVG false;};

case 0: {detach _camadm; _camadm attachTo [(vehicle _target), [0,-10,4]]; _camadm setVectorUp [0, 1, 5];};

case 1: {detach _camadm; _camadm attachTo [(vehicle _target), [0,10,4]]; _camadm setDir 180; _camadm setVectorUp [0, 1, -5];};

case 2: {detach _camadm; _camadm attachTo [(vehicle _target), [0,1,50]]; _camadm setVectorUp [0, 50, 1];};

case 3: {detach _camadm; _camadm attachTo [(vehicle _target), [-10,0,2]]; _camadm setDir 90; _camadm setVectorUp [0, 1, 5];};

case 4: {detach _camadm; _camadm attachTo [(vehicle _target), [10,0,2]]; _camadm setDir -90; _camadm setVectorUp [0, 1, -5];};

};

player commandchat "Viewing cam " + str(_rnum) + " on " + str(name vehicle _target);

_rnum = _rnum + 1;

if (_rnum > 4) then {_rnum = 0;};

sleep 5;

};

} else {

_spectateButton ctrlSetText "Spectate";

player commandchat format ["No Longer Viewing.", name _target];

player cameraEffect ["terminate","back"];

camDestroy _camadm; < CAUSES AN ERRRRRROOOOOOORRRRRR

};

};

its like going back to the stonge age

Edited by Mainfrezzer

Share this post


Link to post
Share on other sites

Once again, this is good, fix your code. Just because it didn't throw errors before due to the stupid quirk of the engine that tolerated undefined variables does not mean it was fine.

Let's take some pointers from, let's say ...

JS

MVwzSIz.png

Ruby

lSUOd9F.png

and Python

3cnTafC.png

Funny thing is, except for the error shown, your code with undefined variables in SQF will still run and the engine will try to make sense of it. Which in reality it shouldn't so we don't end up with such quirk laden scripts.

Share this post


Link to post
Share on other sites
Once again, this is good, fix your code. Just because it didn't throw errors before due to the stupid quirk of the engine that tolerated undefined variables does not mean it was fine.

Let's take some pointers from, let's say ...

JS

http://i.imgur.com/MVwzSIz.png

Ruby

http://i.imgur.com/lSUOd9F.png

and Python

http://i.imgur.com/3cnTafC.png

Funny thing is, except for the error shown, your code with undefined variables in SQF will still run and the engine will try to make sense of it. Which in reality it shouldn't so we don't end up with such quirk laden scripts.

Like he say these are features that are in most languages ever created. Its true that at first seem unreasonable to beginner programmers but once you are used to it it can become such a life saver. The fact this quirk has gone for so long without being fixed is the whole reason so many developers are crying out for a proper language to script in.

This change may even have an impact on performance of your mods as accessing an undefined variable will throw and exception and exceptions are expensive to throw and to handle. (by expensive I mean resource wise.)

Share this post


Link to post
Share on other sites

maybe i was a bit naive but... who doesn't declare his variables?! :D

It's the first thing i do, everytime.

Share this post


Link to post
Share on other sites

Hey there,I had some problems with this also.

I already know how to define local variables but in my mission I also use the publicVariableServer command.

One script is running on clients which sends out publicVariableServer CALL_AI_1_EAST.

My other script is running on the server which captures the variable.

This was working just fine before:

if (!isServer) exitWith {};

if (AI_On_Off == 1) exitWith {};

while {true} do {

waitUntil {CALL_AI_1_EAST};

if ((isServer) and (Aiskill == 1)) then {

Egrp1 = createGroup east;

_unit1 = Egrp1 createUnit ["O_diver_TL_F", position objFlag1, [], 200, "NONE"];

So I figure if I put CALL_AI_1_EAST = false it would be defined but also CALL_AI_1_EAST = [] would also be defined.

I tested with this:

if (!isServer) exitWith {};

if (AI_On_Off == 1) exitWith {};

CALL_AI_1_EAST = false;

while {true} do {

waitUntil {CALL_AI_1_EAST};

if ((isServer) and (Aiskill == 1)) then {

And this is working without errors,but is it the right way to do it?

I want to know before I rewrite all my scripts.

Best Regards Mkill73

Share this post


Link to post
Share on other sites
So I figure if I put CALL_AI_1_EAST = false it would be defined but also CALL_AI_1_EAST = [] would also be defined.

Huh? Is CALL_AI_1_EAST supposed to be a bool or an array? Just define it has one or the other as you did. Not sure what you're meaning by "would also be defined".

Share this post


Link to post
Share on other sites

Hey Kylania thx for the answer,and yes I meant a bool. Sorry for my bad expression. :)

Share this post


Link to post
Share on other sites

In that case you should be good how you had it, but I'd add that somewhere else where it'll be set at the beginning but not overwrite the value when that script it called. Something like this in your init.sqf:

if (isNil "CALL_AI_1_EAST") then {CALL_AI_1_EAST = false;};

Share this post


Link to post
Share on other sites
if (!isNil "_target") then

{

_spectating = ctrlText _spectateButton;

if (_spectating == "Spectate") then {

_spectateButton ctrlSetText "Spectating";

player commandChat format ["Viewing %1.", name _target];

camDestroy _camadm; < YOULL GET AN ERRRRRROOOOOOORRRRRR

_camadm = "camera" camCreate ([(position vehicle _target select 0) - 5,(position vehicle _target select 1), (position vehicle _target select 2) + 10]);

_camadm cameraEffect ["external", "TOP"];

_camadm camSetTarget (vehicle _target);

_camadm camCommit 1;

_rnum = 0;

while {ctrlText _spectateButton == "Spectating"} do {

switch (_rnum) do

{

if (daytime > 19 || daytime < 5) then {camUseNVG true;} else {camUseNVG false;};

case 0: {detach _camadm; _camadm attachTo [(vehicle _target), [0,-10,4]]; _camadm setVectorUp [0, 1, 5];};

case 1: {detach _camadm; _camadm attachTo [(vehicle _target), [0,10,4]]; _camadm setDir 180; _camadm setVectorUp [0, 1, -5];};

case 2: {detach _camadm; _camadm attachTo [(vehicle _target), [0,1,50]]; _camadm setVectorUp [0, 50, 1];};

case 3: {detach _camadm; _camadm attachTo [(vehicle _target), [-10,0,2]]; _camadm setDir 90; _camadm setVectorUp [0, 1, 5];};

case 4: {detach _camadm; _camadm attachTo [(vehicle _target), [10,0,2]]; _camadm setDir -90; _camadm setVectorUp [0, 1, -5];};

};

player commandchat "Viewing cam " + str(_rnum) + " on " + str(name vehicle _target);

_rnum = _rnum + 1;

if (_rnum > 4) then {_rnum = 0;};

sleep 5;

};

} else {

_spectateButton ctrlSetText "Spectate";

player commandchat format ["No Longer Viewing.", name _target];

player cameraEffect ["terminate","back"];

camDestroy _camadm; < CAUSES AN ERRRRRROOOOOOORRRRRR

};

};

Did anyone figure out how to fix this 1? EDIT*** Might need to see the comment above with the code example

Im not very good at coding as such but can follow instructions :)

I still get the error for camadm

Any assistance would be appreciated.

Thanks

Edited by jabbajaws77

Share this post


Link to post
Share on other sites

You're destroying _camadm before you define it at the top. Is that supposed to be destroying something previously created? Are you sure you're getting a second error for the line at the bottom or just listing it since it's the same command?

Share this post


Link to post
Share on other sites
You're destroying _camadm before you define it at the top. Is that supposed to be destroying something previously created? Are you sure you're getting a second error for the line at the bottom or just listing it since it's the same command?

It could be just the first 1

The error I get is as follows in a black box

Error undefined variable in expression: _camadm

Thanks

Full code is

    case 0: //Spectate
	{
		if (!isNil "_target") then
		{
			_spectating = ctrlText _spectateButton;
			if (_spectating == "Spectate") then {
				_spectateButton ctrlSetText "Spectating";
				player commandChat format ["Viewing %1.", name _target];

				camDestroy _camadm;
				_camadm = "camera" camCreate ([(position vehicle _target select 0) - 5,(position vehicle _target select 1), (position vehicle _target select 2) + 10]);
				_camadm cameraEffect ["external", "TOP"];
				_camadm camSetTarget (vehicle _target);
				_camadm camCommit 1;

				_rnum = 0;
				while {ctrlText _spectateButton == "Spectating"} do {
					switch (_rnum) do 
					{
						if (daytime > 19 || daytime < 5) then {camUseNVG true;} else {camUseNVG false;};
						case 0: {detach _camadm; _camadm attachTo [(vehicle _target), [0,-10,4]]; _camadm setVectorUp [0, 1, 5];}; 
						case 1: {detach _camadm; _camadm attachTo [(vehicle _target), [0,10,4]]; _camadm setDir 180; _camadm setVectorUp [0, 1, -5];};
						case 2: {detach _camadm; _camadm attachTo [(vehicle _target), [0,1,50]]; _camadm setVectorUp [0, 50, 1];};
						case 3: {detach _camadm; _camadm attachTo [(vehicle _target), [-10,0,2]]; _camadm setDir 90; _camadm setVectorUp [0, 1, 5];};
						case 4: {detach _camadm; _camadm attachTo [(vehicle _target), [10,0,2]]; _camadm setDir -90; _camadm setVectorUp [0, 1, -5];};                                                                        
					};
					player commandchat "Viewing cam " + str(_rnum) + " on " + str(name vehicle _target);
					_rnum = _rnum + 1;
					if (_rnum > 4) then {_rnum = 0;};
					sleep 5;
				};
			} else {
				_spectateButton ctrlSetText "Spectate";
				player commandchat format ["No Longer Viewing.", name _target];
				player cameraEffect ["terminate","back"];
				camDestroy _camadm;
			};
		};
	};

Edited by Deadfast: Wrapped the code in [ php ] tags for you.

Edited by Deadfast
Wrapped code in tags

Share this post


Link to post
Share on other sites

This error above is only 1 of the ones we havent been able to fix we have a couple of others also if anyone is willing to look at the errors and files associated that would be fantastic.

They all relate to the same thing, Error undefined variable in expression:

And adding a isnil to some of our others has worked just unsure the right format to be using for the ones we cant fix :)

Thanks

Share this post


Link to post
Share on other sites

isNil can be used to fix undefined variables in those simple cases of "oh well, if it's undefined just don't do nothing here". But in cases of more serious bugs (where you need the value of the variable but due to some bug elsewhere it doesn't have a value yet) you'd have to investigate harder to fix it.

Keep in mind those errors are shown to help you fix your bugs. That's the whole point of -showScriptErrors (which thankfully is now on by default, so people know they are playing a buggy mission and can report said bugs to the mission maker). If you are trying to access an undefined variable you are doing something wrong and should fix it. The engine can't guess whether or not you intended to make your script work regardless of whether the variable is defined or not, and therefore assumes you made a mistake and need to fix it to prevent possible bugs.

This is a huge improvement and we should appreciate it. Even though there are still situations where the engine simply chooses to do nothing rather than give an error, even though we really shouldn't be allowed to execute said command without getting some sort of an error message.

Share this post


Link to post
Share on other sites
isNil can be used to fix undefined variables in those simple cases of "oh well, if it's undefined just don't do nothing here". But in cases of more serious bugs (where you need the value of the variable but due to some bug elsewhere it doesn't have a value yet) you'd have to investigate harder to fix it.

Keep in mind those errors are shown to help you fix your bugs. That's the whole point of -showScriptErrors (which thankfully is now on by default, so people know they are playing a buggy mission and can report said bugs to the mission maker). If you are trying to access an undefined variable you are doing something wrong and should fix it. The engine can't guess whether or not you intended to make your script work regardless of whether the variable is defined or not, and therefore assumes you made a mistake and need to fix it to prevent possible bugs.

This is a huge improvement and we should appreciate it. Even though there are still situations where the engine simply chooses to do nothing rather than give an error, even though we really shouldn't be allowed to execute said command without getting some sort of an error message.

I agree its great to know where the issues are to fix them, my problem is not knowing how to :)

If you feel up to the task you could answer the above for me.

We also receive an error when looking at squad mates which says the same thing about undefined variables.

Jabbajaws77

Share this post


Link to post
Share on other sites

This change is awesome. An undefined variable in an if was impossible to debug since neither branch would run.

Share this post


Link to post
Share on other sites
This change is awesome. An undefined variable in an if was impossible to debug since neither branch would run.

Thanks for the above edit I was wondering how to do that.

Jabbajaws77

Share this post


Link to post
Share on other sites

Well, once you realize that no branch would run it's not impossible to debug, but indeed very difficult.

Basically, this change is really just patching up some holes in the error reporting mechanisms, since the engine was already reporting undefined variables in many other cases. So it's really more of a bug fix than an actual change.

Share this post


Link to post
Share on other sites
It could be just the first 1

The error I get is as follows in a black box

Error undefined variable in expression: _camadm

Thanks

Full code is

...

Check if the variable exists before trying to delete it.

    case 0: //Spectate
	{
		if (!isNil "_target") then
		{
			_spectating = ctrlText _spectateButton;
			if (_spectating == "Spectate") then {
				_spectateButton ctrlSetText "Spectating";
				player commandChat format ["Viewing %1.", name _target];

				if (!isNil "_camadm") then // <<<<< Added this
				{
					camDestroy _camadm;
				};
				_camadm = "camera" camCreate ([(position vehicle _target select 0) - 5,(position vehicle _target select 1), (position vehicle _target select 2) + 10]);
				_camadm cameraEffect ["external", "TOP"];
				_camadm camSetTarget (vehicle _target);
				_camadm camCommit 1;

				_rnum = 0;
				while {ctrlText _spectateButton == "Spectating"} do {
					switch (_rnum) do
					{
						if (daytime > 19 || daytime < 5) then {camUseNVG true;} else {camUseNVG false;};
						case 0: {detach _camadm; _camadm attachTo [(vehicle _target), [0,-10,4]]; _camadm setVectorUp [0, 1, 5];};
						case 1: {detach _camadm; _camadm attachTo [(vehicle _target), [0,10,4]]; _camadm setDir 180; _camadm setVectorUp [0, 1, -5];};
						case 2: {detach _camadm; _camadm attachTo [(vehicle _target), [0,1,50]]; _camadm setVectorUp [0, 50, 1];};
						case 3: {detach _camadm; _camadm attachTo [(vehicle _target), [-10,0,2]]; _camadm setDir 90; _camadm setVectorUp [0, 1, 5];};
						case 4: {detach _camadm; _camadm attachTo [(vehicle _target), [10,0,2]]; _camadm setDir -90; _camadm setVectorUp [0, 1, -5];};
					};
					player commandchat "Viewing cam " + str(_rnum) + " on " + str(name vehicle _target);
					_rnum = _rnum + 1;
					if (_rnum > 4) then {_rnum = 0;};
					sleep 5;
				};
			} else {
				_spectateButton ctrlSetText "Spectate";
				player commandchat format ["No Longer Viewing.", name _target];
				player cameraEffect ["terminate","back"];
				camDestroy _camadm;
			};
		};
	};

Share this post


Link to post
Share on other sites

Be careful though when trying to "patch" those errors with isNil checks. It is better to check why the variable really is undefined. Most of the time you will find a bug that you should fix, and using an isNil check will just remove the error message but keep the bug in your mission.

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

×