Any script for randomizing an enemy/entity spawn with a ranged area/coord?

Mr.Q!

Well-known member
Topic.
What I am experiencing is people know where an enemy/boss is going to pop out at certain times, so players wait for them and perform meaty attacks on them for guaranteed damage.
 
Topic.
What I am experiencing is people know where an enemy/boss is going to pop out at certain times, so players wait for them and perform meaty attacks on them for guaranteed damage.

You can certainly do it, but yes, it would have to be scripted. IIRC, both @Bloodbane and @Kratus have such systems already. Tagging them to see.

DC
 
Topic.
What I am experiencing is people know where an enemy/boss is going to pop out at certain times, so players wait for them and perform meaty attacks on them for guaranteed damage.
I suggest taking a look at my SOR2X game. In the chars/random folder, there's some dummy enemies used to spawn other enemies applying some randomness.
There you will find random names, palettes, and you can also add random positions following the same logic.

EDIT: You can also try changing the position directly in the level spawn using inline scripts. The concept would be something like this:

Code:
spawn        Galsia
@script       
void main()
{
    if(random >= chance){
        changeentityproperty(self, "position", x+amount, z, y);
    }
}
@end_script
flip        1
coords        350 150 0
at            0
 
Last edited:
I'm not sure how enemies are spawned in your game.
If they are spawned using enemy spawner, you'd need to modify that spawner to apply position randomizer.
If they are spawned in the level directly, you could use this spawnscript to randomize their position.
RandXY.c:
C:
void main()
{
    void self = getlocalvar("self");
    int Minz = openborvariant("PLAYER_MIN_Z");
    int Maxz = openborvariant("PLAYER_MAX_Z");
    int XPos = openborvariant("xpos"); //Get screen edge's position
    int Screen = openborvariant("hResolution"); // Get screen width
    int r = rand()%50;
    int zW = Maxz - Minz;
    int zM = Minz + zW/2;
    float dz = zM + zW*r/100;
    int W = 60;

    if(r%2 == 1){
      changeentityproperty(self, "position", XPos + Screen + W, dz);
    } else {
      changeentityproperty(self, "position", XPos - W, dz);
    }
}

Declare it like this:
Code:
spawn   Enemy
spawnscript data/scripts/RandXZ.c
health  20
coords  400 206
at      0

With this declared, Enemy could appear from either left or right edge and at randomized z coord.
 
My bad, I didn't give more information.

Given the image attached to this post (very rough sketch):

Ok so he is getting owned each time he spawns despite having no bbox, and I don't want to add an attack to him, so a spawnscript would be nice, yes, but in a way that it doesn't necessarily spawn outside the screen but within a range starting from his real spawning coord position in the stage .txt file...Something like:


  • Blue area is the walkable ground
  • Yellow are are walls
  • Red circle is where the enemy is currently spawning. Imagine he is a ninja so he just teleports there, with a proper anim spawn.
Imagine a stage with a walkable area of 130 minz, 220 maxz, 500pixels long:

Spawn NinjaOwnedByMeatyAttack
spawnscript <--- A script that checks current spawning coord an randomize within a range from said point, like (minus50 Xpixels, plus50 Xpixels, minus30 Zpixels, plus30 Zpixels)
coords 250 180 0
at 0

Sorry if I am explaining this badly :ROFLMAO:
 

Attachments

  • bor - 0000.png
    bor - 0000.png
    70 KB · Views: 9
@Mr.Q!

Basically you'd want to start with code that defines a cube based on adjustable coordinates. That way you can just provide the bounding for each spawn as needed. I would give the system a default size so you can shortcut for most uses.

Then within that cube, you can run RNG to get a spot within it.

So on spawn in the designated position, the cube generates centered on the entity, a random spot inside of the cube gets selected and then entity is moved there instantly. On screen, it would appear the entity spawns into a random place within around the general area.

Not too complex really. Just a bit of geometry work and some optimization to minimize the the math.

Unfortunately I'm way too tied up this week to write the code. Interviewing for academic work. Mid next week I could look at making you a sample if no one beats me to it.

DC
 
RandXY.c:

This method having a ranged 'cube' for randomizing spawn position starting from the spawning coord would be the best solution so it can be used with other entities as well depending the different possible scenarios.
 
Ranged cube.... are you spawning enemies onscreen instead offscreen? that spawnscript above is for spawning enemies offscreen BTW.
 
Yes, I mean, if should just pay attention to the spawning coord in the stage .txt and starting from there, a randomized spawning range acting as a 'cube' like DC said, so it shouldn't matter if it's onscreen or offscreen . This can actually have lots of uses for npc's, weather stuff, environment, etc.
 
