Legacy GM Objects spawning outside of desired area

B

Bogan666

Guest
I have currently got set a map which randomly spawns objects to form the world, using this code to spawn the objects

var i;
for (i = 0; i < 4; i += 1)
{
x = irandom(room_width) div 32 * 32
y = irandom(room_width) div 32 * 32
instance_create(x,y,obj_dirt);
}

So with this it will pick a random place within the room width/height and divide by 32 to keep in the 32x32 grid that I want the game to be played in.
In theory this is great and it works, I've also got a bit of code
"move_wrap(true,true,32);" so if anything gets put out of the map it'll just wrap around to the otherside.

This is where the issues come in, when looking at the world everything looks fine, but I just added a bit of code to spawn a npc at a random object on the map. So say 2/5ths of world are made up for dirt, it picks a random instance of dirt and spawns the player there. But the player can spawn "outside" the map on one of these rouge objects. seemingly up to the size of one 32x32 chunk.

my question is why would the map objects not wrap back once it sees that its outside of the map, is move_wrap not enough for it to see that its out of the map?
in the picture you can see the co ords for the npc, but my room size is 1920x1056.
can explain the world generation if needed.
 

Attachments

woods

Member
move wrap....an instance that has left the room

in your case, the npc hasnt left the room.... it starts outside the room

edit... scratch that.. didnt see that last bit with the npc being inside the coords of the room ;o0
 
B

Bogan666

Guest
move wrap....an instance that has left the room

in your case, the npc hasnt left the room.... it starts outside the room
True, but with the case of the obj_dirt which when created is made in a start position and basically expands in random directions until its filled the set amount of tiles I want it to make. during that process would that not wrap as I have intended. I can understand the npc spawning in a location off screen, but theoretically its potential spawn locations should all be inside the map.
 

woods

Member
and basically expands in random directions until its filled the set amount of tiles I want it to make



are there tiles being created outside of the room? i mean if it is creating tiles in random directions and starts at o,0 it could spit those out off the board.. giving the npc a place to land at creation outside the grid... i know you said that the npc is inside the game room boundaries already tho.. just a thought ;o)

i donno.. wild guess ;o)
===

what happens if you change the 32 to sprite_width

"move_wrap(true,true,32);"

possibly the sprite isnt 32px off the map..
 
B

Bogan666

Guest
and basically expands in random directions until its filled the set amount of tiles I want it to make



are there tiles being created outside of the room? i mean if it is creating tiles in random directions and starts at o,0 it could spit those out off the board.. giving the npc a place to land at creation outside the grid... i know you said that the npc is inside the game room boundaries already tho.. just a thought ;o)

i donno.. wild guess ;o)
===

what happens if you change the 32 to sprite_width

"move_wrap(true,true,32);"

possibly the sprite isnt 32px off the map..
Gave it a go, same effect though. I've attached an image below of what it looks like with a fully spawned world. I'm using a view to display 1920x1080 but the actual room size is 1792x928 to you can see the full extent of what is happening.
the dark square in the bottom right is the corner of the 1792x928 room. As you can see objects are able to spawn/spread past that desired point. After two of the 32x32 chunks they then wrap around. its the same in both directions.
I don't really understand why this could happen with the spawn code being
x = irandom(room_width) div 32 * 32
y = irandom(room_width) div 32 * 32
instance_create(x,y,obj_dirt);

along with any objects being made SHOULD wrap once they are 32pixels out ofthe screen. If you know what might be the cause of this would be a great help. I can't quite wrap my head around why this would happen.
 

Attachments

woods

Member
where is "move_wrap(true,true,32);" located?

paste your actual code...

Code:
is easier for those with more knowledge to lend a hand ;o)
 

woods

Member
what happens when you changed it up with that extra ")"
and is it supposed to be width on both the x and y?
;o)
1920x1056 vs 1920x1920

Code:
x = irandom(room_width) div 32) * 32;
y = irandom(room_height) div 32) * 32;
 
