Boids: natural flight movement and behavior

Post your example zscripts/ACS scripts/etc here.
Forum rules
The Projects forums are only for projects. If you are asking questions about a project, either find that project's thread, or start a thread in the General section instead.

Got a cool project idea but nothing else? Put it in the project ideas thread instead!

Projects for any Doom-based engine (especially 3DGE) are perfectly acceptable here too.

Please read the full rules for more details.
User avatar
4page
Posts: 117
Joined: Tue Aug 06, 2019 5:08 pm
Location: American Pacific Northwest

Boids: natural flight movement and behavior

Post by 4page »

BOIDS
A library to give your flying actors a little more variety.
Use it with just a single actor to give them a nice flying behavior, or with many actors to create a flock.
Use it for decorative purposes, or for enemies, or friendlies.
Use it on pickup items to make them nearly impossible to grab.
Do whatever you want with it, I'm not your boss, I can't tell you what to do.





Other vids:
Spoiler:
To use it, just inherit from HXA_Boid, then use the BoidFlight() function every tick you want the behavior to be active. So maybe in a Tick() override or something.
Be warned, there's a lot going on with these which increases drastically the more you have. I don't know exactly how performance impacting they are exactly, but probably only use as many as you need.

Inside there are several example classes that I put together to showcase how it can be used in various situations. Just spawn them from the console to see how they behave. Some work best in a large group of them, others work well by themselves.

DOWNLOAD HERE
GZDoom Boids Library

Questions, comments, suggestions, and critiques are all appreciated. Please credit me if you end up using this.
Last edited by 4page on Fri Feb 04, 2022 9:03 am, edited 4 times in total.
User avatar
Enjay
 
 
Posts: 26430
Joined: Tue Jul 15, 2003 4:58 pm
Location: Scotland

Re: Boids: natural flight movement and behavior

Post by Enjay »

This could create some very convincing decorative flocks of birds. It's quite reminiscent of a starling mumuration:
User avatar
4page
Posts: 117
Joined: Tue Aug 06, 2019 5:08 pm
Location: American Pacific Northwest

Re: Boids: natural flight movement and behavior

Post by 4page »

That's exactly what it's designed to do! Boids are an artificial life program designed to simulate the flocking behavior of birds. I learned about them a couple years ago and was really interested in them, especially since they have only 3 basic parameters. And ever since then I wanted to make them in GZDoom.

The three parameters are Separation: steering to avoid other boids, Alignment: steering to match the average heading of local flock mates, and Cohesion: steering to move to the center of the flock. Really interesting stuff to look at. https://en.wikipedia.org/wiki/Boids

I did end up cutting some corners, and embellishing some things though, so it's not quite right, but close enough I suppose.
User avatar
Enjay
 
 
Posts: 26430
Joined: Tue Jul 15, 2003 4:58 pm
Location: Scotland

Re: Boids: natural flight movement and behavior

Post by Enjay »

4page wrote:close enough I suppose.
Close enough for me to recognise the behaviour without me knowing the background to the idea and never having heard of boids before. So, yes, definitely close enough IMO. :D

Now that I know the term "boids" it seems obvious that part of the intention behind the name is "birds" in a New York accent. However, living approximately 3,270 miles from New York, I can be forgiven for not spotting that straight away. ;)
User avatar
Matt
Posts: 9679
Joined: Sun Jan 04, 2004 5:37 pm
Location: Gotham City SAR, Wyld-Lands of the Lotus People, Dominionist PetroConfederacy of Saudi Canadia

Re: Boids: natural flight movement and behavior

Post by Matt »

Sweet!
Be warned, there's a lot going on with these which increases drastically the more you have.
I'm not really in a position to look at the code right now, but does it have to iterate through every other boid on the map to check this stuff, or a BlockThingsIterator, or did you find some other way that didn't have to iterate as much?
User avatar
4page
Posts: 117
Joined: Tue Aug 06, 2019 5:08 pm
Location: American Pacific Northwest

Re: Boids: natural flight movement and behavior

Post by 4page »

It uses a thinker iterator to go through every boid of a selected type on the map, but it only really interacts with them if they are within range so it will do mostly a couple checks then continue. Unless you increase the range drastically. I haven't had TOO much in the way of performance hits with it, and I've had like 100 basic boids in a map at once and while it wasn't unplayable it did noticeably impact framerate. But that's major overkill. You'll really only need upwards of 15 to 20 to get the idea across. Plus I think splitting them into multiple flocks would probably help performance even more, since instead of each iterating with every single one, they'll only iterate through ones it can interact with.

