Disallow mining tile from under an entity

Place to ask discuss and request the modding support of Factorio. Don't request mods here.
Post Reply
User avatar
Gergely
Filter Inserter
Filter Inserter
Posts: 595
Joined: Sun Apr 10, 2016 8:31 pm
Contact:

Disallow mining tile from under an entity

Post by Gergely »

If I use a mod like the Platform mod that adds removable landfill tiles, I can kill players and destroy vehicles if I mine a platform tile from under it. Currently the modding interface offers no solution to this problem.

I request the following:
  • A generic method to forbid mining tiles if the tile underneath them would collide with the entities on the tile. This could be a flag on the tile prototype or something different.
Last edited by Gergely on Mon Aug 13, 2018 8:42 am, edited 1 time in total.

Rseding91
Factorio Staff
Factorio Staff
Posts: 13175
Joined: Wed Jun 11, 2014 5:23 am
Contact:

Re: Disallow mining tile from under an entity

Post by Rseding91 »

If I can find a way to implement this that doesn't negatively impact performance in the base game I'll add i t.
If you want to get ahold of me I'm almost always on Discord.

mrvn
Smart Inserter
Smart Inserter
Posts: 5682
Joined: Mon Sep 05, 2016 9:10 am
Contact:

Re: Disallow mining tile from under an entity

Post by mrvn »

Isn't that similar to mining rails when a train in on them?

User avatar
Gergely
Filter Inserter
Filter Inserter
Posts: 595
Joined: Sun Apr 10, 2016 8:31 pm
Contact:

Re: Disallow mining tile from under an entity

Post by Gergely »

mrvn wrote:Isn't that similar to mining rails when a train in on them?
No, rails are entities and they reference the train that is on them.

Tiles however don't know if there is an entity on top of them while they are being removed. The entities on mined tiles die as soon as they are ticked when it's already too late to undo the tile removal.

In other words, rails are more self-conscious.

So that's why implementing this can potentially impact the performance. When removing a single tile, all entities inside the chunk and neighboring chunks might have to be checked.

mrvn
Smart Inserter
Smart Inserter
Posts: 5682
Joined: Mon Sep 05, 2016 9:10 am
Contact:

Re: Disallow mining tile from under an entity

Post by mrvn »

Gergely wrote:
Tue Aug 28, 2018 8:51 pm
mrvn wrote:Isn't that similar to mining rails when a train in on them?
No, rails are entities and they reference the train that is on them.

Tiles however don't know if there is an entity on top of them while they are being removed. The entities on mined tiles die as soon as they are ticked when it's already too late to undo the tile removal.

In other words, rails are more self-conscious.

So that's why implementing this can potentially impact the performance. When removing a single tile, all entities inside the chunk and neighboring chunks might have to be checked.
Do I understand this right? Every tick every entity checks the tiles it stands on and if they conflict with what the entity requires then the entity dies?
That sounds like a horrible design.

Rseding91
Factorio Staff
Factorio Staff
Posts: 13175
Joined: Wed Jun 11, 2014 5:23 am
Contact:

Re: Disallow mining tile from under an entity

Post by Rseding91 »

mrvn wrote:
Mon Sep 17, 2018 7:36 am
Do I understand this right? Every tick every entity checks the tiles it stands on and if they conflict with what the entity requires then the entity dies?
That sounds like a horrible design.
No.

When a tile is changed the game scans the entities on the tile and destroys any that collide with the new tile.

The problem with "don't mine if any collide" is it has to then scan every time the mining operation starts in addition to every time it finishes.
If you want to get ahold of me I'm almost always on Discord.

mrvn
Smart Inserter
Smart Inserter
Posts: 5682
Joined: Mon Sep 05, 2016 9:10 am
Contact:

Re: Disallow mining tile from under an entity

Post by mrvn »

Rseding91 wrote:
Mon Sep 17, 2018 10:23 am
mrvn wrote:
Mon Sep 17, 2018 7:36 am
Do I understand this right? Every tick every entity checks the tiles it stands on and if they conflict with what the entity requires then the entity dies?
That sounds like a horrible design.
No.

