I spent six good hours on trying to spawning one monster on a nearby FREE tile RANDOMLY!

RyanYe

RPG Game Lover
Veteran
Joined
Dec 31, 2020
Messages
75
Reaction score
10
First Language
English
Primarily Uses
RMMV
Clipboard04.png

Clipboard01.png

Clipboard02.png

Clipboard03.png

I want to spawn one monster on nearby free tile RANDOMLY.
OK, here is what i did:
1, I use SRD_collision plugin to check west,north,east,south four nearby tiles
2, If it is empty , i set variable to a certain value
3, I wrote STUPID code to generate a random number on empty tiles
4, I spawn the monster by conditional branch and AABS plugin command.
yes I did it, but i think this is a very stupid way! I can feel it with my bones!

But the question is, I don't know how to do this in a DECENT/ELEGANT/NICE/NEAT way!
help!!
 

Zerothedarklord

Veteran
Veteran
Joined
Jun 25, 2013
Messages
339
Reaction score
106
First Language
English
Primarily Uses
RMMV
why not just make events in 4 spots, each one triggered by a variable's value being set to 1, 2, 3 or 4, and then when you want to spawn it, just set the variable's value to a random number between 1 and 4. that will easily do the same thing

If you want it to seem randomized, make more until it will feel random (maybe 32, 36 or 40), so that it will still feel random.
 

Eliaquim

Hakuen Studio
Veteran
Joined
May 22, 2018
Messages
1,880
Reaction score
1,354
First Language
Portuguese - Br
Primarily Uses
RMMZ
Hi!

Do that with the event interface can be a bit complicated and tricky sometimes. Why don't you go with a plugin that spawns events?
 

RyanYe

RPG Game Lover
Veteran
Joined
Dec 31, 2020
Messages
75
Reaction score
10
First Language
English
Primarily Uses
RMMV
why not just make events in 4 spots, each one triggered by a variable's value being set to 1, 2, 3 or 4, and then when you want to spawn it, just set the variable's value to a random number between 1 and 4. that will easily do the same thing

If you want it to seem randomized, make more until it will feel random (maybe 32, 36 or 40), so that it will still feel random.
I try to avoid make multiple event around the center event because i will copy this event to many places
and what's more, i want to place the event like this:
0X0
0?0
0X0
where X is event
if i place event like you said, the "?" place will be impossible to set
 

RyanYe

RPG Game Lover
Veteran
Joined
Dec 31, 2020
Messages
75
Reaction score
10
First Language
English
Primarily Uses
RMMV
Hi!

Do that with the event interface can be a bit complicated and tricky sometimes. Why don't you go with a plugin that spawns events?
hi i know how to spawn events, actually i can spawn event perfectly with AABS plugin(one single plugin command), but my point is "how to spawn event at FREE tiles ROMDAMLY"
the hard point is "FREE" and "RANDOM"
 

Kyuukon

主人公
Veteran
Joined
Aug 22, 2013
Messages
2,256
Reaction score
1,116
First Language
Spanish
Primarily Uses
RMMV
There is many ways to do this.
What I recently did to "randomly" spawn items around an area was more or less this:

Event: Move To Center(x,y) Loop Wait 20 frames Event: Move At Random (Skip) If(Event Is NOT at Center(x,y)) > Break Loop Loop End Event: Spawn (Self Switch A = ON)

I hope that helps.
 

RyanYe

RPG Game Lover
Veteran
Joined
Dec 31, 2020
Messages
75
Reaction score
10
First Language
English
Primarily Uses
RMMV
There is many ways to do this.
What I recently did to "randomly" spawn items around an area was more or less this:

Event: Move To Center(x,y) Loop Wait 20 frames Event: Move At Random (Skip) If(Event Is NOT at Center(x,y)) > Break Loop Loop End Event: Spawn (Self Switch A = ON)

I hope that helps.
thx but how to tell which tile is free tile?
and what's more, is this javascript?Can i run this code directly by copying them?

and one more thing, if there is no free tiles, i don't want the game crash by running into an endless loop
 

Kyuukon

主人公
Veteran
Joined
Aug 22, 2013
Messages
2,256
Reaction score
1,116
First Language
Spanish
Primarily Uses
RMMV
Ah, sorry it's lazy pseudo code (trying to simulate event commands xD). You can run this in a parallel process in the event itself on a blank page (through OFF) . The event will try to move to a random direction (assuming it allows diagonal movement too). If there is no free tiles on that random direction, then it will Skip the move command and attempt to move randomly again in 20 frames until it finally moves and breaks loop to spawn (the 20 frames is the "cooldown" so it doesn't lag but you can make it 1 frame and it will work fine too).

