Jump to content


Photo
- - - - -

Guide To Dealing With Unknown Variable Errors


  • Please log in to reply
4 replies to this topic

#1 flexaplex

flexaplex

    GMC Member

  • Global Moderators
  • 4814 posts
  • Version:GM8

Posted 20 March 2009 - 08:15 PM

  • Title: Guide To Dealing With 'Unknown Variable' Errors
  • Description: Guide covering most of the reasons which might lead you to getting an 'Unknown Variable' error
  • GM Version: Causes for the error may vary depending on the GM version. As far as I am aware the reasons covered in this guide all apply for GM5/6/7
  • Registered: Registration should not affect the occurrence of the error.
  • Tags: unknown, variable, error, guide, solve, dealing, flexaplex, faq, game maker, gmc, yoyogames
If you know of any other scenarios you think I have missed which may cause an Unknown Variable error please reply explaining it (however in cases that are not clear cut to what causes the error please supply evidence of the error in a gmk file).


Guide To Dealing With 'Unknown Variable' Errors


There are quite a few reasons and scenarios in which you might get an unknown variable error. It is a regular error to occur and can also be fairly hard to find error sometimes so you should try to familiarise yourself with the reasons why it might happen. The first thing you should do is look at the error message, more specifically the location where the error message is pointing to (which object and event), this will help you identify where the problem lies. Then here a list of things you should do:

1. Check you have initialised the variable

The most common reason for this error is that you have not actually initialised the variable. What this means is that you have not set the variable to anything anywhere so when game maker tries to call upon it's value it doesn't know what it is. For example if you have put something like:

score = level*2;
Game maker does not just 'know' what the variable level is, you have to of at some point told game maker what it is. Most of the time you want to be initialising variables in the creation event, you do this by putting something like this in the creation event:

level = 0;
What you are doing here is you are giving the variable an initial value (a starting value).. this value can be anything you want, in this case I have set the level to 0 which is probably what you would want to start such a variable on. You can initialise variables in whatever event you like however as long as the event calling upon the variable occurs after the event where you initialise it. You should try to avoid initialising variables in events that occur often such as the draw or step event as this unnecessarily forces game maker to execute the line every step. A good coding practice to use is to also comment after every variable initialisation you make explaining what the variable is, eg:

level = 0;  //the level the player is on, affects the speed and scoring of the game
Doing this will allow you or anyone else that might wish to read your code to easily follow all the variables you have, if you don't like commenting much in your game at least try to do this as it can be very useful when you forget what certain variables do.

I would also like to note at this point that there is an option in game maker to treat all uninitialised variables as 0, someone on the forum may post telling you to do this at some point.. however I highly advise against doing so. There is no need to use this feature, other than laziness, and doing so inevitably leads to further complications in your game which can be hard to detect. The only use it can really have is possibly for debugging purposes.

2. Check the object is in the room

I have put this separately because it is a very frequent cause of the problem. Most commonly this confuses people when they get the error message "Unknown variable x" however this can be the issue when trying to call any local variable in another instance. To solve this problem you must simply make sure that an object is actually in the room when you try to call a variable from it. For example if you use the following code:

move_towards_point(obj_enemy.x,obj_enemy.y,5);
If there is no instance of obj_enemy in the room when you call the code it is going to give you an Unknown variable x error as GM will not have an enemy instance to refer to in order to get an x value. So what you need to do is first check the instance is in the room like so:

if (instance_exists(obj_enemy))
{
  move_towards_point(obj_enemy.x,obj_enemy.y,5);
}
Now it will move towards the enemy when there is actually an instance of it in the room.

I have also seen people say this a few times: "the object is definitely in the room, that can't be the problem" then it turns out later that in fact the object was not in the room when the code was executed. There are sometimes things that might confuse you into thinking it is in the room when s=actually isn't. If you are calling upon a variable in another object always MAKE SURE it is in the room. Say for example you are checking the hp of a player object using:

if (obj_player.hp == 0)
{
  show_message("Game Over");
}
And it is giving you an Unknown variable hp error, then you can use this line of code before your code to check that obj_player is actually in the room, like:

if !(instance_exists(obj_player)) {show_message("There is no player");}
if (obj_player.hp == 0)
{
  show_message("Game Over");
}
If there is in fact no player instance in the room then a message will pop-up telling you that there isn't, if not then it is in the room, this is a definite way of checking so you can be sure.

Having made sure there is an instance in the room and this is not the problem or if you cannot work out why there is not an instance in the room when you think there should be then read on through the guide as there are sometimes other things that can be causing you a problem.

3. Look at what event the error is pointing to