When a tile is changed the game scans the entities on the tile and destroys any that collide with the new tile.

The problem with "don't mine if any collide" is it has to then scan every time the mining operation starts in addition to every time it finishes.
Huh? Why?

You already have the code that scans entities and destroys them. But before you destroy the entity you add:

Code: Select all

if (dont_destroy) return false; // mining would destroy building
Seems like a trivial change. No need to scan twice. Trying to mine tiles that destroy entities would simply fail. Like mining a chest when you don't have enough space for the contents.

Note: You can't reliably scan before mining starts because a second player might place something while the player mines and then mining should fail (at the end). So you might as well have it fail at the end in all cases if scanning takes too much time.

Rseding91
Factorio Staff
Factorio Staff
Posts: 13175
Joined: Wed Jun 11, 2014 5:23 am
Contact:

Re: Disallow mining tile from under an entity

Post by Rseding91 »

Mining a tile can destroy multiple entities which means it can't just "stop mining the tile if it found 1 entity while destroying that can't be destroyed" since it could have destroyed others already.
If you want to get ahold of me I'm almost always on Discord.

User avatar
Gergely
Filter Inserter
Filter Inserter
Posts: 595
Joined: Sun Apr 10, 2016 8:31 pm
Contact:

Re: Disallow mining tile from under an entity

Post by Gergely »

I have a headache imagining how ... slick that might be. Would be a shame to ruin it.
Here's what I have gathered so far. Correct me if I'm wrong:
  • The destroy operation for entities is a 1 step operation which means after a single method call, the entity forcefully ceases to exist no matter which part of the main loop the method was called from.
  • The entities are in a one way only linked list (and likely are the links themselves) which means you can only destroy them during an iteration of the list.
  • You figured iterating the list twice instead of once would largely impact the performance of bots that place modded water fill. I don't yet know how. Would that really impact the performance so much that it is no longer worth this feature?
I know this isn't simple, but deconstructing tiles are the most effective way to kill players (even invulnerable players!!!) in modded Factorio.

mrvn
Smart Inserter
Smart Inserter
Posts: 5682
Joined: Mon Sep 05, 2016 9:10 am
Contact:

Re: Disallow mining tile from under an entity

Post by mrvn »

Rseding91 wrote:
Wed Sep 19, 2018 7:01 am
Mining a tile can destroy multiple entities which means it can't just "stop mining the tile if it found 1 entity while destroying that can't be destroyed" since it could have destroyed others already.
I thought the idea was to not allow mining if it would destroy entities. So the first one you find that must be destroyed you stop and the mining fails.
So there would never be any "destroyed others already" case.

But even your case seems rather simple. Assuming entities overlap and some can be destroyed and other not. You first scan the area for any entities that may be destroyed and add them to a list. If you don't find any conflicts in the area the mining will succeed and you destroy all the entities in the list.

It means having 2 loops but the second will only loop over entities that need to be destroyed, not over an area that could cover multiple chunks. The only real extra cost is allocating and building the list. But in all but exceptional cases the list would only have at most one element. Generally entities do not overlap and players tend to not alter tiles destructively below entities except by accident.

User avatar
Gergely
Filter Inserter
Filter Inserter
Posts: 595
Joined: Sun Apr 10, 2016 8:31 pm
Contact:

Re: Disallow mining tile from under an entity

Post by Gergely »

mrvn wrote:
Thu Sep 20, 2018 9:42 am
But even your case seems rather simple. Assuming entities overlap and some can be destroyed and other not. You first scan the area for any entities that may be destroyed and add them to a list. If you don't find any conflicts in the area the mining will succeed and you destroy all the entities in the list.
Ummm....

How exactly do you imagine "adding them to a list" would work memory wise if this is supposed to be extremely optimized?

mrvn
Smart Inserter
Smart Inserter
Posts: 5682
Joined: Mon Sep 05, 2016 9:10 am
Contact:

Re: Disallow mining tile from under an entity

Post by mrvn »

