Set up a variable and then increase its value for each instance...

T

Toxidalf

Guest
Hello, is there a way to do that?

For example, I have 300 instances of one object, and I want each instance to have a value (starting from 1) that increases for each single one.

Is that possible?
 
Last edited by a moderator:
A

Allar

Guest
Yes this is my solution to this problem

Put this code in the Draw Event(might working the Create Event as well if not displaying the number) of the object your wanting to assign an Indexed ID to
Code:
number_objects = instance_number(obj_name);
 var myID;
 for (myID = 0; myID <number_objects; myID++){
     IDCheck = instance_find(obj_name, myID);
     if(id == IDCheck){
         break;
     }
 }

//prints myID number on my object
draw_set_colour(c_black);
 draw_text(self.x+33,self.y+30,string(myID));
obj_name : is the object you want to have indexed
number_objects : gets the total number of obj_name instances in the room.
IDCheck : checks to see what number this object is
myID : this is my index number

any questions?
 
Last edited by a moderator:
D

dannyjenn

Guest
Maybe try something like:
Code:
count = 1;
with(obj_whatever){
    value = other.count;
    other.count+=1;
}
 
T

Toxidalf

Guest
Yes this is my solution to this problem

Put this code in the Draw Event(might working the Create Event as well if not displaying the number) of the object your wanting to assign an Indexed ID to
Code:
//obj_name is the object you want to have indexed
//number_objects gets the total number of obj_name instances in the room.
number_objects = instance_number(obj_name);
//myID this is my index number
 var myID;
 for (myID = 0; myID <number_objects; myID++){
//IDCheck checks to see what number this object is
     IDCheck = instance_find(obj_name, myID);
     if(id == IDCheck){
         break;
     }
 }

//prints myID number on my object
draw_set_colour(c_black);
 draw_text(self.x+33,self.y+30,string(myID));
any questions?

Thanks, I'll test this out!
 
T

Toxidalf

Guest
Yes this is my solution to this problem

Put this code in the Draw Event(might working the Create Event as well if not displaying the number) of the object your wanting to assign an Indexed ID to
Code:
//obj_name is the object you want to have indexed
//number_objects gets the total number of obj_name instances in the room.
number_objects = instance_number(obj_name);
//myID this is my index number
 var myID;
 for (myID = 0; myID <number_objects; myID++){
//IDCheck checks to see what number this object is
     IDCheck = instance_find(obj_name, myID);
     if(id == IDCheck){
         break;
     }
 }

//prints myID number on my object
draw_set_colour(c_black);
 draw_text(self.x+33,self.y+30,string(myID));
any questions?
I tried but all of the instances are equal to "1".

A few things:

- I'm using GM 8.1 (don't know if it is bothersome but worth saying it)
- I'm using the instance calling the code as a parent, therefore there are childs around that use this code, could it be problematic? :D


Thanks for the help!
 
A

Allar

Guest
I'm using the instance calling the code as a parent, therefore there are childs around that use this code, could it be problematic?
yes it could be try calling it directly in the object your wanting to count
because acting as a parent will only check the ID of that parent thus its 1
 
T

Toxidalf

Guest
yes it could be try calling it directly in the object your wanting to count
because acting as a parent will only check the ID of that parent thus its 1
I did that and now things seem to be better!

Now I'll run some tests to see if that fully works out, thanks in advance and again :D
 
T

Toxidalf

Guest
yes it could be try calling it directly in the object your wanting to count
because acting as a parent will only check the ID of that parent thus its 1
Is there a way to transfer "MyID" to a variable of another object?!

I need the value of "MyID" to be read in another var called "Idd" of another object :D
 
A

Allar

Guest
Is there a way to transfer "MyID" to a variable of another object?!

I need the value of "MyID" to be read in another var called "Idd" of another object :D
try using obj_name.MyID to reference it
 
A

Allar

Guest
try using obj_name.MyID to reference it
If its a collision type referencing you can try

Events Collision with object_name:
Code:
Idd = other.MyID
not sure if that would work 100% other might have to be refered to as something else
 
T

Toxidalf

Guest
try using obj_name.MyID to reference it
Dude I just found that the whole thing cannot simply work in the end :(

I'm using an array to keep track of the instances id (minus a value so the array won't overcome the 32000 threshold), so when I get back to the room only the deleted instances keep destroyed.

This method doesn't work because all the instance have the same MyIDD value, only when you take (coins) them they get decreased by 1.

But I think you paved me the way for something, thanks anyway!!
 
A

Allar

Guest
Dude I just found that the whole thing cannot simply work in the end :(

I'm using an array to keep track of the instances id (minus a value so the array won't overcome the 32000 threshold), so when I get back to the room only the deleted instances keep destroyed.

