[1.1.72] rounding error with create_entity{position}

Things that has been reported already before.
Post Reply
BurninSun
Inserter
Inserter
Posts: 44
Joined: Fri Mar 16, 2018 4:54 am
Contact:

[1.1.72] rounding error with create_entity{position}

Post by BurninSun »

When calling `create_entity`, negative positions are rounded differently than positive positions. Any negative fraction less than 1/256 is rounded but positive numbers are just truncated.
Examples creating assembly machines:
`/c game.player.surface.create_entity({name="assembling-machine-1", position={x=0, y=10}})` centered at y=10.5 <-- expected
`/c game.player.surface.create_entity({name="assembling-machine-1", position={x=0, y=9.99999999}})` centered at y=9.5 <-- expected
`/c game.player.surface.create_entity({name="assembling-machine-1", position={x=0, y=-10.00390625}})` centered at y=10.5 <-- expected
`/c game.player.surface.create_entity({name="assembling-machine-1", position={x=0, y=-10.00390624}})` centered at y=9.5 <-- NOT expected

This produces the following mappings:
[2,3) --> 2.5
[1,2) --> 1.5
(-1/256, 1) --> 0.5 <-- unexpected mapping range
(-1-1/256, -1/256] --> -0.5
(-2-1/256, -1-1/256] --> -1.5
(-3-1/256, -2-1/256] --> -2.5

User avatar
boskid
Factorio Staff
Factorio Staff
Posts: 2242
Joined: Thu Dec 14, 2017 6:56 pm
Contact:

Re: [1.1.72] rounding error with create_entity{position}

Post by boskid »

This topic is not as simple to call it a bug based on what you are describing. It is simillar to 97568 because there are actually 2 layers of rounding: first layer of rounding happens when values from lua are converted to MapPosition (where coordinates are fixed points with resolution of 1/256th) and second layer is buildPosition rounding which uses provided MapPosition values. It is not possible to have the entity's build position function take a raw position with doubles to perform rounding in one step due to all layers of abstraction that are between lua and entity creation.

Most reasonable approach for me would be to tweak the MapPosition rounding in a way that the exact values are in the middle of the range that rounds to such values, but that would mean [-1/512, 1/512) would round to 0, [1/512, 3/512) would round to 1/256 for the MapPosition, and when looking at both rounding at once (MapPosition and build position function), it would look like positions from [-1/512, 1-1/512) would consistently give you the entity position of 0.5 (regardless if it would be x or y coordinate) for entities of odd tile grid size.

BurninSun
Inserter
Inserter
Posts: 44
Joined: Fri Mar 16, 2018 4:54 am
Contact:

Re: [1.1.72] rounding error with create_entity{position}

Post by BurninSun »

I don't really have a good solution. For symmetry, it would be best to round MapPosition towards 0 then split the tile giving a mapping
[1,2) -> 1.5
[0,1) -> 0.5
(-1, 0) -> -0.5
(-2, -1] -> -1.5

But that means iterating across 0 (eg, -2, -1, 0, 1, 2) would skip the mapping to -0.5. If instead the MapPosition was simply floored
[1,2) -> 1.5
[0,1) -> 0.5
[-1, 0) -> -0.5
[-2, -1) -> -1.5

Would mean someone setting a specific position of -2 would end up at -1.5 which seems odd as well.

Not sure what the best approach is.

User avatar
boskid
Factorio Staff
Factorio Staff
Posts: 2242
Joined: Thu Dec 14, 2017 6:56 pm
Contact:

Re: [1.1.72] rounding error with create_entity{position}

Post by boskid »

I am going to move this to Duplicates due to 97568 but it could also go to Not a bug (because there is no explicit guarantee that rounding of coordinates for MapPosition and build position function are equal) or Wont fix (because changes here have a really high possibility of being breaking changes which i cannot accept anymore in 1.1.x branch). Description specifies the problem as if there was only one rounding and there is cascade of 2 roundings which are independent of each other. It would be nice if you would stop using coordinates that are not multiple of 1/256th so you would not notice the first rounding, or you could use x+0.5 when iterating over integer coordinates to make sure the build position function would not be working on the threshold and deciding in the direction that does not match your expectation because of first rounding. There is always a rage quit solution i can implement, first would be to make MapPosition parsing from lua to throw an error if coordinate is not a multiple of 1/256th, second would be to abort entity creation if the given position is not at the correct build position. Both are harmful but if modders have problems with soft requirements being too soft then there will be hard requirements everywhere.

Post Reply

Return to “Duplicates”