Detect collision with cliffs

Place to get help with not working mods / modding interface.
Post Reply
Pi-C
Smart Inserter
Smart Inserter
Posts: 1656
Joined: Sun Oct 14, 2018 8:13 am
Contact:

Detect collision with cliffs

Post by Pi-C »

Is there any way to detect collisions of vehicles using the "car" prototype with a cliff? It seems if you bump into a cliff while driving, the vehicle doesn't take damage, so I listening to on_entity_damaged doesn't work. I'm collaborating on Autodrive, and while the mod's pathfinder avoids cliffs, I've been experimenting with a kind of panic mode. In certain situations the vehicle should just get out of the way as soon as possible, so I send it off the calculated path in a straight line. If a cliff happens to be in its way, the vehicle just hangs there trying to get through (this would work with rocks or trees, as they finally get killed). So, how do I detect that the obstacle in its way is a cliff?
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!

Honktown
Smart Inserter
Smart Inserter
Posts: 1028
Joined: Thu Oct 03, 2019 7:10 am
Contact:

Re: Detect collision with cliffs

Post by Honktown »

Feels bad for having nothing to do and responding quickly to posts
You can do a find_entities_filtered within a "one second" radius of the car (approximate it based on speed, etc). Check every second it's driving or after repathing. If a cliff's collision box would collide with a 1-second long line segment, re-path the car.

Needed to do this for a different context: collision detection with blueprinting and cliffs isn't quite right. Game detects most collisions and removes ghosts, but doesn't detect all of them when you unmark the cliff for destruction and/or use a blueprint specifically.
Turn a collision box into four line segments -> see if any collide with the four line segments you make from another collision box or one entity is completely outside the other.
I phrase it with line segments, because I already looked it up and one of the algorithms is the line segment intersection algorithm. Don't understand how it works, but an algorithm is programmable.

Edit:

or this

https://www.geeksforgeeks.org/check-if- ... intersect/

That looks a lot easier, and has code examples.
I have mods! I guess!
Link

Honktown
Smart Inserter
Smart Inserter
Posts: 1028
Joined: Thu Oct 03, 2019 7:10 am
Contact:

Re: Detect collision with cliffs

Post by Honktown »

For your case, there might be an even easier way: If it's not moving but you're supposed to be, look for stuff within a small radius that could be stopping you. Only works after it collides.
I have mods! I guess!
Link

Pi-C
Smart Inserter
Smart Inserter
Posts: 1656
Joined: Sun Oct 14, 2018 8:13 am
Contact:

Re: Detect collision with cliffs

Post by Pi-C »

Honktown wrote:
Sun Dec 22, 2019 4:48 pm
For your case, there might be an even easier way: If it's not moving but you're supposed to be, look for stuff within a small radius that could be stopping you. Only works after it collides.
Thanks, I think I'll do that! Already thought of something along these lines. It's actually more versatile that an event or something for checking just cliff collisions! It could also help when cars can't go on because there's water in their path (or land in the case of boats).
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!

Honktown
Smart Inserter
Smart Inserter
Posts: 1028
Joined: Thu Oct 03, 2019 7:10 am
Contact:

Re: Detect collision with cliffs

Post by Honktown »

Pi-C wrote:
Wed Dec 25, 2019 1:44 pm
Honktown wrote:
Sun Dec 22, 2019 4:48 pm
For your case, there might be an even easier way: If it's not moving but you're supposed to be, look for stuff within a small radius that could be stopping you. Only works after it collides.
Thanks, I think I'll do that! Already thought of something along these lines. It's actually more versatile that an event or something for checking just cliff collisions! It could also help when cars can't go on because there's water in their path (or land in the case of boats).
There might be a problem. Belts can push entities. May want to check the general case, you're not moving in the direction you want to go (speed and orientation). Edge case.
Merry Christmas
I have mods! I guess!
Link

PyroFire
Filter Inserter
Filter Inserter
Posts: 356
Joined: Tue Mar 08, 2016 8:18 am
Contact:

Re: Detect collision with cliffs

Post by PyroFire »

What's wrong with the pathfinder that's built in to factorio?

https://lua-api.factorio.com/latest/Lua ... quest_path

Pi-C
Smart Inserter
Smart Inserter
Posts: 1656
Joined: Sun Oct 14, 2018 8:13 am
Contact:

Re: Detect collision with cliffs

Post by Pi-C »

PyroFire wrote:
Wed Dec 25, 2019 5:54 pm
What's wrong with the pathfinder that's built in to factorio?