a) The 1st case I will explain are strange errors like the one pointing to the <no key> key release event. This error occurs when there is an error in the room creation of a room, the reason this error occurs is because game maker has nowhere to point the error to so it just points it to the next executed event, which is the no key release event of the 1st object. A similar thing happens when you have an error in the instance creation code of an object you set in a room, which gives you an error in the Key Release Event for <Enter> Key. Errors can also sometimes occur if you are using third party libraries, this error message could point to somewhere completely different.. if you are using a third party library at all and you get a strange unknown variable message it's a good idea to check whether this is the problem or not. You can check this by removing calls to the library and seeing if the error goes away.

b) The 2nd case I will explain is an error in the draw event. This error can sometimes occur for 2 reasons, one is that you have initialised the variable in an event other than the creation event, like the step event for example.. then you have tried to call the variable from the draw event. You may have looked at the event execution order and seen that the draw event is executed after the step event.. however at the start of a room the draw event is actually executed once straight after the creation event and thus before the step events so when this happens the variable will have not been initialised.

The other reason why you may be getting this error in the draw event is because the draw event of that object is being forced to execute before it's creation event. There are a few functions that when called upon force the draw event of all objects to be called, like screen_redraw() or reactivating a deactivated object, look for places where this might of occurred in the creation events of other objects.. you may need use the next method I am about to explain to solve this problem.

c) The 3rd case is an error occurring in the creation event. This is often caused by you trying to call upon a local or global variable set in another object's creation event. The reason this can be a problem is if game maker is executing the object's creation events in an unwanted wrong order as this can make a variable unknown at the time of calling it. For example if you have:

in obj_player creation event:

hunger = obj_shop.pies/2;
and in the creation event of obj_shop you have:

pies = 24;
The obj_player is only going to know what the variable obj_shop.pies is if the obj_shop's creation event has been executed before it.

A good solution to this is to execute the creation event's of all the objects yourself manually, therefore allowing you to execute them in your desired order. This can be done by placing the creation event of every object into a script and deleting the creation event of every object altogether. Then in a controller object's creation event you simply execute the scripts like so:

with (obj_shop) {obj_shop_creation_ev();}
with (obj_player) {obj_player_creation_ev();}
//etc for every object
Doing this then gives you complete control over all the creation events.

4. Check for resources clashes

Resource clashes can also confuse you and lead to unknown variable errors. A resource clash occurs when you give 2 things the same name like a sprite and a variable, or a script and an object etc. You can check some resource clashes by clicking the scripts tab at the top and then clicking 'check resource names'. You cannot however check for resource clashes with variables, you have to lookout yourself for these and make sure you haven't git any.. a problem can also be that you can name a resource with the same name as a built-in variable or function. A good way to avoid resource clashes is to name your resource using prefixes eg obj_player, spr_person, scr_showhelp, snd_boom then resource clashes are unlikely to happen.

I will give you an example of when resource clashes can give you errors. For example if you have a sprite called money.. then in the creation event of an object you put:

money = 10;
It is going to throw an error at you because you are trying to change the value of a sprite (well actually you are trying to change the value of a number, see this topic if you don't understand why). This error message given however will be different completely different.. it should say something like 'ERROR variable name expected'.

However there are circumstances where a resource clash can confuse you and give you a normal unknown variable error. For example if you have a object called starting and you have a script called starting also. Then in some code you put:

starting();
Now when you do this GM will not be calling upon the script index 'starting' it will be calling upon the object index 'starting' this will be a completely different value and thus will cause GM to call upon an entirely different script altogether. If you do this you could quite easily have variables used in the other script which you have not initialised yet.

There are other scenarios where resource clashes can cause confusion also. You should also note yourself that resource clashes can lead to all sorts of different errors, so in future if you get an error and cannot work out why, quickly consider to yourself whether or not you could have a resource clash. If you name resources properly using prefixes though, you should eliminate nearly all of them.

5. Check for other mistakes

There are some miscellaneous mistakes that you may still be making, these might be confusing you into thinking your code is correct when it isn't.

a) If you are using the room start event to initialise a variable the object must actually be in the room at the start of the room, the same goes for the game start event if you are using this make sure the object is in the first room of your game when it starts. If this is not the case then you should probably change the event to the creation event or if this is not possible set the variable as a global variable from an object that is actually in the room at the start.

b) Perhaps the variable you are calling might actually be global when you think it is local. Look through your code to check this isn't the case.

c) If you are using instance_change check to make sure you have set the 2nd argument perf as true if it is needed. If it is not set as true then the creation event of the object you are changing into wont get executed which means any variable assignments you have put in it wont happen. Also the destroy event of the object you are changing from wont happen but this probably wont be an issue unless you are setting a global variable there for some reason.

d) As well as resource clashes making you call from the wrong object you may also be doing it yourself by mistake, a common way is when you are calling for the variable from inside a with statement forgetting that when you use code in with statement it is executing in that object, not the original object. Another mistake might be if you calling the variable from an instance using an id stored in a variable.. you may have calculated the id for the variable incorrectly or the id may be set to noone. It is a good idea to check the id of the instance to make sure it is correct, for example if you have used the code to get the nearest enemy's name:

