I'm working on adding a third mode called "hybrid". The hybrid mode uses the pixel movement code from library mode but uses some built-in procs to speed it up. For example, here's how the library checks if a mob is standing on the ground in library and native modes:
// library mode
for(var/atom/a in nearby())
if(!can_bump(a)) continue
while(1)
if(a.pleft == a.pright)
if(py != a.py + a.pheight) break
else
if(py != a.height(px,py,pwidth,pheight)) break
// If you're not lined up horizontally we can also ignore the object
if(px >= a.px + a.pwidth) break
if(px + pwidth <= a.px) break
on_ground |= (1 | a.flags | a.flags_top)
break
// native mode
for(var/atom/a in obounds(src, 0, -1, 0, -pheight + 1))
if(!can_bump(a)) continue
on_ground |= (1 | a.flags | a.flags_top)
The code for library mode looks much more complex but that's not what made it slower. What made it slower is that the for loop uses nearby() instead of obounds(). The nearby() proc essentially returns a list of atoms in oview(1), the obounds() proc returns a list of atoms that occupy the space directly below the mob.
The idea behind hybrid mode is that it can make use of procs like obounds. All the library has to do is set the step_x, step_y, bound_width, and bound_height of the player and obounds() will return the proper list of atoms. Hybrid mode uses these procs to speed up things in ways that library mode can't (because it only used its own px, py, pwidth, and pheight vars, not step_x, step_y, bound_width, and bound_height).
The key is that hybrid mode still uses its own collision detection and resolution code, which means that it's possible to support ramps (and other things not supported by BYOND's native pixel movement).There are still some kinks to work out but so far this looks promising. I created a new demo where mobs move randomly around the map. I ran the test in each mode with 10 mobs. Each test ran until the pixel_move proc was called 25,000 times (about a minute). This table shows the average execution times for the three big pixel movement procs the library has.
+------------+---------------------------+ | | Time (in microseconds) | | Proc +--------+--------+---------+ | | Native | Hybrid | Library | +------------+--------+--------+---------+ | pixel_move | 115.1 | 76.8 | 167.9 | +------------+--------+--------+---------+ | set_pos | 47.3 | 34.4 | 90.3 | +------------+--------+--------+---------+ | set_flags | 50.5 | 48.1 | 89.1 | +------------+--------+--------+---------+As I said, there are still some kinks to be worked out but this is very promising. The hybrid mode outperformed native mode! It'll take more work to get this added to the pixel movement library, but hopefully these same improvements will make it possible to have ramps and 3D movement in the Pixel Movement library with performance that's on par with BYOND's native pixel movement.