scarpet
scarpet copied to clipboard
Added block collision box library
This library provides the bounds of the solid collision box of every block and block state combination in the game, or null if a block does not have solid collision.
Bounds are provided as list of pairs of triples representing vertices of the rectangular prisms that comprise collision box if block existed at [ 0, 0, 0 ].
bounds( 'flowering_azalea' ) =>
[
[
[ 0.375, 0, 0.375 ],
[ 0.625, 0.5, 0.625 ]
] ,
[
[ 0, 0.5, 0 ],
[ 1, 1, 1 ]
]
]
bounds( 'spruce_fence_gate[open=true]' ) => null
bounds( 'stone' ) =>
[
[
[ 0, 0, 0 ],
[ 1, 1, 1 ]
]
]
Bounds function can take block(block( 67, 10, -92 )), triple([ 995, 23, -37 ]), or string('stone' or 'hopper[facing=east]'). Can also provide the following:
- boolean representing if point is in a block
insideblock( [ 106.3718, 72, -447.2 ] ) => false
- filtered and sorted list of blocks
filter_sort_direction( [ 'iron_bars', 'cake[bites=3]', 'grindstone', [ -54, 0, -199 ] ], '-x', 'min', 'exclude', 0) =>
[ iron_bars, cake, grindstone ]
- all(tm) unique collision boxes that exist
box_list() => example return value too big to fit in this margin but in 1.19.3 it's just a list of 320 blocks that's mostly cobblestone walls and chorus plants
- drawn bounds of a block with any color and fill
draw_bounds( [ -69, 1, -186 ], 100, [0xFF000FF, 0x0000FF55] ) =>