B

Bogan666

Guest
where is "move_wrap(true,true,32);" located?

paste your actual code...

Code:
is easier for those with more knowledge to lend a hand ;o)
move_wrap is currently located in being step

This is obj_dirt's being step code:
Code:
if dir > 4 { dir = 1};

if obj_generation.amount > 0 && create > 0
    {

        if dir = 1 {
        if position_empty(self.x,self.y-32){
            instance_create(self.x,self.y-32,obj_dirt)
            obj_generation.amount -=1;
            self.create -= 1;}
            else self.dir +=1}
     
        else if dir = 2 {
        if position_empty(self.x+32,self.y){
            instance_create(self.x+32,self.y,obj_dirt)
            obj_generation.amount -=1;
            self.create -= 1;}
            else self.dir +=1}
     
        else if dir = 3 {
        if position_empty(self.x,self.y+32){
            instance_create(self.x,self.y+32,obj_dirt)
            obj_generation.amount -=1;
            self.create -= 1;}
            else self.dir +=1}
     
        else if dir = 4 {
        if position_empty(self.x-32,self.y){
            instance_create(self.x-32,self.y,obj_dirt)
            obj_generation.amount -=1;
            self.create -= 1;}
            else self.dir +=1}
 
 
    }
 
move_wrap(true,true,sprite_width);
move_wrap(true,true,sprite_height);
this is the code to pick a random location on the map to spawn an obj_dirt, refer back to the other code blocks obj_generation, this is that object.

Code:
amount = irandom_range(700,900);
gen1 = 1;
randomize();
var ins;


var i;
for (i = 0; i < 4; i += 1)
{
x = irandom(room_width) div 32 * 32
y = irandom(room_width) div 32 * 32
instance_create(x,y,obj_dirt);
}
]
 
Last edited by a moderator:
B

Bogan666

Guest
what happens when you changed it up with that extra ")"
and is it supposed to be width on both the x and y?
;o)
1920x1056 vs 1920x1920

Code:
x = irandom(room_width) div 32) * 32;
y = irandom(room_height) div 32) * 32;
it was meant to be height and width! WOOPS.
Though saying that, changing it to the correct value didn't change anything.
And adding an extra ")" doesn't change anything either
 

woods

Member
my question is why would the map objects not wrap back once it sees that its outside of the map, is move_wrap not enough for it to see that its out of the map?

i took another look at move_wrap...
https://docs.yoyogames.com/source/d...vement and collisions/movement/move_wrap.html


Note that the instance must have a speed for wrapping to work, because the direction of wrapping is based on the direction of the motion.

would explain dirt tiles not wrapping when placed... unless your dirt has speed ;o)


====
doesnt this take one value... (n)?
irandom(n);


if thats the case... would it make sense that everything after room_width would fall off? unless it was wrapped in ()
x = irandom(room_width) div 32 * 32
vs
x = irandom((room_width)div 32*32)


edit.. i originally missed the first "(" in front of room_width ;o)
 
B

Bogan666

Guest
my question is why would the map objects not wrap back once it sees that its outside of the map, is move_wrap not enough for it to see that its out of the map?

i took another look at move_wrap...
https://docs.yoyogames.com/source/dadiospice/002_reference/movement and collisions/movement/move_wrap.html


Note that the instance must have a speed for wrapping to work, because the direction of wrapping is based on the direction of the motion.

would explain dirt tiles not wrapping when placed... unless your dirt has speed ;o)


====
doesnt this take one value... (n)?
irandom(n);


if thats the case... would it make sense that everything after room_width would fall off? unless it was wrapped in ()
x = irandom(room_width) div 32 * 32
vs
x = irandom((room_width)div 32*32)


edit.. i originally missed the first "(" in front of room_width ;o)
Gave that a test, though it kinda works, there seem to be a bunch of obj_dirts which aren't bound to the 32x32 spawn pattern I have. So they'll be all over the place overlapping and stuff.
very interesting that an object requires speed, I didn't read that part apparently.