This method doesn't work because all the instance have the same MyIDD value, only when you take (coins) them they get decreased by 1.

But I think you paved me the way for something, thanks anyway!!
ah okay no problem. BTW you should look into the instance_id variable in the help it might be what your looking for.
 
T

Toxidalf

Guest
ah okay no problem. BTW you should look into the instance_id variable in the help it might be what your looking for.
Yeah I was using that, but I decided to change this method since it gives me some problems (for example, deleting and placing new instances does increase the instance_id read only variable, so it gets difficult for me to manage it all :D
 
T

Toxidalf

Guest
ah okay no problem. BTW you should look into the instance_id variable in the help it might be what your looking for.
Ok I tried a lot of things and none of them worked AHHAHA

So, I don't know what to do...

Is there a way, for example, to tell GM to increase the value of idd by 1 if one instance has already that value?

Like, seriously? There's no answer to this problem D:

Maybe arrays/for loop is the only way.
 
T

Toxidalf

Guest
...Should be able to delete, had to put a search.
Unknown variable "amount"

Plus, for Room Creation event you mean the Room Start event?
I've never heard of that before lol, maybe Room Creation Code? I tried that as well but it gives me the same err :(
 

Dupletor

Member
There shouldn't be an error of unknown variable in GML for globals. If a variable is not known, it is created automatically.
Anyway, the code I provided does not work, as a destroyed object would never again exist anyway. So if you destroy the object of tag 3, a new generated would not replace the tag 3.

If you want to set the tag as the minimum available value, you have to search through every instance for an available value, which is costful.
If you just want to know how many instances there are, just increment on creation and decrement in the destruction of the object.
 
T

Toxidalf

Guest
There shouldn't be an error of unknown variable in GML for globals. If a variable is not known, it is created automatically.
Anyway, the code I provided does not work, as a destroyed object would never again exist anyway. So if you destroy the object of tag 3, a new generated would not replace the tag 3.
I could fix all of this situation by adding manually, in the object creation code in the room editor, the tag "idd = 1" , "idd = 2", "idd = 3"....

but I have more than 500 instances and that's a pain in the ass, it can be done by code, I'm convinced of that!
 

Dupletor

Member
Will they be destroyed?
If not, just do as I said:
global.amount = 0, in room creation code.

In object creation code:
global.amount++;
tag = global.amount;

If objects are destroyed, it is more complicated. You have to reduce the value of amount in the Destroy event and search for a spare value when creating.
 
T

Toxidalf

Guest
Will they be destroyed?
If not, just do as I said:
global.amount = 0, in room creation code.

In object creation code:
global.amount++;
tag = global.amount;
Yeah, they are coins to be collected so they will be destroyed :(
 

Dupletor

Member
If they can't be recreated until all of them are lost, it is fine. The problem is about replacing, you can't replace a coin that still exists. So, you have to know it exists before you replace it. That demands searching for all of them.
 
T

Toxidalf

Guest
Also, how the hell can you not lag with 500 instances in the same room?
They're not in the same room ahah, they are spread around the "world" (made up of 50 room so far)

I'm doing this because I have a revisiting room system but I need a way to increase the value of "idd" per every instance for it to work!
 

Dupletor

Member
Well, just increase the amount of them as they keep existing, and ignore the fact that a coin with tag 3 does not exist if you collect the coin of tag 3. :p

The code I said works for this case, but you will eventually have a coin of tag 2 billion, if you collect and recreate them a lot.
 
T

Toxidalf

Guest
Also, you don't need to tag coins. At all. It's not like they have identity and personality.
This sketch will help you clear out what I'm trying to archieve (but It should be clear I think, I don't know ahjha)
 

Attachments

T

Toxidalf

Guest
Well, just increase the amount of them as they keep existing, and ignore the fact that a coin with tag 3 does not exist if you collect the coin of tag 3. :p

The code I said works for this case, but you will eventually have a coin of tag 2 billion, if you collect and recreate them a lot.
The fact is that my variable is laid to an array, so its value can't overpass 32000 :-
 

TheouAegis

Member
, just make a global variable at the very start of the game, keep adding one to it every time you create an instance that needs to have that variable save as idd. check if the variable exceeds however large your array is going to be and set it back to zero if it gets too large. Of course this means assuming you actually make it to 3200 instances what any of the lower instances are still around, you would have a conflict. so you would have to additionally also verify with a loop such as a normal with loop that no instances have the new value as their idd, otherwise add one and loop through them all again. or you could reset the counter to whatever idd of an instance gets destroyed so that you can reuse that idd again sooner.
 
T

Toxidalf

Guest
, just make a global variable at the very start of the game, keep adding one to it every time you create an instance that needs to have that variable save as idd. check if the variable exceeds however large your array is going to be and set it back to zero if it gets too large. Of course this means assuming you actually make it to 3200 instances what any of the lower instances are still around, you would have a conflict. so you would have to additionally also verify with a loop such as a normal with loop that no instances have the new value as their idd, otherwise add one and loop through them all again. or you could reset the counter to whatever idd of an instance gets destroyed so that you can reuse that idd again sooner.
But why do I need to use created instances to keep track of this?

I don't think what you posted is the solution to my problem, sorry D:

Maybe it's me who hasn't got it all yet ahah
 

TheouAegis

Member
Well you talked about destroying some and creating some.

As for the initial setup in a room with precreated instances, run a position loop at the start of the room checking if there is an instance at each position and setting idd in order that way.

Or if idd is going to be based on position in the room and you can safely ensure no two instances will spawn less than 8 pixels or so away from where another instance spawns, you can base the idd value strictly on that.

idd = x div 8 | y div 8 * 16000

The 16000 was just a random value i picked.
 
T

Toxidalf

Guest
Well you talked about destroying some and creating some.

As for the initial setup in a room with precreated instances, run a position loop at the start of the room checking if there is an instance at each position and setting idd in order that way.

Or if idd is going to be based on position in the room and you can safely ensure no two instances will spawn less than 8 pixels or so away from where another instance spawns, you can base the idd value strictly on that.

idd = x div 8 | y div 8 * 16000

The 16000 was just a random value i picked.
Thanks for the reply!

I wan't talking about destroying and recreating instances as a thing I need to do, I was explaining why I couldn't use instance's id any longer :D

I can't have instance separated by the way, each instance is snapped into a 64x64 perfect grid and cannot in any way be split or shifted!

But yeah, using position seems a good idea!!

How can I "sort" the variable "idd" (that's in an array so cannot be negative) using the position of the instance? (I cannot always use "idd = self.x", because then there could be some instances with the same value you know!)

(Edit: sorry if this wasn't clear, It's not easy to explain it all ahah)
 
T

Toxidalf

Guest
Well you talked about destroying some and creating some.

As for the initial setup in a room with precreated instances, run a position loop at the start of the room checking if there is an instance at each position and setting idd in order that way.

Or if idd is going to be based on position in the room and you can safely ensure no two instances will spawn less than 8 pixels or so away from where another instance spawns, you can base the idd value strictly on that.

idd = x div 8 | y div 8 * 16000

The 16000 was just a random value i picked.
Well you talked about destroying some and creating some.

As for the initial setup in a room with precreated instances, run a position loop at the start of the room checking if there is an instance at each position and setting idd in order that way.

Or if idd is going to be based on position in the room and you can safely ensure no two instances will spawn less than 8 pixels or so away from where another instance spawns, you can base the idd value strictly on that.

idd = x div 8 | y div 8 * 16000

The 16000 was just a random value i picked.
Never mind It can't be... same values from different room is the problem :(
 

TheouAegis

Member
It doesn't matter if instances can move or not. What matters first and foremost is that they aren't created (either by you manually in the room editor or via instance_create) at the same location as another instance.

CREATE EVENT:
idd = (x div 64) | (y div 64) * 16000;

Boom! Unless you're stacking instances in the room editor, this should be enough at the beginning of the program.

If an instance later moves over and another one is created in its place, then you'd have a conflict of idd values when the new one is created. In that case, you'd need to modify the Create Event to find the nearest open value.

Code:
idd = (x div 64) | (y div 64) * 16000;
while 1 {
with all if idd == other.idd
    other.idd == (x div 64) | (y div 64) * 16000;
else break;
}
 
T

Toxidalf

Guest
How big is each room?
How many rooms?
You can make the room a factor in the position too.
So far I have 50 rooms (1920 x 1080 / 64x64), each (minus 1) revisitable, but not persistent...

Anyway, I did a compromise before you just posted!
The compromise is that I will have to wait the very end of the game to change that unstable "138500" :(



idd = self.id - 138500

if idd > 32000 {
idd = idd - 10000
}
if idd < 0 {
idd = idd + 10000
}

But I want to try your code now! Thanks :D
 

TheouAegis

Member
1920 x 1080

So 30 x 16, or 480 "cells" per room.

32000/480 = 66 rooms allowable.

Some mantain the same value!
You're talking about the "full" code, right? I just looked over that again and spotted my logic error. But it shouldn't have occurred until after instances had been moved...

Code:
//This first line ideally is all you should need

idd = room + 66 * ( (y >> 6) + ((x >> 6) * 16) );


//The following code should only be necessary when spawning instances with instance_create()

with object_index                //replace object_index with the object class that has idd in it
{
    if id == other.id continue;
    if idd == other.idd
        other.idd = -1;
}
if idd == -1
{
    idd = room;
    var brk = 1;
    while brk
    {
        brk = 0;
        with object_index                //replace object_index with the object class that has idd in it
        {
            if id == other.id continue;
            if idd == other.idd
            {
                other.idd += 66;
                brk = 1;
                break;
            }
        }
    }
}
Yeah, it's a bit uglier. But here are the changes I made:
  1. Added the room id into the evaluation of idd. Keep in mind that this method requires rearranging the resource tree so that your game rooms are at the top of the resource list. The order of the rooms matters, so if you're using this for save features or anything and there will be updates in the future, you have to make sure the room order doesn't change between versions, otherwise the save files might not be bugged. This also limits your rooms to 66 total for the game rooms (any other rooms such as for menus don't count toward this limit).
  2. When an idd is assigned, it checks all other instances to verify it hasn't picked one that already exists. This really should not be an issue at all if you don't create instances on the fly with instance_create. Anything placed in the room should just need the initial idd algorithm.
  3. If two idd values conflict, then it starts from 00 (well, room+0*66), checks if someone else has the same idd, then goes up until it finds an idd that no one else has.
 
T

Toxidalf

Guest
1920 x 1080

So 30 x 16, or 480 "cells" per room.

32000/480 = 66 rooms allowable.


You're talking about the "full" code, right? I just looked over that again and spotted my logic error. But it shouldn't have occurred until after instances had been moved...

Code:
//This first line ideally is all you should need

idd = room + 66 * ( (y >> 6) + ((x >> 6) * 16) );


//The following code should only be necessary when spawning instances with instance_create()

with object_index                //replace object_index with the object class that has idd in it
{
    if id == other.id continue;
    if idd == other.idd
        other.idd = -1;
}
if idd == -1
{
    idd = room;
    var brk = 1;
    while brk
    {
        brk = 0;
        with object_index                //replace object_index with the object class that has idd in it
        {
            if id == other.id continue;
            if idd == other.idd
            {
                other.idd += 66;
                brk = 1;
                break;
            }
        }
    }
}
Yeah, it's a bit uglier. But here are the changes I made:
  1. Added the room id into the evaluation of idd. Keep in mind that this method requires rearranging the resource tree so that your game rooms are at the top of the resource list. The order of the rooms matters, so if you're using this for save features or anything and there will be updates in the future, you have to make sure the room order doesn't change between versions, otherwise the save files might not be bugged. This also limits your rooms to 66 total for the game rooms (any other rooms such as for menus don't count toward this limit).
  2. When an idd is assigned, it checks all other instances to verify it hasn't picked one that already exists. This really should not be an issue at all if you don't create instances on the fly with instance_create. Anything placed in the room should just need the initial idd algorithm.
  3. If two idd values conflict, then it starts from 00 (well, room+0*66), checks if someone else has the same idd, then goes up until it finds an idd that no one else has.

Thanks for the effort!

I will soon check this out, but a question: does that mean I can't use more than 66 rooms?! That would be sore somehow XD
 

TheouAegis

Member
Use more than one array, then. One array for every 66 or fewer rooms. In that scenario, whereas in my code it was strictly "room + 66*n", the room would need to be replaced by another variable that itself is based on the room.

var r = room div 66;
idd = room + 66 * ( (y>>6) + ( (x>>6)*16) );
 
T

Toxidalf

Guest
T
Use more than one array, then. One array for every 66 or fewer rooms. In that scenario, whereas in my code it was strictly "room + 66*n", the room would need to be replaced by another variable that itself is based on the room.

var r = room div 66;
idd = room + 66 * ( (y>>6) + ( (x>>6)*16) );
Sorry for the delay, the code works great!

I'll let you know if there are some inconveniences, thanks again!!

I often see you here in this forum, ya're kind of legend aren't you? XD
 
T

Toxidalf

Guest
Use more than one array, then. One array for every 66 or fewer rooms. In that scenario, whereas in my code it was strictly "room + 66*n", the room would need to be replaced by another variable that itself is based on the room.

var r = room div 66;
idd = room + 66 * ( (y>>6) + ( (x>>6)*16) );

I noticed that I could get away without other arrays, maybe there will be some objects with the same idd, but that's not so important... You are always confined into 20/25 rooms which make a single "world" and cannot go back once you reach the new world, I think it can work out pretty well.
 
Top