Edit: just tested it, and yeah having 100 boids in 1 flock is really heavy, but having 100 boids in 5 flocks is significantly less so. I'll probably try to come up with a limiter on the iterators, so they only go through and interact with a limited number.
User avatar
Caligari87
User Accounts Assistant
Posts: 5997
Joined: Thu Feb 26, 2004 3:02 pm
Preferred Pronouns: He/Him

Re: Boids: natural flight movement and behavior

Post by Caligari87 »

What about having the Boids add themselves to a per-species array in an event handler when they spawn? Would iterating over that array be faster than a BlockThingsIterator perhaps?

8-)
User avatar
eharper256
Posts: 869
Joined: Sun Feb 25, 2018 2:30 am
Location: UK

Re: Boids: natural flight movement and behavior

Post by eharper256 »

:D This is awesome 4page! Lets you do alot more autonomous flying projectiles. Just when I was thinking of trashing the Raven Familiar idea as well, so that poor birb has been saved. :)
User avatar
4page
Posts: 117
Joined: Tue Aug 06, 2019 5:08 pm
Location: American Pacific Northwest

Re: Boids: natural flight movement and behavior

Post by 4page »

Would iterating over that array be faster than a BlockThingsIterator perhaps?
Well, I'm using a ThinkerIterator, not a BlockThingsIterator, and the ThinkerIterator you can tell it specifically what class you want to iterate through. I needed to do ThinkerIterator specifically because I want the Boids to be able to function without being part of the blockmap. And I think that's how it works, but I'm no expert....
Just when I was thinking of trashing the Raven Familiar idea as well, so that poor birb has been saved.
Pretty much the entire reason I made this now is because I'm going to be using it to make a flying familiar type thing. :D
User avatar
Enjay
 
 
Posts: 26430
Joined: Tue Jul 15, 2003 4:58 pm
Location: Scotland

Re: Boids: natural flight movement and behavior

Post by Enjay »

I've been trying to code something that uses this and failed. I wonder if anyone might be willing to help out?

What I had in mind was an invisible, placeable object that the boids would use as the centre of their flying/flocking activity. I thought this would a good idea so that the object might be placed, say, where you want an atmospheric flock of ravens flitting around but you don't want them to wander too far.