Save original position:
this.character(0)._spawnOriginalPositionX = this.character(0).x; this.character(0)._spawnOriginalPositionY = this.character(0).y;

Check IF it's not original position:
!this.character(0).pos(this.character(0)._spawnOriginalPositionX,this.character(0)._spawnOriginalPositionY)
 

Attachments

  • spawnevent.jpg
    spawnevent.jpg
    170.7 KB · Views: 7
  • spawnevent2.jpg
    spawnevent2.jpg
    126 KB · Views: 5

RyanYe

RPG Game Lover
Veteran
Joined
Dec 31, 2020
Messages
75
Reaction score
10
First Language
English
Primarily Uses
RMMV
Save original position:
this.character(0)._spawnOriginalPositionX = this.character(0).x; this.character(0)._spawnOriginalPositionY = this.character(0).y;

Check IF it's not original position:
!this.character(0).pos(this.character(0)._spawnOriginalPositionX,this.character(0)._spawnOriginalPositionY)

If there is no free tiles around, will this loop end by itself? or it will result in a dead loop and game crash?

EDIT: one more question, this method added a "wait 20 frames" and this could be multiple 20 frames if the event is blocked by three obstacles, (maybe 5 or 10 times as 20 frames if unlucky)
and this is not what i expect, i want the game "SMARTLY" find out which is free tile and spawn the event precisely and directly, not "try -> fail -> try -> fail -> try -> success" mode
 

Kyuukon

主人公
Veteran
Joined
Aug 22, 2013
Messages
2,256
Reaction score
1,116
First Language
Spanish
Primarily Uses
RMMV
Try it. If you do it like in the picture it won't ever make your game freeze/crash. And it will keep trying to spawn for as long as you are in that map (even if there are no free tiles around).

EDIT: one more question, this method added a "wait 20 frames" and this could be multiple 20 frames if the event is blocked by three obstacles, (maybe 5 or 10 times as 20 frames if unlucky)
and this is not what i expect, i want the game "SMARTLY" find out which is free tile and spawn the event precisely and directly, not "try -> fail -> try -> fail -> try -> success" mode
You could change it to 1 frame and the waiting time will be barely noticeable. But yeah, I guess there is better ways to do it, I just went with an easy eventing solution :p
 
Last edited:

RyanYe

RPG Game Lover
Veteran
Joined
Dec 31, 2020
Messages
75
Reaction score
10
First Language
English
Primarily Uses
RMMV
Try it. If you do it like in the picture it won't ever make your game freeze/crash. And it will keep trying to spawn for as long as you are in that map (even if there are no free tiles around).
ok, i will try it
谢谢啊!
 

Eliaquim

Hakuen Studio
Veteran
Joined
May 22, 2018
Messages
1,880
Reaction score
1,354
First Language
Portuguese - Br
Primarily Uses
RMMZ
hi i know how to spawn events, actually i can spawn event perfectly with AABS plugin(one single plugin command), but my point is "how to spawn event at FREE tiles ROMDAMLY"
the hard point is "FREE" and "RANDOM"
That's why I recommend this one. Because normally these kinds of plugins already have functions to do what you want. If you take a look at the features, you would see that it also support to spawn event at random tiles:
1614245937797.png
So you can either choose a region id or use a region id = 0 (which is no region id) then spawn your event.
 

RyanYe

RPG Game Lover
Veteran
Joined
Dec 31, 2020
Messages
75
Reaction score
10
First Language
English
Primarily Uses
RMMV
That's why I recommend this one. Because normally these kinds of plugins already have functions to do what you want. If you take a look at the features, you would see that it also support to spawn event at random tiles:
View attachment 180849
So you can either choose a region id or use a region id = 0 (which is no region id) then spawn your event.

I surely have taken looks at all descriptions, but these features is not FREE tiles checking feature
I cannot know the x,y or region ID because everything will be the different in the middle of the game, i have to check FREE tiles dynamically.

I must write code or command to check free tiles around, i cannot use solid X,Y or region ID, because they can be BLOCKED at any time( such as the player blocked it)
 
Last edited:

ImaginaryVillain

High Cultist of the Sporkle
Veteran
Joined
Jun 22, 2019
Messages
879
Reaction score
5,245
First Language
Absurdism
Primarily Uses
RMMZ
JavaScript:
    let x = 0 //X cordinate of the event
    let y = 0 //Y cordinate of the event
    let arrayX = [x + 1, x - 1, x, x];
    let arrayY = [y, y, y + 1, y - 1];
    for (let i = 0, target = 0; i < 4; i++) {
        target = $gameMap.eventIdXy(arrayX[i], arrayY[i]);
        if (target === 0) {
            //whatever you wanted to do if the spot is empty
            break;
        }
    };