https://lua-api.factorio.com/latest/Lua ... quest_path
Nothing, Autodrive does use this for pathfinding! You select a vehicle, you click somewhere on the map with your Autodrive controller, vehicle generates a path (if possible) and moves to its destination. In some situations (e.g. unarmed vehicle equipped with Enemy sensor detects enemies), the vehicle enters panic mode and is moved at top speed in the direction it was last moving. The calculated path will be ignored in this case (will have to implement repathing once there's no reason for panicking anymore), the vehicle will just move in a straight line until panic mode ends or there's an obstacle it can't pass (cliff, water etc.). Trees or rocks may stop the vehicle for a while, but will eventually be destroyed. Cliffs are different because they won't be destroyed, and cliff collisions don't seem to damage the vehicle and thus are harder to detect then collisions with normal entities that have health.
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!

pleegwat
Filter Inserter
Filter Inserter
Posts: 266
Joined: Fri May 19, 2017 7:31 pm
Contact:

Re: Detect collision with cliffs

Post by pleegwat »

Could you detect the fact the vehicle has been standing still for more than, say, a second?

PyroFire
Filter Inserter
Filter Inserter
Posts: 356
Joined: Tue Mar 08, 2016 8:18 am
Contact:

Re: Detect collision with cliffs

Post by PyroFire »

The whole panic mode thing seems a bit strange to me, but in any case.
I'm glad you've already checked the damaged event, because that was my first thought as well.

There is no reliable or "clean" method to detect this.
There are a few options, but most of them are bad.

Line intersections might work... if you could actually scan for cliffs that way (api request maybe?).
Basically you don't have a reliable way to get any opposing lines to intersect with in the first place, bringing you back to the same problem - how to detect?
Not to mention it's inaccurate, even if you had cliff lines.
You're not doing collision checks manually in lua, that'd be crazy.

find_ents_in_sphere() every tick could work too... but consider running that on 20~50 idle bots at the same time.
That's going to hurt in the frames.

And there is no on_entity_position_changed, so checking velocities every tick, while fine, would also have some complicated conditions, e.g. do we want to enter panic mode if the vehicle has been idle for a while, or only when the vehicle is already in a path, or whathaveyou.
There's more involved than it may appear, so you're back to hurting in the frames again at 20~50 bots.

Instead, why not just do a re-path with "panic mode" options? e.g. in a random-ish direction some distance forward of where the vehicle currently is, causing it to path around obstacles naturally. Combine your existing behavior, then after a short delay apply this "panic mode path". you don't get the path result instantly anyway, and you also want some delay before intelligent pathing kicks back in right?.
This should result in a seamless illusion between "panic mode" driving and "getting back on track" that may give a more fluid and natural feeling to the ai's behavior, specifically unless it was mid-turn or about to hit something, it should maintain its speed and keep moving cleanly in most cases.
Building on this, you could repath multiple times in sequence with random settings so that collisions with cliffs can either be forced (if there happens to be cliffs nearby at the time of the rng roll) or if they'll simply be avoided, if you really wanted complex behavior when it comes to making the ai drive like a madman.

Interesting to note too, the "line intersections with cliffs" happens on the C++ level so it's a lot better than anything you could do with lua - the path result will or will not include a cliff (if there happens to be one) based on given collision masks.
Plus, if the given path's next node is in a dramatically different direction from the vehicles current orientation and you've only pathed directly forward (saying the vehicle needs to turn) - there's obviously something in the way... so there's your sensor/condition/check, period.

And we're kinda talking about tweaking the behavior of an AI anyway.
Why not just give some of that pathing intelligence to this panic mode state since it apparently needs it?

Pi-C
Smart Inserter
Smart Inserter
Posts: 1656
Joined: Sun Oct 14, 2018 8:13 am
Contact:

Re: Detect collision with cliffs

Post by Pi-C »

pleegwat wrote:
Wed Dec 25, 2019 9:25 pm
Could you detect the fact the vehicle has been standing still for more than, say, a second?
Should be possible as the mod already acts at every tick. Store current position; if panic mode is on, compare position from previous and current tick; if position is the same while speed != 0, there's something in the way, so back up a bit and repath. I guess there should be no position change for several ticks to distinguish between obstacles that are really impassable (e.g. water, cliffs) and just temporary obstacles (e.g. a rock in the way) that can be destroyed by the vehicle after some time.
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!

Pi-C
Smart Inserter
Smart Inserter
Posts: 1656
Joined: Sun Oct 14, 2018 8:13 am
Contact:

Re: Detect collision with cliffs

Post by Pi-C »

That was a lot of text! Took me a while to digest and answer. :-)
PyroFire wrote:
Wed Dec 25, 2019 10:51 pm
find_ents_in_sphere() every tick could work too... but consider running that on 20~50 idle bots at the same time.
That's going to hurt in the frames.
The trouble with this mod is that it really isn't cheap UPS wise:
The biggest UPS hits are:
  • Cars actively driving because it's Lua and on-tick. Having lots of vehicles is fine, just not all pathing and driving at once...
  • Cars with a logistic sensor left parked in a logistic network zone for no reason. Remove the sensor or park cars outside the yellow zone once they've finished logistics requests.