hmm, this makes this all the much harder. do you know of a way that could warp or wrap an object to the otherside of the room assuming the space is clear?
 
B

Bogan666

Guest
Ahhh I don't get it. wrap still works technically, it is wraping objects that are over 32-64 (depending on what the value I have in move_wrap is) to the other side...but I can't understand why there is such a big gap in the distance before it starts to wrap. also the lack of speed thing is weird for this. these objects have no speed, just are just spawned at a position.
 
B

Bogan666

Guest
OKAY! I may have found some sort of solution. I tested a number of times and it seems to work, but I guess I'll find out later if there is issues.
Code:
if instance_position(room_width,y,self)
or instance_position(x,room_height,self)
    {
        x = irandom(room_width) div 32 * 32
        y = irandom(room_height) div 32 * 32
    }
   
move_wrap(true,true,0);
this is the step event in obj_dirt.
Though it kinda can cause some scuffed issues with where some of the objects are placed they seem to all be in the world now.
 

woods

Member
is surprising to me that move_wrap is even working on your placed tiles.... as it is designed to handle objects running away offscreen ;o)

this might be of use, to get your dirt lined up on your grid....
Code:
   if !place_snapped(32, 32)
      {
      move_snap(32, 32);
      }
 

jo-thijs

Member
my question is why would the map objects not wrap back once it sees that its outside of the map, is move_wrap not enough for it to see that its out of the map?

i took another look at move_wrap...
https://docs.yoyogames.com/source/d...vement and collisions/movement/move_wrap.html


Note that the instance must have a speed for wrapping to work, because the direction of wrapping is based on the direction of the motion.
This is because the GameMaker documentation is full of mistakes and this is one of them.
The implementation of move_wrap in GM:S 2.0 (and probably GM:S 1.4 too, but I currently can't test that to be sure) is equivalent to the script:
Code:
if argument0 {
    if x < -argument2 {
        x += room_width + argument2 * 2;
    } else if x > room_width + argument2 {
        x -=  room_width + argument2 * 2;
    }
}
if argument1 {
    if y < -argument2 {
        y += room_height + argument2 * 2;
    } else if y > room_height + argument2 {
        y -=  room_height + argument2 * 2;
    }
}
Ahhh I don't get it. wrap still works technically, it is wraping objects that are over 32-64 (depending on what the value I have in move_wrap is) to the other side...but I can't understand why there is such a big gap in the distance before it starts to wrap. also the lack of speed thing is weird for this. these objects have no speed, just are just spawned at a position.
It is working perfectly.
You've set the margin to wrap to 32 in a room with a height of 1056.
This allows y coordinates in the range of (-32, 1088).
The out-of-bounds y coordinate you found was 1088, which is still within that range.
You meant to use a margin of 0 instead (which would still allow 1 row and column of tiles outside the room).

OKAY! I may have found some sort of solution. I tested a number of times and it seems to work, but I guess I'll find out later if there is issues.
Code:
if instance_position(room_width,y,self)
or instance_position(x,room_height,self)
    {
        x = irandom(room_width) div 32 * 32
        y = irandom(room_height) div 32 * 32
    }
  
move_wrap(true,true,0);
this is the step event in obj_dirt.
Though it kinda can cause some scuffed issues with where some of the objects are placed they seem to all be in the world now.
This works because you use a margin of 0 and relocate instances when they are just over the border.

There is a much better approach however: don't spawn the instances on faulty coordinates in the first place!
Spawn them using:
Code:
repeat 4
{
    x = irandom(room_width / 32 - 1) * 32;
    y = irandom(room_height / 32 - 1) * 32;
    instance_create(x,y,obj_dirt);
}
 
B

Bogan666

Guest
Thanks for the help, think I might have got it sorted now, a couple friends gave some advice, but I'll look into these too, likely to be useful
 
Top