Run this, making x, y equal to the coordinates of the chest/trap/tree/floating sentient taco/etc. As soon as it finds an empty space going in a circle around the target it will execute your command and break the loop.

This won't randomize it though. If you wish to do that, you can push each successful "target" coordinates to an array, then math.random that array for one and use that as the coordinates for spawning in something. Or I guess you could just use $gameMap.event(eventID).setPosition(x, y); using the successful target coordinates arrayX, arrayY as the x,y if you don't wish to use an event spawner.
 

Eliaquim

Hakuen Studio
Veteran
Joined
May 22, 2018
Messages
1,880
Reaction score
1,354
First Language
Portuguese - Br
Primarily Uses
RMMZ
Ok, got it. I forgot about the nearly random tiles. Otherwise, you could use the Galv plugin to spawn event in region ID 0(which means all map tiles that don't have regions), then it will automatically check for solid X, Y, and free to spawn. But guess it's a little complicated to do it.

But I made a function to do it for you. Currently, it will check if the tile X, Y is:
  • Passable;
  • Doesn't have an event
  • Doesn't have a vehicle
  • Doesn't have a player
If all of that is true, then you get a free coordinate X, Y

It has four parameters: px, py, range, eventId

So you can either use the event id for it or an x, y coordinate of your choice.

After that, you set the range parameter which will be responsible to define all the nearby tiles that you want to check.

If you set a range of 2 and put the event id of the chest, then the function will search for free tiles on the range shown in the picture below:
getFreeTileToSpawnEvent(0, 0, 2, chestId)
Clipboard04.png
You can save it as a plugin(recommended) and use a script call to invoke the function.
See if it will work, I believe I made all the necessary checks (Or not? ^^'')

JavaScript:
function getFreeTileToSpawnEvent(px, py, range, eventId) {

    if(eventId){
        px = $gameMap.event(eventId).x
        py = $gameMap.event(eventId).y
    }

    const startX = Math.max(px - range, 0)
    const startY = Math.max(py - range, 0)
    const endX = Math.min(px + range, $dataMap.width-1)
    const endY = Math.min(py + range, $dataMap.height-1)
    const shuffle = function (array) {
        let elementsLeft = array.length;
        let currentElement;
        let randomIndex;

        while (elementsLeft) {
          randomIndex = Math.floor(Math.random() * elementsLeft--);
          currentElement = array[elementsLeft];
          array[elementsLeft] = array[randomIndex];
          array[randomIndex] = currentElement;
        }
     
        return array;
    }
   
    let coords = []

    for(let x = startX; x <= endX; x++){
        for(let y = startY; y <= endY; y++){
            coords.push([x, y])
        }
    }

    coords = shuffle(coords)

    for(let i = 0; i < coords.length; i++){
        const [x, y] = coords[i]
        console.log(x, y)
        // Check if has a event here
        if($gameMap.eventsXyNt(x, y).length > 0) continue
        // Check if the player is here
        if($gamePlayer.pos(x, y)) continue
        // Check if this tile is passable
        if(!$gameMap.isPassable(x, y)) continue
        // Check if has a vehicle here
        if($gameMap.vehicles().some(vehicle => vehicle.pos(x, y))) continue
        // If all above is false, you can spawn your event in this coordinate.
        // Replace with the function that you use to spawn the event. Then break the loop
        console.log('can spawn here!')
        break
    }

}

[EDIT] Seeing the post of the @ImaginaryVillain , it seems that I forgot the random nearby detail...
I Will see what I can do about it to implement in this function xD

[EDIT 2] - Ok, I fixed it! It is disorganized, but it is working xD. Maybe there is a space for improvement too, but I didn't go this far.
Put that code in a .js file and put it into your plugin manager.

Then all you have to do is use the script call:
getFreeTileToSpawnEvent(0, 0, 2, chestId)

Don't forget to replace the "console.log('can spawn here!')" With the function, you use to spawn your events.
 
Last edited:

RyanYe

RPG Game Lover
Veteran
Joined
Dec 31, 2020
Messages
75
Reaction score
10
First Language
English
Primarily Uses
RMMV
Ok, got it. I forgot about the nearly random tiles. Otherwise, you could use the Galv plugin to spawn event in region ID 0(which means all map tiles that don't have regions), then it will automatically check for solid X, Y, and free to spawn. But guess it's a little complicated to do it.

this is super great!! I will try it tomorrow(my bedtime for now)
super thx for you to write so many complex code for me, already burst into tears!!!!!
 

Stimulantfound

La Princesa Stephany
Veteran
Joined
Feb 14, 2021
Messages
60
Reaction score
91
First Language
Español
Primarily Uses
RMMZ
This thread was very informative, and if you found your solution, I'm happy for you, but I want to ask you a question . . . if you don't mind telling me, from a game design perspective, why does this event need to be truly random?
 

RyanYe

RPG Game Lover
Veteran
Joined
Dec 31, 2020
Messages
75
Reaction score
10
First Language
English
Primarily Uses
RMMV
This thread was very informative, and if you found your solution, I'm happy for you, but I want to ask you a question . . . if you don't mind telling me, from a game design perspective, why does this event need to be truly random?

Yes , spawning monster in a fixed order is kinda easy to do. But i am kind of perfection, I think randomly generating is better than fixed order so i will get the better one i want, and what's more, doing this kind of game setting may enhance my skill quite a lot. and knowing great ppl here! It's worth a time spending !

cheers!
 

RyanYe

RPG Game Lover
Veteran
Joined
Dec 31, 2020
Messages
75
Reaction score
10
First Language
English
Primarily Uses
RMMV
Ok, got it. I forgot about the nearly random tiles. Otherwise, you could use the Galv plugin to spawn event in region ID 0(which means all map tiles that don't have regions), then it will automatically check for solid X, Y, and free to spawn. But guess it's a little complicated to do it.

I have tried, but i don't know how to pass the calculated X,Y to variables for my spawning command to execute, help!
 

Attachments

  • Clipboard01.png
    Clipboard01.png
    15 KB · Views: 5

Eliaquim

Hakuen Studio
Veteran
Joined
May 22, 2018
Messages
1,880
Reaction score
1,354
First Language
Portuguese - Br
Primarily Uses
RMMZ
Hi there!
First, you have to replace this "chestId" with the ID of the event. I write "chestId" as an example for you. But this arg must be a valid event id.

I updated the code to set the x and y to variables Id of your choice. The thing is that you always be variable 3 and 4. If you want to change something, you can take a look at the code. You can even add more parameters to the script call.

But if the function doesn't find a free x and y tile? You will use your plugin command and it will take the values of the last time you used the script call.
In an attempt to prevent that, I put the variables 3 and 4 to be always -1 when you call your script call. And if it finds a free x and y, they will set the variable values with this x and y.

So I recommend that after you use the script call and before you use the plugin command, you make a conditional branch checking if either variable 3 or 4 is higher than -1. If yes, then you use the plugin command.

JavaScript:
function getFreeTileToSpawnEvent(px, py, range, eventId) {
    $gameVariables.setValue(3, -1)
    $gameVariables.setValue(4, -1)
    if(eventId){
        px = $gameMap.event(eventId).x
        py = $gameMap.event(eventId).y
    }

    const startX = Math.max(px - range, 0)
    const startY = Math.max(py - range, 0)
    const endX = Math.min(px + range, $dataMap.width-1)
    const endY = Math.min(py + range, $dataMap.height-1)
    const shuffle = function (array) {
        let elementsLeft = array.length;
        let currentElement;
        let randomIndex;

        while (elementsLeft) {
          randomIndex = Math.floor(Math.random() * elementsLeft--);
          currentElement = array[elementsLeft];
          array[elementsLeft] = array[randomIndex];
          array[randomIndex] = currentElement;
        }
    
        return array;
    }
  
    let coords = []

    for(let x = startX; x <= endX; x++){
        for(let y = startY; y <= endY; y++){
            coords.push([x, y])
        }
    }

    coords = shuffle(coords)

    for(let i = 0; i < coords.length; i++){
        
        const [x, y] = coords[i]
        if($gameMap.eventsXyNt(x, y).length > 0) continue
        if($gamePlayer.pos(x, y)) continue
        if(!$gameMap.isPassable(x, y)) continue
        if($gameMap.vehicles().some(vehicle => vehicle.pos(x, y))) continue
      
        // Variables to hold X and Y values
        
        $gameVariables.setValue(3, x)
        $gameVariables.setValue(4, y)
        break
    }

}
 

Latest Threads

Latest Posts

Latest Profile Posts

BCj
Whelp, it's been a while. Had another retina surgery on april 1st on my left eye. Well, 4 time's the charm, right? *recovery mode on*
The next JABS update will include ally AI and an aggro system.

Question:
What would YOU expect to happen if you had four+ party members in an ABS, all fighting either together or separately or a mix of the two, and the player hits "swap leader" button?
It currently pulls all followers to the player's location, removes all aggro towards enemies, and swaps them.
Time to wear a new face again...

Should keep things interesting huh? @EpicFILE :p
unknown.png

Been feeling that my characters spent too much time exploring caves, so I figured it was time to explore abandoned keeps instead.
Did you had some minor hitches with RMMZ? Come report to my topic where I did the same! [Just another rant from a RM veteran + Suggestions and Solutions] All opinions are welcome!

Forum statistics

Threads
110,329
Messages
1,052,393
Members
143,371
Latest member
DrXGB
Top