Okay, try this spawnscript:
RandCu.c
C:
void main()
{
    void self = getlocalvar("self");
    int x = getentityproperty(self, "x");
    int z = getentityproperty(self, "z");
    int Minz = openborvariant("PLAYER_MIN_Z");
    int Maxz = openborvariant("PLAYER_MAX_Z");
    int Wx = 50; // possible spawn length in x
    int Wz = 30; // possible spawn width in z
    int r = rand()%50;
    int s = rand()%50;
    float dx = Wx*r/50;
    float dz = Wz*s/50;
    int Nz = z + dz;

    if(Nz < Minz){
      Nz = Minz;
    } else if(Nz > Maxz){
      Nz = Maxz;
    }

    changeentityproperty(self, "position", x + dx, Nz);
}

I've added z check to prevent script to put enemies outside playing field.
 
It's working, but for some reason it's not respecting the coord info from the stage.txt, so the enemy is being spawned at times outside the screen and inside walls depending on where the scroll is at the moment.
 
So do you want the script to randomize position but not placing enemy offscreen and inside walls?
The former should be easy but the latter might require some tricks.
 
Alright, here's the updated script:
RandCu.c
C:
void main()
{
    void self = getlocalvar("self");
    int x = getentityproperty(self, "x");
    int b = getentityproperty(self, "base");
    int z = getentityproperty(self, "z");
    int Wx = 50; // possible spawn length in x
    int Wz = 30; // possible spawn width in z
    int Nx = RandoXZ(Wx, Wz, "x");
    int Nz = RandoXZ(Wx, Wz, "z");
    int Cy = checkwall(Nx,Nz);

    while(Cy > b){
      Nx = RandoXZ(Wx, Wz, "x");
      Nz = RandoXZ(Wx, Wz, "z");
      Cy = checkwall(Nx,Nz);
    }

    changeentityproperty(self, "position", Nx, Nz);
}

void RandoXZ(int Rx, int Rz, void C)
{ // Randomizes position 
    void self = getlocalvar("self");
    int x = getentityproperty(self, "x");
    int z = getentityproperty(self, "z");
    int XPos = openborvariant("xpos"); //Get screen edge's position
    int Screen = openborvariant("hResolution"); // Get screen width
    int Minz = openborvariant("PLAYER_MIN_Z");
    int Maxz = openborvariant("PLAYER_MAX_Z");
    int r = rand()%50;
    int s = rand()%50;
    float dx = Rx*r/50;
    float dz = Rz*s/50;
    int Nx = x + dx;
    int Nz = z + dz;

    if(Nx < XPos){
      Nx = XPos;
    } else if(Nx > XPos + Screen){
      Nx = XPos + Screen;
    }

    if(Nz < Minz){
      Nz = Minz;
    } else if(Nz > Maxz){
      Nz = Maxz;
    }

    if(C == "x"){
      return Nx;
    } else if(C == "z"){
      return Nz;
    }
}

This one prevents entity from going offscreen and from entering walls.

HTH
 
Tested, and the game crashed badly, it froze and didn't close properly so no log after shutting down.
 
I'll give a better example:


That's the stage, it has walls on both sides. I am spawning ninja at the yellow dot with proper coords, and 'at 0' so he will instantly spawn over there. He takes at least one second to have an active bbox so player wait for his spawning animation to end and atack him already and meaty combo him to death.

The blue area should be the randomized area where he could spawn, and the blue 'cube' range could be declared in a spawnscript like:

is the character being spawned at X, Z? then :

spawn whithin randomx coord: -50 50 (50 pixels back and front of the stage spawning coord)
and randomz coord: -20 20 (20 pixels into the background and 20 pixels into the foreground of the stage spawning coord)
 

Attachments

  • Dibujo.GIF
    Dibujo.GIF
    131.2 KB · Views: 9
Strange, I've just tested the script myself and it works fine in that stage.
Can you tell me at which level you declare that script?
 
Tested with enemy ESodom2 in stage 2.4 using the given spawning coord. It works well until he gets to be spawned at certain random location that makes the engine get stucked with a crash and no log.
 
Hmmm.... I don't know how you did that but I've tried declaring RandCu.c on other enemies in stage2.4 and the script works fine. I've moved their starting coordinate to the center of screen and field to prevent them from getting stuck.
RandCu.c is designed to randomize enemy's position around 50 pixels in x and 30 pixels in z. If the script drops enemy inside a wall, the script would rerun the randomizer again until enemy is not inside a wall.
IOW you have to ensure enemy doesn't start near any wall before using this script to prevent the script from endless loop and caused the crash.
 
Back
Top Bottom