[1.1.30] Blueprint json position inaccuracy for negative values

Bugs that are actually features.
Post Reply
jurgy
Manual Inserter
Manual Inserter
Posts: 4
Joined: Wed Feb 27, 2019 5:55 pm
Contact:

[1.1.30] Blueprint json position inaccuracy for negative values

Post by jurgy »

Hi, I'm working on some tool that handles blueprint strings/json when I noticed that Factorio handles the exact position of entities in a rather odd way.

When exporting a single 1x1 tile as blueprint (let's say a single belt) the position of the belt in the json is nice and round at the (.5, .5) mark. Similarly when exporting a 2x2 entity such as a substation their position is at the (.0, .0) mark. This all makes sense to me.

However, I was exploring some json downloaded from factorioprints when I encountered blueprints where all the positions were rounded to the nearest integer but when imported in Factorio the blueprint was loaded correctly. From this I naively assumed that for 1x1 entities everything in the interval (N.0 <= x < (N+1).0) would be centered to the that specific tile and everything lower would be offset 1 tile to the left and anything higher 1 tile to the right. (With N I mean any non-specific integer so N.0 could be 3.0 and (N+1).0 would be 4.0 in that case)

So I checked some coordinates, at first in positive direction and this assumption seemed to hold: 0.0 to 0.999 was on one tile 1.0 to 1.999 was on the tile over and 2.0 to 2.999 was yet another tile further. But then I checked negative numbers and came to the following discovery. The first negative position starts between -0.0039062 and -0.0039063 and this offset doesn't change depending on the scale x=-10000.5 and -10000.0039063 are the same tile (or column of tiles) and x=-10000.0039062 is the next tile over.

Then I checked for the y axis and the same offset appeared for negative numbers but no offset was observed for positive numbers.

I'm aware of floating point precision but I doubt that that's the case here since no positive numbers seems to be affected while negative numbers close to zero are affected the same way as large negative numbers. Furthermore the scale of the offset is way larger than most floating point precision errors are at in my experience.

I understand that this is but a small problem in a non-standard use-case of the Factorio blueprint import/export functionality but I wanted to let you guys know.

Thanks!


Data:
(Correct) Two belts on the same tile with x being positive

Code: Select all

{
    "blueprint": {
        "icons": [{
                "signal": {
                    "type": "item",
                    "name": "assembling-machine-3"
                },
                "index": 1
            }
        ],
        "entities": [{
                "entity_number": 1,
                "name": "fast-transport-belt",
                "position": {
                    "x": 10000.5,
                    "y": 0.5
                }
            }, {
                "entity_number": 2,
                "name": "fast-transport-belt",
                "position": {
                    "x": 10000.0039062,
                    "y": 0.5
                }
            }
        ],
        "item": "blueprint",
        "version": 281479273644032
    }
}

Code: Select all

0eNqdkMEKwjAQRH9FcraSprVaf0VEUl11odmWZBVLyb+7jYIFb+Y0sxneJDuqpr1D75FY7RajwlNHQdR+VAGvZNs05aEHEQoZnFouFFmXvA0BXNMiXTNnTzckyAoVJYB0hqck8ngQB8TICB9ucsOR7q4BP2VmwIsNnLG3FPrOc9ZAy1Nf3wUBdJQek7hazmotV4M4UVFaf9Hmb7TWRa0rMy+YfpIWILDv0mT4AB/eBLPNy01tNkVVlrowMb4AuvhrzQ==
(Incorrect) Two belts on the different tiles with x being negative (-10000.5 and -10000.0039062)

Code: Select all

{
    "blueprint": {
        "icons": [{
                "signal": {
                    "type": "item",
                    "name": "assembling-machine-3"
                },
                "index": 1
            }
        ],
        "entities": [{
                "entity_number": 1,
                "name": "fast-transport-belt",
                "position": {
                    "x": -10000.5,
                    "y": 0.5
                }
            }, {
                "entity_number": 2,
                "name": "fast-transport-belt",
                "position": {
                    "x": -10000.0039062,
                    "y": 0.5
                }
            }
        ],
        "item": "blueprint",
        "version": 281479273644032
    }
}

Code: Select all

0eNqdkM0KwjAQhF9FcjaSpvX3VUQk1VUXmm1JtmIpeXe3UVDwZk4zm+GbZEdVNz10AYnVbjYqPLUURe1HFfFKrslTHjoQoZDBq/lMkfPZuxjB1w3SVXt3uiGBLlWSANIZHpIo0kEcECMjvLnZDUfqfQ1hynwBLy6y5uAodm1gXUPDU1/XRgG0lB8zcXVh5CyWcjeIFZWk9pdt/2cbU27Nyn43TH/JKxDaZ20yvEOIL4TdFNV6a9flqqpMaVN6AnmKbCc=

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

Re: [1.1.30] Blueprint json position inaccuracy for negative values

Post by boskid »

Thanks for the report. I am not considering this to be a bug.

All the internal position coordinates are internally stored as a fixed point value with an increment of 1/256th (= 0.00390625). Rounding towards -Inf for entities in blueprint makes sense due to blueprint logic, and rounding -10000.0039062 towards -10000 makes sense due to map position load from string conversion logic (which rounds towards zero).

Only thing that i may look into is the fact that the exact values (while as string) appear to be really close to the rounding transitions. Maybe it would be better if values from 0.99804 up to 1.00195 would all be loading as position coordinate of 1 (= 256 / 256), but then your issue would shift onto the other end: 10000.999 (=2560255.744 / 256) would be loaded as 10001.000 (= 2560256 / 256)

jurgy
Manual Inserter
Manual Inserter
Posts: 4
Joined: Wed Feb 27, 2019 5:55 pm
Contact:

Re: [1.1.30] Blueprint json position inaccuracy for negative values

Post by jurgy »

Thanks for your response. The "pixels" being 1/256 wide does make sense!

I do still wonder though why the inaccuracy only shows up for negative numbers though. This makes the center tile 1/256th bigger than the rest.

I've created a blueprint of two rows of belts where the top row is as much to the right as possible and the bottom row is as much to the left as possible.

(Python dictionary, not json this time, so I can put in calculations instead of the exact values)

Code: Select all

 d = 
    {
        'blueprint': {'icons': [{'signal': {'type': 'item', 'name': 'assembling-machine-3'}, 'index': 1}], 'entities': [
            {'entity_number': 1, 'name': 'fast-transport-belt', 'position': {'x':  2         - 0.000000001, 'y': 0.5}},
            {'entity_number': 2, 'name': 'fast-transport-belt', 'position': {'x':  1                      , 'y': 1.5}},

            {'entity_number': 3, 'name': 'fast-transport-belt', 'position': {'x':  1         - 0.000000001, 'y': 0.5}},
            {'entity_number': 4, 'name': 'fast-transport-belt', 'position': {'x':  0 - 1/256 + 0.000000001, 'y': 1.5}},

            {'entity_number': 5, 'name': 'fast-transport-belt', 'position': {'x':  0 - 1/256              , 'y': 0.5}},
            {'entity_number': 6, 'name': 'fast-transport-belt', 'position': {'x': -1 - 1/256 + 0.000000001, 'y': 1.5}}],
    'item': 'blueprint', 'version': 281479273644032}}

Code: Select all

0eNql0lFLxDAMAOC/cvTZjq7tdu7+ioh0ZzwLazbanDhG/7tZVRQUJrNPSRq+5CGL6IcrTNEjidNhEf48YuLobhHJX9ANpUrzBBwITxDEzUGgCyV3KUHoB48XGdz52SNIIzI3eHyEV+6o8z1ngOTJw4dbsvkBr6GHuPZ8A59cIknRYZrGSLKHgdZ505gYGLEsU9yq+3z8PXNFVU3myT95vYffQs0OVP19Z7uDl6pSynSq1XbTb/7lN1t8u4evf19/vZ9ydmx9nSoXXyCmd0Df1vbY6aNprVVG5/wGDY/daQ==
Image

And the width of each tile:

Code: Select all

> print(d["blueprint"]["entities"][0]["position"]["x"] - d["blueprint"]["entities"][1]["position"]["x"])
> print(d["blueprint"]["entities"][2]["position"]["x"] - d["blueprint"]["entities"][3]["position"]["x"])
> print(d["blueprint"]["entities"][4]["position"]["x"] - d["blueprint"]["entities"][5]["position"]["x"])
0.9999999989999999
1.003906248
0.9999999989999999

Post Reply

Return to “Not a bug”