Non-square non-1x1 inserter giving constant error
Non-square non-1x1 inserter giving constant error
I am trying to make an entity of type inserter which has a size of 3x6, and no matter what I do, I cannot get the game to load, as it always halts with an "invalid insert vector, not a safe distance from the tile edge" error.
No matter what positions I pick, I get this error. I have tried the originals (inherited from the stack inserter), those values offset by 1, 1.5, and 3 (to compensate for the increased hitbox size), and even ridiculous like {0, 2000}. Nothing has worked.
What exactly raises this error? What is it telling me, and what can I do to fix it (not just some magic values, but how are such 'safe' values derived)?
No matter what positions I pick, I get this error. I have tried the originals (inherited from the stack inserter), those values offset by 1, 1.5, and 3 (to compensate for the increased hitbox size), and even ridiculous like {0, 2000}. Nothing has worked.
What exactly raises this error? What is it telling me, and what can I do to fix it (not just some magic values, but how are such 'safe' values derived)?
- eradicator
- Smart Inserter
- Posts: 5206
- Joined: Tue Jul 12, 2016 9:03 am
- Contact:
Re: Non-square non-1x1 inserter giving constant error
They're probably derived similar to fluid boxes (see this post).
I find those error messages pretty frustrating myself though.
I find those error messages pretty frustrating myself though.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: ζ₯ζ¬θͺ, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Mod support languages: ζ₯ζ¬θͺ, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Re: Non-square non-1x1 inserter giving constant error
I suspected this, as I have run into that error myself, back when designing the geothermal wells.eradicator wrote:They're probably derived similar to fluid boxes (see this post).
I find those error messages pretty frustrating myself though.
However, among the values I tried were ones that should meet that criterion, like {0, -1.6} or {0, -2} for an entity of collision box {{-2.9, -1.4}, {2.9, 1.4}}.
EDIT:
OK, WTF: I tried rotating the collision and selection boxes 90 degrees, as a random test, and now it loads. But the insert vector is inside the collision box! How is this acceptable while its 90-degree counterpart is not?! And why do vanilla ones - which are NOT inside the box - work?
Also, rotation is broken - I hit R when holding the item, but when I place a new entity, its collision box is not placed in a rotated state. Its insert vectors are, (and now in line with what I wanted), but the collision box remains "aligned to Y axis". Likewise if I rotate the insert vector in the prototype but leave the collision box unrotated:
- eradicator
- Smart Inserter
- Posts: 5206
- Joined: Tue Jul 12, 2016 9:03 am
- Contact:
Re: Non-square non-1x1 inserter giving constant error
Non-square entities are generally fiddly, and if you want an entity that's rotateable 4 ways after being placed they're a straight no-go. They can only rotate 2-way (i.e. flip direction). And ofc the vectors are box sensitive. Best guess: inserters don't have any code for non-square boxes. Best to ask someone (rsed?) on irc i guess.
I remember there was a bug report/fix about a non-square tank but can't find it right now. I found a topic concerning assemblers viewtopic.php?t=53310 which sounds like it supports my theory that every entity needs special code before it can handle non-square boxes.
I remember there was a bug report/fix about a non-square tank but can't find it right now. I found a topic concerning assemblers viewtopic.php?t=53310 which sounds like it supports my theory that every entity needs special code before it can handle non-square boxes.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: ζ₯ζ¬θͺ, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Mod support languages: ζ₯ζ¬θͺ, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Re: Non-square non-1x1 inserter giving constant error
Insert positions must not be on tile boundaries, i.e. having final coordinates that are integers or close to integers. (I've found >=0.2 and <=0.8 to be safest.)Reika wrote:However, among the values I tried were ones that should meet that criterion, like {0, -1.6} or {0, -2} for an entity of collision box {{-2.9, -1.4}, {2.9, 1.4}}.
For this example, the collision box has even size in the X direction, and odd size in the Y direction, so the center of the entity will be something like (0, 0.5). Adding the insert vector to this, we get (0, -1.1), and (0, -1.5). These are both invalid in the X direction. It's unclear to the engine whether dropped items should be inserted into tile (0,-1) or (-1, -1).
Vanilla inserters are 1x1, giving them a conceptual center of (0.5, 0.5) relative to the tile grid, and integer pickup/drop positions are always safely within the bounds of a tile.
Being inside/outside the collision box is not important, as long as the drop_position is clearly inside a tile, not near a tile boundary.Reika wrote:EDIT:
OK, WTF: I tried rotating the collision and selection boxes 90 degrees, as a random test, and now it loads. But the insert vector is inside the collision box! How is this acceptable while its 90-degree counterpart is not?! And why do vanilla ones - which are NOT inside the box - work?
Rotating the collision box changes the conceptual center of the entity to (0.5, 0). If you did not change the drop_position, we now have a sum drop position of:
(0.5, -1.1) or (0.5, -1.5), which do not contain integer values on either axis, and are thus valid.
From the screenshots, it looks like you're trying to make a train unloader with inserters, possibly inspired by Miniloader? I ran into very similar problems tweaking drop positions to put items into the different lanes of a belt.
Miniloader β UPS-friendly 1x1 loaders
Bulk Rail Loaders β Rapid train loading and unloading
Beltlayer & Pipelayer β Route items and fluids freely underground
Bulk Rail Loaders β Rapid train loading and unloading
Beltlayer & Pipelayer β Route items and fluids freely underground
- eradicator
- Smart Inserter
- Posts: 5206
- Joined: Tue Jul 12, 2016 9:03 am
- Contact:
Re: Non-square non-1x1 inserter giving constant error
@Therax:
Do you have any "proof"/anectodes that that "conceptual" center of entities is relevant to vectors? I assumed that entities are always "centered" on 0,0 of their own collision box and thus the vectors should be based on that and not on if the game places them on a tile boundary or not?
(Not saying you're wrong. I'm just struggling with that s*** myself and want to understand it better...)
Do you have any "proof"/anectodes that that "conceptual" center of entities is relevant to vectors? I assumed that entities are always "centered" on 0,0 of their own collision box and thus the vectors should be based on that and not on if the game places them on a tile boundary or not?
(Not saying you're wrong. I'm just struggling with that s*** myself and want to understand it better...)
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: ζ₯ζ¬θͺ, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Mod support languages: ζ₯ζ¬θͺ, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Re: Non-square non-1x1 inserter giving constant error
Maybe you can glean some insight from this:eradicator wrote:@Therax:
Do you have any "proof"/anectodes that that "conceptual" center of entities is relevant to vectors? I assumed that entities are always "centered" on 0,0 of their own collision box and thus the vectors should be based on that and not on if the game places them on a tile boundary or not?
(Not saying you're wrong. I'm just struggling with that s*** myself and want to understand it better...)
Code: Select all
bool InserterPrototype::isPickupDropoffPositionValid(Vector checkVector)
{
double intPart;
float intPartFloat;
checkVector.dx = modff(modf(modf(checkVector.dx, &intPart) + double(1.0), &intPart), &intPartFloat);
checkVector.dy = modff(modf(modf(checkVector.dy, &intPart) + double(1.0), &intPart), &intPartFloat);
return !(checkVector.dx <= ItemEntityPrototype::size.getDouble() + 0.01 ||
checkVector.dy <= ItemEntityPrototype::size.getDouble() + 0.01 ||
checkVector.dx >= 1 - ItemEntityPrototype::size.getDouble() - 0.01 ||
checkVector.dy >= 1 - ItemEntityPrototype::size.getDouble() - 0.01);
}
Re: Non-square non-1x1 inserter giving constant error
Anecdotal evidence: Reika rotated the collision_box of an entity without changing the vectors, and it went from non-working to working.eradicator wrote:@Therax:
Do you have any "proof"/anectodes that that "conceptual" center of entities is relevant to vectors? I assumed that entities are always "centered" on 0,0 of their own collision box and thus the vectors should be based on that and not on if the game places them on a tile boundary or not?
(Not saying you're wrong. I'm just struggling with that s*** myself and want to understand it better...)
I'm assuming that collision boxes are centered around 0,0, which I believe is true for all vanilla entities and followed by most mod authors. I've never tried to make a collision box that wasn't centered on 0,0, so I can't say what the behavior might be in that case. When I say "conceptual center", all I'm referring to is whether the center of an entity, its "position", lies on a tile boundary or not.
The "position" of an entity is the center of the collision box, but the size of the collision box affects where "position" lies in relation to the tile grid. Check "position" of a 1x1 entity (inserter), or a 3x3 entity (storage-tank), and you'll always find that the position has the form (XX.5, YY.5). Do the same for an entity with an even dimension, like a pump or a decider combinator (1x2), and you'll find that the position is always (XX.0, YY.5) or (XX.5, YY.0), depending on its rotation.
Do the same for a 2x2 entity like a straight-rail or a train-stop, and the position is always (XX.0, YY.0), because the center of the entity is exactly the center of 4 tiles, on a "corner" of the tile grid.
Put another way, Factorio's coordinate system is anchored at the top-left corner of each tile, so tile boundaries are integer coordinates, while a 1x1 entity aligned with the grid has its position in the center of a tile, at (0.5, 0.5) relative to the top-left corner of its tile.
Last edited by Therax on Tue Jan 16, 2018 9:34 pm, edited 1 time in total.
Miniloader β UPS-friendly 1x1 loaders
Bulk Rail Loaders β Rapid train loading and unloading
Beltlayer & Pipelayer β Route items and fluids freely underground
Bulk Rail Loaders β Rapid train loading and unloading
Beltlayer & Pipelayer β Route items and fluids freely underground
Re: Non-square non-1x1 inserter giving constant error
Thanks Klonan!Klonan wrote:Maybe you can glean some insight from this:
Code: Select all
bool InserterPrototype::isPickupDropoffPositionValid(Vector checkVector) { double intPart; float intPartFloat; checkVector.dx = modff(modf(modf(checkVector.dx, &intPart) + double(1.0), &intPart), &intPartFloat); checkVector.dy = modff(modf(modf(checkVector.dy, &intPart) + double(1.0), &intPart), &intPartFloat); return !(checkVector.dx <= ItemEntityPrototype::size.getDouble() + 0.01 || checkVector.dy <= ItemEntityPrototype::size.getDouble() + 0.01 || checkVector.dx >= 1 - ItemEntityPrototype::size.getDouble() - 0.01 || checkVector.dy >= 1 - ItemEntityPrototype::size.getDouble() - 0.01); }
So taking "s" as the size of the "item-on-ground" entity (plus a floating-point rounding-compensation factor of 0.01), it takes the fractional part of both x and y of checkVector and makes sure they're in the range s <= fractional_part <= 1-s. The addition of 1.0 ensures that fractional_part always ends up with a positive value in the range 0 <= x < 1.
I'm fairly sure that checkVector is simply position + drop_position. What eradicator and I are discussing is how tile alignment determines the inserter's position from its collision_box.
Miniloader β UPS-friendly 1x1 loaders
Bulk Rail Loaders β Rapid train loading and unloading
Beltlayer & Pipelayer β Route items and fluids freely underground
Bulk Rail Loaders β Rapid train loading and unloading
Beltlayer & Pipelayer β Route items and fluids freely underground
- eradicator
- Smart Inserter
- Posts: 5206
- Joined: Tue Jul 12, 2016 9:03 am
- Contact:
Re: Non-square non-1x1 inserter giving constant error
Not really. You misunderstood the question. It looked like you were calculating the correct vector values off the map position of an entity whereas i assume that the map position should be (more or less) irrelevant. Thinking about it the map position has to be relevant to prevent dropping on tile borders.... I'm farily sure i know how the positioning works though (see my description here).Therax wrote:What eradicator and I are discussing is how tile alignment determines the inserter's position from its collision_box.
@Klonan:
Thanks for the snippet. I have to admit i have no c experience... but comparing it with @Theraxes explanation (thanks for that too) i think i get it now. A vector is invalid if it would put an item-on-the-ground so close to the tile border that the items collision box would overlap with the tile border. It also doesn't seem to consider the collision box at all?
@Therax:
I always thought of the 0.01 as more of a collision-prevention so things directly adjacent things don't collide. I.e. two lines [0,1] and [1,2] collide at the point 1, but two lines [0,0.99] and [1.01,2] don't collide.
So that would mean a valid vector for a 6x3 entity should be...eer, {0,3.5} or {0.5,2} for pickup and {0,3.7} or {0.5,2.2} for insert? Time for @Reika to do some more tests
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: ζ₯ζ¬θͺ, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Mod support languages: ζ₯ζ¬θͺ, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Re: Non-square non-1x1 inserter giving constant error
Because of these and other problems, I ended up scrapping the entire entity, at least for now.eradicator wrote:Time for @Reika to do some more tests
Re: Non-square non-1x1 inserter giving constant error
Seems like having certain prototypes completely unrelated to the inserter (e.g. data.raw.item-entity) with incorrect collision boxes also cause this error.
Weird.
Weird.
Re: Non-square non-1x1 inserter giving constant error
Not that weird. As discussed:
Changing the size of the item-on-ground entity changes the math of how close to the edge of a tile an inserter's drop position is allowed to be.Therax wrote: βTue Jan 16, 2018 9:26 pmSo taking "s" as the size of the "item-on-ground" entity (plus a floating-point rounding-compensation factor of 0.01), it takes the fractional part of both x and y of checkVector and makes sure they're in the range s <= fractional_part <= 1-s. The addition of 1.0 ensures that fractional_part always ends up with a positive value in the range 0 <= x < 1.
Miniloader β UPS-friendly 1x1 loaders
Bulk Rail Loaders β Rapid train loading and unloading
Beltlayer & Pipelayer β Route items and fluids freely underground
Bulk Rail Loaders β Rapid train loading and unloading
Beltlayer & Pipelayer β Route items and fluids freely underground