near_enemy = instance_nearest(x,y,obj_enemy);
clos_nam = near_enemy.name;
And it pops up the message "unknown variable name" then you could use this line to check what the near_enemy variable has been set to:

near_enemy = instance_nearest(x,y,obj_enemy);
show_message(string(near_enemy)+"  "+object_get_name(near_enemy));
enemy_name = near_enemy.name;
If the message pops up -4 <undefined> then it means that it has been set to noone this would mean that there is in fact no enemies in the room to be found. In this case you might want to change your code to:

near_enemy = instance_nearest(x,y,obj_enemy);
if (near_enemy != noone)
{
  enemy_name = near_enemy.name;
}
This will then first check that there is an enemy found before trying to get the name. As well as a -4 <undefined> you may also see the message show a different object name to what you thought it should be.. if this is the case make sure again that you have not got a resource clash and make sure you have not set the id variable somewhere that you shouldn't of.

Another rarer case where id's might be causing a problem is say for example you have an object in a room called obj_bomb, in this object you have set no variables, then in an event you create another bomb like so:

bmb = instance_create(x,y,obj_bomb);
bmb.damage = 5;

Now you may think that obj_bomb has the variable damage set to 5.. so you use the code:

health -= obj_bomb.damage;
This is going to throw an error. Because in fact obj_bomb does not have the variable damage, only 1 instance that you created has that variable set. And if you call the index of an object like you have done using obj_bomb it will call only the instance with the lowest id which will be the origin bomb in the room, which doesn't have the variable set. In this case what you will probably be wanting to do is call bmb.damage not obj_bomb.damage.

e) You can also get unknown variable errors when declaring variables with var. For example if in the creation event of an object obj_player you put:

dist = 7.2;
Then in an event in the same object obj_player you were to put:

var dist;
x += dist;
This is going to throw an error as when you var dist the variable is localised to the script, therefore when you call x += dist it is not checking the one you initialised in the creation event but instead checking for the dist variable local in the script, which has not been declared.

This is probably too easy to spot for you to make this mistake, however it could possibly be missed when you call it from within side a with statement in another object. For example if in a different object you were to put:

var dist;
with (obj_player)
{
  dist += 1;
}
This would throw an error for the same reason as before.. as even when you use a with statement the variable is still localised within the script (using other.dist will now also give you an error for the same reasons). You can however still use:

var dist;
obj_player.dist += 1;
As this now calls dist variable from obj_player directly.


If you have gone through all those cases thoroughly and you still cannot find why you are getting an unknown variable error, then I advise posting on the novice q&a at the gmc for help and being very descriptive about what you have tried.

- guide written by flexaplex -

Edited by flexaplex, 27 July 2009 - 01:27 AM.

  • 1

#2 Aidiakapi

Aidiakapi

    GMC Member

  • New Member
  • 200 posts

Posted 20 March 2009 - 09:21 PM

Rather useful, too bad it's not useful anymore for me.
  • 0

#3 RetroDANIEL

RetroDANIEL

    GMC Member

  • GMC Member
  • 67 posts

Posted 17 November 2010 - 06:00 PM

Ive gott a diferent problem with the score
in the game the score is money and cannon_true its when you have enough money to buy it. cannon_false its when you dont have enough money these are objects.
OBJECT Cannon_true
now when the var score is smaller than 50 <then change instance object cannon_true to cannon_false>
OBJECT Cannon_false
when var score is larger than 49 <then change instance object cannon_false to cannon_true>

this works for 3 other objects but in this one it dosent seem to work help im planning to put this game in yoyo games next week :lol: i got all the story mode done and the game play too but the main object failed HELP!!!
  • 0

#4 Chronic

Chronic

    Administrator

  • Global Moderators
  • 2729 posts
  • Version:GM:Studio

Posted 17 November 2010 - 09:15 PM

The problem with running the create event manually is that you will end up having it run twice for every instance you do it with. Once when that script fires off, and then again when each instance is created. Because of these reasons, it does not give complete control over the creation events.

Apart from that, there is some helpful information here. However in my opinion some of it is out of the scope of the tutorials topic.
  • 0

#5 RetroDANIEL

RetroDANIEL

    GMC Member

  • GMC Member
  • 67 posts

Posted 19 November 2010 - 09:05 AM

well i fixed the problem by moving the object to a garbage folder and duplicaded it. but the problem is spreading to other objects this is getting every moment worst. :skull:
could this be cause of an excess of Data? , because i had a problem before cause of the sprite sizes. :wacko: or for the same Reason.

Edited by RetroDANIEL, 19 November 2010 - 09:14 AM.

  • 0




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users