[0.16.36] find_entities_filtered misses straight rail by pos

Place to get help with not working mods / modding interface.
Post Reply
sparr
Smart Inserter
Smart Inserter
Posts: 1327
Joined: Fri Feb 14, 2014 5:52 pm
Contact:

[0.16.36] find_entities_filtered misses straight rail by pos

Post by sparr »

Code: Select all

game.surfaces.nauvis.create_entity{name="straight-rail",position={x=1,y=1},force="player",direction=7}
game.print(#game.surfaces.nauvis.find_entities_filtered{name="straight-rail",position={x=1,y=1}})
game.print(game.surfaces.nauvis.find_entities_filtered{name="straight-rail",position={x=0.9,y=0.9}}[1].position)
This creates a rail "at" {1,1}, pointing northeast/southwest, occupying the northwest almost-half of the box {{0,0},{2,2}}. Trying to find entities with position {1,1} finds nothing, but searching just a bit to the northwest of that works.

I think this is a bug because I expect the position of find{position} results to be the position I searched for, and I expect it to find things created at the position in question.

User avatar
Klonan
Factorio Staff
Factorio Staff
Posts: 5150
Joined: Sun Jan 11, 2015 2:09 pm
Contact:

Re: [0.16.36] find_entities_filtered misses straight rail by pos

Post by Klonan »

sparr wrote:

Code: Select all

game.surfaces.nauvis.create_entity{name="straight-rail",position={x=1,y=1},force="player",direction=7}
game.print(#game.surfaces.nauvis.find_entities_filtered{name="straight-rail",position={x=1,y=1}})
game.print(game.surfaces.nauvis.find_entities_filtered{name="straight-rail",position={x=0.9,y=0.9}}[1].position)
This creates a rail "at" {1,1}, pointing northeast/southwest, occupying the northwest almost-half of the box {{0,0},{2,2}}. Trying to find entities with position {1,1} finds nothing, but searching just a bit to the northwest of that works.

I think this is a bug because I expect the position of find{position} results to be the position I searched for, and I expect it to find things created at the position in question.
Rails are aligned on a 2x2 grid, are you sure the positions it is created at is actually (1,1)?

I would guess it is at (0,0) or (2,2)

sparr
Smart Inserter
Smart Inserter
Posts: 1327
Joined: Fri Feb 14, 2014 5:52 pm
Contact:

Re: [0.16.36] find_entities_filtered misses straight rail by pos

Post by sparr »

If you try to create a rail at {0,0} you get a rail at {1,1}. {1,1} is the center of the rail grid tile that spans the bounding box {{0,0},{2,2}}, and is the .position of any straight rails occupying that tile.

sparr
Smart Inserter
Smart Inserter
Posts: 1327
Joined: Fri Feb 14, 2014 5:52 pm
Contact:

Re: [0.16.36] find_entities_filtered misses straight rail by pos

Post by sparr »

The problem here, per Bilka on Discord, is that .find_entities_filtered applies to collision boxes, and the collision box for a diagonal straight rail with .position {1,1} does not actually include {1,1}.

chrisgbk
Long Handed Inserter
Long Handed Inserter
Posts: 92
Joined: Mon Jan 02, 2017 4:31 am
Contact:

Re: [0.16.36] find_entities_filtered misses straight rail by pos

Post by chrisgbk »

sparr wrote:The problem here, per Bilka on Discord, is that .find_entities_filtered applies to collision boxes, and the collision box for a diagonal straight rail with .position {1,1} does not actually include {1,1}.
I believe your understanding of tile coordinates is incorrect. Bilka is correct with the reason, but the underlying issue isn't in the game.

The center of map tiles is always at a 0.5 offset, and placement logic when placed at integer coordinates is to align to the grid, then find the center of the tile. (edit: unless the offgrid flag is applied, thanks Nexela)

As an example, creating a stone-wall at {0,0} and then searching {0,0} for that entity will not find it, because the entity was actually placed centered at {0.5, 0.5}. The point {0,0} is outside the bounds of the collision rect, because the width and height of the collision rect is strictly < 1.0.

Similarly, for the rail, the rail is aligned to the grid first, which makes the placement position when specified as {1,1} be translated to {0,0}, and then adjusted to the center based on direction, so it is placed centered at {0.5, 0.5} in your example which, of course, makes the point {1,1} outside of the collision rect. Turning on the tile grid and collision box debug info makes this obvious. See picture:

Image

Grid lines are whole integer coordinates. Printed position is player coordinate X, which is as close to the center to the rail as I could make it by hand.

The way the alignment to the grid is performed is by truncation, so creating a rail like that at any position from 0 <= x(or y) < 2 will result in being placed centered at 0.5. Then, from 2 <= x(or y) < 4 it will be centered at 2.5, and so on.

Note, that using different placement direction(ie: 3), the rail gets created centered around {1.5, 1.5} instead, and so on for other directions that can cause centering at {0.5, 1.5} and {1.5, 0.5}.

Only vertical and horizontal rails get centered literally at {1, 1}. I'm sure there is a relation somewhere that neatly maps the offset based on the direction.

So if you want to find all the rail in the 2x2 grid, you can either check one of 5 coordinates depending on the directions you want to search for specifically, or you can check an area that includes all the possible points.

Code: Select all

game.player.print(#game.player.surface.find_entities_filtered{name="straight-rail", area={{0.5, 0.5}, {1.5, 1.5}}})
will find all 6 possible straight rails.

Code: Select all

game.print(#game.surfaces.nauvis.find_entities_filtered{name="straight-rail",position={x=0.5,y=0.5}})
will find the top left, northeast facing rail.

Code: Select all

game.print(#game.surfaces.nauvis.find_entities_filtered{name="straight-rail",position={x=1.5,y=1.5}})
will find the bottom right, northeast facing rail.

and so on.

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

Re: [0.16.36] find_entities_filtered misses straight rail by pos

Post by Rseding91 »

I'm moving this to modding help since I've not seen anything that's a bug yet.
If you want to get ahold of me I'm almost always on Discord.

sparr
Smart Inserter
Smart Inserter
Posts: 1327
Joined: Fri Feb 14, 2014 5:52 pm
Contact:

Re: [0.16.36] find_entities_filtered misses straight rail by pos

Post by sparr »

chrisgbk wrote:
sparr wrote:The problem here, per Bilka on Discord, is that .find_entities_filtered applies to collision boxes, and the collision box for a diagonal straight rail with .position {1,1} does not actually include {1,1}.
I believe your understanding of tile coordinates is incorrect. Bilka is correct with the reason, but the underlying issue isn't in the game.

[...]

Similarly, for the rail, the rail is aligned to the grid first, which makes the placement position when specified as {1,1} be translated to {0,0}, and then adjusted to the center based on direction, so it is placed centered at {0.5, 0.5} in your example which, of course, makes the point {1,1} outside of the collision rect.
I believe you didn't bother to check the .position of the rail that you created, which the test case in my original post explicitly prints out.

One square of the rail grid spans from 0,0 to 2,2; making 1,1 the center of that grid square, and that's where rails in that square have their position set.
Last edited by sparr on Sun Apr 15, 2018 7:32 am, edited 2 times in total.

sparr
Smart Inserter
Smart Inserter
Posts: 1327
Joined: Fri Feb 14, 2014 5:52 pm
Contact:

Re: [0.16.36] find_entities_filtered misses straight rail by pos

Post by sparr »

Klonan wrote:are you sure the positions it is created at is actually (1,1)?
The test case code in my original post prints out the .position of the created rail.

sparr
Smart Inserter
Smart Inserter
Posts: 1327
Joined: Fri Feb 14, 2014 5:52 pm
Contact:

Re: [0.16.36] find_entities_filtered misses straight rail by pos

Post by sparr »

Rseding91 wrote:I'm moving this to modding help since I've not seen anything that's a bug yet.
There is at least one bug here, I'm just not sure which behavior is the bug.

When I do create_entity and specify a position I understand that the entity might not end up at that position due to grid snapping. The problem here is when the entity DOES get the position I requested for it to get, but the entity's collision box(?) doesn't cover that position. When that happens, find_entity still finds the entity based on its position attribute, but find_entities_filtered for that same position doesn't find it because of the offset collision box.

Add this to my original test case to see the disparity:

Code: Select all

game.print(game.surfaces.nauvis.find_entity("straight-rail",{x=1,y=1}).position)

chrisgbk
Long Handed Inserter
Long Handed Inserter
Posts: 92
Joined: Mon Jan 02, 2017 4:31 am
Contact:

Re: [0.16.36] find_entities_filtered misses straight rail by pos

Post by chrisgbk »

sparr wrote:
chrisgbk wrote:
sparr wrote:The problem here, per Bilka on Discord, is that .find_entities_filtered applies to collision boxes, and the collision box for a diagonal straight rail with .position {1,1} does not actually include {1,1}.
I believe your understanding of tile coordinates is incorrect. Bilka is correct with the reason, but the underlying issue isn't in the game.

[...]

Similarly, for the rail, the rail is aligned to the grid first, which makes the placement position when specified as {1,1} be translated to {0,0}, and then adjusted to the center based on direction, so it is placed centered at {0.5, 0.5} in your example which, of course, makes the point {1,1} outside of the collision rect.
I believe you didn't bother to check the .position of the rail that you created, which the test case in my original post explicitly prints out.

One square of the rail grid spans from 0,0 to 2,2; making 1,1 the center of that grid square, and that's where rails in that square have their position set.
I did check. Entities are allowed to specify a bounding box that is not centered. So the entity does exist at that point, but it's collision box does not, because the collision box isn't centered.

That might seem super weird and illogical, but it's by design, and the way to deal with it is to either search in an area, or search possible points it could be if it had certain directions.

This allows you to do things like create a wall that has a collision box in the next tile over, so it can be placed at {0.5, 0.5} but only collides at {1.5, 0.5} for example. Not very useful, but possible.

More useful is making two half entities that can share the same position, such as making rails on a 2x2 grid that are two halves aligned virtually to the 1x1 grid.

Bilka
Factorio Staff
Factorio Staff
Posts: 3132
Joined: Sat Aug 13, 2016 9:20 am
Contact:

Re: [0.16.36] find_entities_filtered misses straight rail by pos

Post by Bilka »

chrisgbk wrote:I did check. Entities are allowed to specify a bounding box that is not centered.
No, they are not allowed to specify that. EntityPrototype will throw an error if the collision_box does not include {0,0}. And if you looked at the files you would find that the straight-rail collision box is {{-0.7, -0.8}, {0.7, 0.8}}, which is rotated with the entity direction.

This rotation seems to be the issue, the rail is rotated in a way that the bounding box is not where its position is. You can try it yourself by selecting the built rail and teleporting to its position using /c game.player.teleport(game.player.selected.position)
factorio_2018-04-15_16-02-59.png
factorio_2018-04-15_16-02-59.png (350.01 KiB) Viewed 3196 times
Rather obvious that the center of the player is outside the rail collision box, so the position is outside the collision box. This is the case for all diagonal rail, the position of all 4 rails on this pictures is the same, it's the non-colliding area between them:
Image

Pretty stupid, but I doubt this will be "fixed".
I'm an admin over at https://wiki.factorio.com. Feel free to contact me if there's anything wrong (or right) with it.

sparr
Smart Inserter
Smart Inserter
Posts: 1327
Joined: Fri Feb 14, 2014 5:52 pm
Contact:

Re: [0.16.36] find_entities_filtered misses straight rail by pos

Post by sparr »

Code: Select all

find_entity(entity.name,entity.position).position
always produces entity.position, which seems right to me

Code: Select all

find_entities_filtered{name=entity.name,position=entity.position}
can, and does in this case, fail to find the entity at all. This is the behavior that I am calling a bug.

At the very least, the docs for find_entities_filtered need to be updated to specify this unexpected behavior.

Maybe the .position for diagonal straight rails needs to be the center of their collision box so that find_entity and find_entities_filtered will both find the entity.

Maybe find_entities_filtered should find based on collision box OR entity.position, so it would find the diagonal rails with their current configuration.

Maybe... some other solution.

chrisgbk
Long Handed Inserter
Long Handed Inserter
Posts: 92
Joined: Mon Jan 02, 2017 4:31 am
Contact:

Re: [0.16.36] find_entities_filtered misses straight rail by pos

Post by chrisgbk »

Bilka wrote:
chrisgbk wrote:I did check. Entities are allowed to specify a bounding box that is not centered.
No, they are not allowed to specify that. EntityPrototype will throw an error if the collision_box does not include {0,0}.
Whoops, I missed the check for {0,0} while doing testing; I was playing around with a larger entity, so I was able to offset it by a whole tile, but that still left {0,0} inside. Slightly disappointing, now my idea of on-grid micro-entities is slightly dead. Or at least significantly more complicated.
And if you looked at the files you would find that the straight-rail collision box is {{-0.7, -0.8}, {0.7, 0.8}}, which is rotated with the entity direction.
I was assuming that it was translated/rotated internally from that, as opposed to explicitly specified. I just thought it was possible to specify a box that didn't contain {0,0}, so it wasn't out of the ordinary.
sparr wrote:

Code: Select all

find_entity(entity.name,entity.position).position
always produces entity.position, which seems right to me
This should only work since 0.16.31, when find_entity was changed to have this behaviour to allow finding entities without collision boxes.
Maybe find_entities_filtered should find based on collision box OR entity.position, so it would find the diagonal rails with their current configuration.

Maybe... some other solution.
Request an API enhancement for this behaviour. Based on the previous discussion, it might offer better consistency.

This also means that currently find_entities_filtered with a position will also miss entities without coillision boxes(ie: corpses), like the pre-0.16.31 behaviour of find_entity. This might give more traction to be considered for change, or even to be considered more of a bug.

Post Reply

Return to “Modding help”