I guess it can't be done differently.
And there is no on_entity_position_changed, so checking velocities every tick, while fine, would also have some complicated conditions, e.g. do we want to enter panic mode if the vehicle has been idle for a while, or only when the vehicle is already in a path, or whathaveyou.
There's more involved than it may appear, so you're back to hurting in the frames again at 20~50 bots.
Right, I still have to think that through. So far, something like the panic mode has been implemented for the train sensor (accelerate hard to get out of reach of approaching trains), but doesn't quite work -- I've seen stopped cars jumping to life when a train goes by and getting killed in the process. It's on my todo list, though.
Instead, why not just do a re-path with "panic mode" options? e.g. in a random-ish direction some distance forward of where the vehicle currently is, causing it to path around obstacles naturally. Combine your existing behavior, then after a short delay apply this "panic mode path". you don't get the path result instantly anyway, and you also want some delay before intelligent pathing kicks back in right?.
Not quite that easy. If the enemy sensor is present, the vehicle checks on every tick for enemies in a certain range around it. Enemies may chase it some way, so I can't know how far ahead I have to go until repathing is required.
This should result in a seamless illusion between "panic mode" driving and "getting back on track" that may give a more fluid and natural feeling to the ai's behavior, specifically unless it was mid-turn or about to hit something, it should maintain its speed and keep moving cleanly in most cases.
I'm willing to compromise, if necessary. In panic mode, things aren't rational. It seems appropriate that the vehicle goes off at top speed and bumps into things. If it hits a cliff, it may even go sporadically backwards for a while. I think it wouldn't hurt if it stopped completely to cool off a bit once it's out of danger. Currently, however, it doesn't stop but just accelerates against the cliff -- and thus can't be steered manually.
Interesting to note too, the "line intersections with cliffs" happens on the C++ level so it's a lot better than anything you could do with lua - the path result will or will not include a cliff (if there happens to be one) based on given collision masks.
An event for cliff collisions certainly would help. But I guess it couldn't be used for detecting water that prevents a car from moving (cliffs are entities, water should be tiles), right?
And we're kinda talking about tweaking the behavior of an AI anyway.
Why not just give some of that pathing intelligence to this panic mode state since it apparently needs it?
To be honest: I don't understand the code for moving vehicles completely yet. I've looked at parts of the code to fix some issues of it with one of my own mods, but it's not yet a week ago that I've been given collaborator status. So I'm taking it slow for now: getting some primitive panic mode working first, and refining it later on seems reasonable.

Anyway, thanks for the input! You've given me quite some material to think about, really appreciate it. :-)
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!

Pi-C
Smart Inserter
Smart Inserter
Posts: 1656
Joined: Sun Oct 14, 2018 8:13 am
Contact:

Re: Detect collision with cliffs

Post by Pi-C »

Honktown wrote:
Wed Dec 25, 2019 2:03 pm
There might be a problem. Belts can push entities. May want to check the general case, you're not moving in the direction you want to go (speed and orientation). Edge case.
Ooops, I didn't even think of belts yet! However, they aren't quite as bad as cliffs: If a car in autodrive mode is steered against a cliff, it will always accelerate, thus going forwards with no way to turn left or right. A belt may take you opposite to the direction you want to go, but you wouldn't collide with something, so you could steer off the belt again.
Merry Christmas
Thanks, same to you! :-)
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!

PyroFire
Filter Inserter
Filter Inserter
Posts: 356
Joined: Tue Mar 08, 2016 8:18 am
Contact:

Re: Detect collision with cliffs

Post by PyroFire »

Pi-C wrote:
Thu Dec 26, 2019 5:39 pm
Not quite that easy.

...

To be honest: I don't understand the code for moving vehicles completely yet.

...

getting some primitive panic mode working first, and refining it later on seems reasonable.
It's never that easy, and much like a changelog we're making light of what could be days or even weeks of work in a few short words, barely more than a sentence or two.
Like i said, we're talking about tweaking some ai here.

Important to note here is that paths ... Yeah they're expensive to calculate.
But only as expensive as their length.
A very short path (50 units) isn't as bad as you might think, and is likely to return near instantly.
A very long path (10,000+ units) on the other hand could take several seconds to return if not longer.
Though i have not physically tested this, it shouldn't be too hard to confirm with what you've already got.

You can achieve most of what you need to from there, including cliff and water detection by reading the resulting path (does a path of 10 units have a drastic turn in it, or the path length is 10x longer than 10 units? or can't actually reach the goal position? It's probably colliding with something.), and doing this is cheaper/faster/better than any alternative you could ever hope or dream of making out of lua.

Your last resort is making an api request if you really prefer a different method: viewforum.php?f=28

Post Reply

Return to “Modding help”