I thought, perhaps, the placeable thing could take arguments such as number of boids to spawn, maximum radius they can wander too and maybe some other parameters too. However, as I said, I have failed. :( Not sure why, it seems simple enough in concept but everything I have tried so far has either not spawned anything or ignored my parameters entirely.
User avatar
eharper256
Posts: 869
Joined: Sun Feb 25, 2018 2:30 am
Location: UK

Re: Boids: natural flight movement and behavior

Post by eharper256 »

Enjay wrote:I've been trying to code something that uses this and failed. I wonder if anyone might be willing to help out?

What I had in mind was an invisible, placeable object that the boids would use as the centre of their flying/flocking activity. I thought this would a good idea so that the object might be placed, say, where you want an atmospheric flock of ravens flitting around but you don't want them to wander too far.

I thought, perhaps, the placeable thing could take arguments such as number of boids to spawn, maximum radius they can wander too and maybe some other parameters too. However, as I said, I have failed. :( Not sure why, it seems simple enough in concept but everything I have tried so far has either not spawned anything or ignored my parameters entirely.
Just create a seperate actor that uses A_SpawnItemEx to generate a custom boid, and give that boid the flight parameters of CloseToMaster, and reduce the default range to about 200. Something like this:

Code: Select all

BoidFlight(MaxVelocity: 12, CloseToMaster: TRUE, DistanceFromMaster: 200);
Spawned with this sort of thing:

Code: Select all

A_SpawnItemEx("AngryBirb",20,0,40,0,0,0,0,SXF_SETMASTER);
And have that iterate as many times as you want birds. If you want a duration controllable by the main spawner, put the conditions for that into a state somewhere on the spawner, and then have it give items to children, and have the boid check whether it has that item every so often and if so send it to a death state with a Stop.

It's what I'm using with my current familiar when its not got a target and it seems to work well.
User avatar
4page
Posts: 117
Joined: Tue Aug 06, 2019 5:08 pm
Location: American Pacific Northwest

Re: Boids: natural flight movement and behavior

Post by 4page »

Yeah, I hope I didn't make it too confusing. Basically all the conditions have to be done from the Boid actor itself. So you CAN have a controller, but it has to pass all the info to the boids, or spawn actors with predefined properties.
User avatar
IvanDobrovski
Posts: 83
Joined: Mon Aug 08, 2016 4:05 am

Re: Boids: natural flight movement and behavior

Post by IvanDobrovski »

This looks very good. I've dabbled with Boid systems in college for a bit, they can look amazing if done right. Yours looks very satisfying and convincing. Nicely done.
User avatar
4page
Posts: 117
Joined: Tue Aug 06, 2019 5:08 pm
Location: American Pacific Northwest

Re: Boids: natural flight movement and behavior

Post by 4page »

Thanks! I'm sure it breaks easily under many circumstances, but I'll try to address issues as they arise.
User avatar
Enjay
 
 
Posts: 26430
Joined: Tue Jul 15, 2003 4:58 pm
Location: Scotland

Re: Boids: natural flight movement and behavior

Post by Enjay »

OK, been away for a few days because a storm took down my electricity and my Internet.

This is what I have by way of a couple of test actors. All actor names, and everything else too, are subject to change. Could someone who understands ZScript a bit better take a look and see where it can be improved?

The intention is to be able to place an actor that spawns a flock of boids which then stay centred on the spawning actor. i.e. it creates a decorative flock of boids.

At present it seems to work, but it's probably clumsily coded and error-filled.

Code: Select all

Class NJBoider : Actor
{

    default
    {
    +NOGRAVITY;
    }
    
    States
    {
    Spawn:
    POSS A 0;
    POSS A 0 A_JumpIf(args[0] == 0, "BoidsIsNull");
    //
    SpawnBoids:
    POSS A 1 Bright A_SetArg(4, args[0]);
    SpawnBoids2:
    POSS A 0 Bright A_JumpIf(args[4] == 0, "NoMoreBoids");
    POSS A 0 Bright A_SpawnItemEx("NJBoid",20,0,40,0,0,0,0,SXF_SETMASTER|SXF_NOCHECKPOSITION);
    POSS A 0 Bright A_SetArg(4, args[4] - 1);
    Goto SpawnBoids2;
    
    
    BoidsIsNull:
     POSS A 1 A_SetArg(0, 8);
     goto SpawnBoids;


    NoMoreBoids:
    SPOS A -1;
    Stop;
    }
}
The NJBoider actor above is the one that spawns the flock. Obviously, the final version will not be visible. I *think* I have set it up so that it reads arg0 and then spawns a number of boids equal to that arg's value. If the arg is 0, it sets itself to a default of 8. This was adapted from some old DECORATE code and I could well have made some mistakes here but, like I said, it does seem to work.

Code: Select all

Class NJBoid : HXA_Boid
{
    Override Void Tick()
    {
        BoidFlight(MaxVelocity: 12, CloseToMaster: TRUE, DistanceFromMaster: 200);
        Super.tick();
    }
    Default
    {
        HXA_Boid.BoidActor "NJBoider";
        +MISSILE;
        -ISMONSTER;

        +CANNOTPUSH;
        +NOTELEPORT;
        +NOTELESTOMP;
        +NOBLOCKMONST;
        +THRUACTORS;
        
        -ACTIVATEIMPACT;
        -CANPUSHWALLS;
        -CANUSEWALLS;
        -ACTIVATEMCROSS;
        -ACTIVATEPCROSS;
    }
    
} 
The NJBoid actor is the boid that I want to spawn in flocks. I know that I've gone over the top with the flags - I can address that. It's the other stuff I need to check to make sure it is OK. The boids aren't flying quite how I want them to (a bit to erratic in the Z axis, a bit fast and wander a bit too far from the spawning actor), but I'm guessing I can tweak this with some more parameter changes.

I don't want these boids to die, despawn, whatever (i.e. they are a permanent decoration) but once I have things figured out, I will probably change the spawning actor so that it can be deactivated and call A_RemoveChildren. That way the flock could be despawned/respawned via ACS if need be.

The line HXA_Boid.BoidActor "NJBoider"; seems to be necessary. If I don't have that, separate flocks from different "NJBoider" actors seem to not stay separate. Is that correct? Have I used the line correctly?




So, can it be improved?

Return to “Script Library”