Disclaimer
I could be wrong in some of my assumptions here, but this is based on what I've gathered from forums and API docs. Please correct me where I'm wrong, thoughTLDR
Polling expensive.Collision cheap.
Detect stuff via special collision layer or special mask, that doesn't affect/impact/block anything, only detects and emits an event. Doesn't block movement or placing. Only notifies.
LR
My assumption is that collision check is less expensive (UPS-wise) than polling, especially if we get into hundreds or thousands of polls every tick.Mines use polling to detect nearby enemies (even if it's once every 20 ticks, it's still polling. Unnecessary (often) polling. Avoidable polling).
Turrets use polling to detect nearby enemies (even if there are no more biters left to kill. Like, at all. Turrets will still be polling like crazy).
Gates use polling to detect incoming entities.
Bots use scheduled checks "are we there yet?" that fire with increasing frequency the closer they are to their target (if I recall corresponding FFF post correctly).
Instead of polling, add a flag to collision layer (or introduce a new type of layer, or add a flag to collision mask definition) that would not block pathfinding, would not block movement, would not block placing, would not block anything, zero impact whatsoever - it would only do one thing and one thing only: trigger an event(*).
That way mines won't have to poll: biter pathfinding ignores trigger layer, biter runs over a mine, biter collides with trigger mask, mine explodes.
Turret doesn't have to scan all the time - make trigger mask slightly larger (say, 20% larger) that targeting range (mask is rectangular, targeting is circular), and activate target scanning only when something collides with turret's trigger mask.
Same with gates. Even if the player/car/train is never coming to this station, gate will still be polling. Why? With trigger mask you don't have to poll if there is an incoming train nearby, it will tell you about it when it's close enough. Or maybe just make gate trigger mask large enough to account for fast entities, and only activate polling when an entity is within the gate's trigger mask - like with turrets.
Same with bots. You don't have to schedule checks "are we there yet" for every bot, you just give bot a direction, speed, and wait until it collides with a trigger mask. (well, in case of drones you still probably need a safeguard check in case destination got removed midflight, so drone doesn't overshoot too far).
And, most importantly, it will finally allow me to build a scalable, low-impact, fully event-based (instead of poll-based) stateless logistic delivery system, where delivery bots are made of tiny cars controlled entirely by traffic signs, have no state (no source, no destination, no schedule, no "are we there yet"), and "read" the traffic signs when they "collide" with them instead of having to poll next tile every tick
----
(*) trigger an event -- at minimum, trigger it once when two trigger masks collide for the first time.
Though ideally, there would be 3 events:
1) two masks collide for the first time
2) two masks that were previously intersecting are no longer intersected (Elvis has left the building!).
3) two or more masks are currently intersecting (triggered every N ticks, just like `on_tick` and `on_nth_tick`)
Additionally/optionally, a handy shortcut method could be added to an entity/object, a shortcut to/similar to `surface.find_entity/find_entities/find_entities_filtered` - "is there anything colliding with my trigger mask right now?"
----
That's it. Thanks for reading