Gergely wrote:
Fri Sep 21, 2018 8:29 am
mrvn wrote:
Thu Sep 20, 2018 9:42 am
But even your case seems rather simple. Assuming entities overlap and some can be destroyed and other not. You first scan the area for any entities that may be destroyed and add them to a list. If you don't find any conflicts in the area the mining will succeed and you destroy all the entities in the list.
Ummm....

How exactly do you imagine "adding them to a list" would work memory wise if this is supposed to be extremely optimized?

Code: Select all

std::vector to_be_destroyed(4);
for(entities_in_area) {
  if (should_be_destroyed(entity))
    to_be_destroyed.push_back(entity);
}
As said the normal case would be at most 1 entity since they normally do not overlap. The vector starts of with space for 4. If more than 4 entities overlap the tile and need to be destroyed then the std::vector will allocate memory as needed in amortized O(1) cost per entity.

Note: I got what you mend by entities that can be destroyed and ones that must not, I think. Did you mean that there might be decorations in the way as well as actual player placed entities? Decoration would be fine to destroy but player based entities would not.

User avatar
Gergely
Filter Inserter
Filter Inserter
Posts: 595
Joined: Sun Apr 10, 2016 8:31 pm
Contact:

Re: Disallow mining tile from under an entity

Post by Gergely »

mrvn wrote:
Tue Sep 25, 2018 8:17 am

Code: Select all

std::vector to_be_destroyed(4);
for(entities_in_area) {
  if (should_be_destroyed(entity))
    to_be_destroyed.push_back(entity);
}
As said the normal case would be at most 1 entity since they normally do not overlap. The vector starts of with space for 4. If more than 4 entities overlap the tile and need to be destroyed then the std::vector will allocate memory as needed in amortized O(1) cost per entity.
Aaaaaoooohhh...
Image
*Pfsshh*

Are you serious right now? :shock: :shock: :shock: Or am I just an idiot for not having thought of that?
Either way, building that list takes up at least n+n-1 "space" in memory where n is the number of entities to be destroyed. (Unless n ≤ 4 of course.) Let Rseding91 be the judge of that.
Last edited by Gergely on Fri Dec 14, 2018 9:52 pm, edited 1 time in total.

mrvn
Smart Inserter
Smart Inserter
Posts: 5682
Joined: Mon Sep 05, 2016 9:10 am
Contact:

Re: Disallow mining tile from under an entity

Post by mrvn »

An std::vector<Entity*> takes c+8*n space where c is some constant like 32 and n is the number of entity pointers. I considered using a linked list or something that is easier to extend but that would require a next and data pointer, so 16*n, and one allocation per item. And I really don't expect there to be any entities in the majority of cases and a std::vector will do fewer calls to new().

I imagine a worst case could be like this:
- the tile has some decoration
- there is an explosion crater (does that exclude decorations? Is that a decoration?)
- some scrap pieces from an explosion are lying around
- there are 4 items on the tile
- there is a building encroaching that tile

Even then that should be a trivial overhead.

@rseeding91: What's your take on this? Does that make sense?

User avatar
Gergely
Filter Inserter
Filter Inserter
Posts: 595
Joined: Sun Apr 10, 2016 8:31 pm
Contact:

Re: Disallow mining tile from under an entity

Post by Gergely »

Careful!

std:vector needs to re-allocate it's array a lot during which it takes up almost double the space.
This might make linked list a better choice because it would be faster, though less efficient on memory.

mrvn
Smart Inserter
Smart Inserter
Posts: 5682
Joined: Mon Sep 05, 2016 9:10 am
Contact:

Re: Disallow mining tile from under an entity

Post by mrvn »

Gergely wrote:
Sat Sep 29, 2018 8:10 pm
Careful!

std:vector needs to re-allocate it's array a lot during which it takes up almost double the space.
This might make linked list a better choice because it would be faster, though less efficient on memory.
Note the part about the vector/list being small and pre-allocating it to fit 99.99% of all cases.

User avatar
Gergely
Filter Inserter
Filter Inserter
Posts: 595
Joined: Sun Apr 10, 2016 8:31 pm
Contact:

Re: Disallow mining tile from under an entity

Post by Gergely »

I wonder if it's possible to do now...

Post Reply

Return to “Modding interface requests”