- bounds positioned at the block instead of positioned at
[0,0,0]
bounds( [5, 8, -35] ) => [ [ [0, 0, 0], [1, 1, 1] ] ]
positioned_bounds( [5, 8, -35] ) => [ [ [5, 8, -35], [6, 9, -34] ] ]
- list of blocks an entity is currently colliding with
entity_block_collision( player('rovxr') ) => [ lily_pad, comparator, piston_head ]
For a fun time, run
/script run import('collision','__entity_block_collision','__draw_bounds');__on_tick() -> ( draw_bounds( __entity_block_collision(player()), 2, [] ) )
and bump into a bunch of blocks
Todo list
- [x] make this list look better
- [x] can anything get sped up or are some functions always going to require a thread/be really slow?
- [x] ~can iron bars and fences be combined?~ would it even speed it up?
- [x] ~can candles, turtle eggs, and pickles be combined?~ again, no speed improvement
- [x] ~maybe use early
return()calls for blocks that don't have the final rotations/flips, might speed things up~ nope didn't help - [x] make sure all the debug prints and deprecated functions made it out
- [x] ~don't think draw bounds checks which dimensions to draw in~ seems good
- [x] smh potted saplings, mushrooms, fungi, roots don't work right now, regex time!
- [x] ~new 1.18 block tags might be handy~ apparently d23e577 did that
- [x] can probably remove underscores from some function names
- [ ] uhoh to detect projectiles hitting blocks do I need to know fluid shapes?
- [ ] pretty sure I can check spawning conditions of mobs with this or should that be built-in to scarpet?
- [ ] try to rewrite using classes?
- [ ] get default block directions map (
global_default_direction) dynamically withblock_state(...,'facing') - [ ] code examples
- [ ]
bounds() - [ ]
draw_bounds() - [ ]
box_list() - [ ]
filter_sort_direction() - [ ]
entity_block_collision()
- [ ]
Feedback needed
- Should this just be a default scarpet feature instead of a library?
- I need better names for some functions(this means you
filter_sort_direction()). - Honestly that whole function might need to be redone
- ~Should I add a function to offset bounds to position in world? eg
[[[102,30,-10],[103,31,-9]]]instead of[[[0,0,0],[1,1,1]]]~ 4d7eedb - Should double blocks(doors, pistons, etc) have both hitboxes or only one?
- Hopper facing relies on list order being consistent. Is this robust enough?
- ~Bamboo, pointed dripstone,~ open shulker boxes, etc have inconsistent collision boxes that can't be determined with
block_state(). I'm currently providing a solid block for shulker boxes ~and the maximum possible collision box for others.~ How should these be handled? - Is adding more boxes good enough or should the originals be stretched? eg double chest, some iron bars and fences, etc
- Better comments needed anywhere?
- Are null hitboxes for fluids and portals okay?
- I haven't manually checked every block for errors or correct hitboxes. Please complain if something is wrong.
Feel free to ask questions and provide feedback!
some block`s shape depends on who you are. such as snower snow and scaffolding.🤷♂️
random offset of bamboos like blocks is based on its x and z.
public static long hashCode(int x, int z) {
long l = (long)(x * 3129871) ^ (long)z * 116129781L;
l = l * l * 42317861L + l * 11L;
return l >> 16;
}
then, the result of the hash function is used to calc the offset.
offsetX=(((hash & 15) / 15) - 0.5) * 0.5
offsetZ=(((hash >> 8 & 15) / 15) - 0.5) * 0.5
then it is clamped between ± maxModeloffset.
dripstone`s maxModeloffset is 0.125
others is 0.25
Just for implementation, in scarpet that would be:
hashCode(x, z)->(
l = bitwise_xor(x*3129871, z*116129781);
l = l * l * 42317861 + l * 11;
bitwise_shift_right(l, 16);
)
I'm calling the function hashCode cos scarpet already has a native hash_code function which gets the has h of an object.
some block`s shape depends on who you are. such as snower snow and scaffolding.🤷♂️
~The script is meant mostly for projectiles, then players, so I'm not too concerned with getting entity states and such.~
some block`s shape depends on who you are. such as snower snow and scaffolding.🤷♂️
The script is meant mostly for projectiles, then players, so I'm not too concerned with getting entity states and such.
scaffolding s shape depends on whether your foot is higher than it, or whether you are shifting.........
some block`s shape depends on who you are. such as snower snow and scaffolding.🤷♂️
The script is meant mostly for projectiles, then players, so I'm not too concerned with getting entity states and such.
scaffolding s shape depends on whether your foot is higher than it, or whether you are shifting.........
Clarification: This is mostly meant for reference and ideally runs in a vacuum. I don't want to query entities at all. I'd prefer the result of a bounds() call to be based solely on block state and nothing more, mainly for consistency.
random offset of bamboos like blocks is based on its x and z.
public static long hashCode(int x, int z) { long l = (long)(x * 3129871) ^ (long)z * 116129781L; l = l * l * 42317861L + l * 11L; return l >> 16; }then, the result of the hash function is used to calc the offset.
offsetX=(((hash & 15) / 15) - 0.5) * 0.5offsetZ=(((hash >> 8 & 15) / 15) - 0.5) * 0.5then it is clamped between ± maxModeloffset. dripstone`s maxModeloffset is 0.125 others is 0.25
@Ghoulboy78
__hashCode(x, z)->(
l = bitwise_xor(x * 3129871, z) * 116129781;
l = l * l * 42317861 + l * 11;
l = bitwise_shift_right(l, 16);
[ ( bitwise_and( l, 15 ) / 15 - 0.5 ) * 0.5, ( bitwise_and( bitwise_shift_right( l, 8 ), 15 ) - 0.5 ) * 0.5 ]
);
__clamp(list, min, max) ->
(
output = copy(list);
for(output,
if(_ > max,
output:_i = max,
_ < min,
output:_i = min
)
);
output
);
offset = __clamp(__hashCode(x,z),-0.25,0.25);
Does this code seem right?
The results aren't great...

Probably has something to do with the type I'm passing vs what the function ought to be given. Might have to do some manual recasting
Got it working. Thanks @ch-yx
Mark as draft while you work on it?
make sure all the debug prints and deprecated functions made it out
you can have a wrapper around print galled debug_print or dprint or whatever that's basically
dprint(msg) -> if(global_debug, print(player(), msg);
and have a variable global_debug somewhere that you turn on while debugging. That way it's easier to go back to debug mode if you find an issue and also less work ahving to remove all the print statements.
Known issue: blocks that are positioned based on x-z location(bamboo, pointed dripstone) can sometimes fail collision checks because entities are touching but are not numerically in contact. Error only seems to occur in positive x and z directions. It appears that either both fail or neither fail, and this can change on reload.
Results after 1 test Bamboo error: +x : 2nm (effectively 2^-32 meters, hmmm) +z : 12nm Pointed dripstone error: +x : 4.9nm +z : 10nm
After testing at many positions, error seems to always be less than ~20nm. Error along any axis is positive on one side, negative and equal on other side(+x: 2, -x: -2, etc). Slight problem with offset calculation?
After further investigation, the above issue is likely related to the conversion between data types (float precision error or something like that). If someone can check the precision of the game's collision code or any rounding that occurs for bamboo/dripstone locations then I can just round values and hopefully that should solve this.
In the meantime, I might rewrite this to use classes.
my script works fine here