ID:118230
 
A quick update of the planned changes to my sidescroller and pixel movement libraries to include the changes in BYOND v490:

First off, the libraries are still useful. It sounds like native pixel movement is all you need, but there's more too it than that (this is similar to the feeling that you get when you look at DirectX or OpenGL and think, "that's the whole graphics engine, what else is there to it?", then you realize you need to load and manage textures, 3D models, animations, etc.). It's not about how the feature is implemented, it's about how you use it. The library has always done two things: provide you with the feature and bridge the gap between the feature and how you'll use it. The feature itself was always just the library's pixel_move() proc, but if you take a look at the library you'll see there's a lot more to it than that one proc.

The new pixel movement feature replaces the library's pixel_move() and set_pos() procs. The new bounds() proc also makes some improvements available to set_flags(). Those were the three biggest CPU users in the library and they can all be converted to use the built-in feature. Because this conversion is possible, all demos that come with the libraries (and anything you wrote using the library) will automatically use the new feature.

There are many features that the built-in implementation doesn't provide. Of these, some may be added in the future, some may be added with soft code, and some may be neither. The libraries still provide you with the movement/action loops, velocity vars, position/size vars (px, py, pwidth, etc.), icon state management, movement speed restrictions, the flags vars, the can_bump proc (easier than using Enter and Cross), keyboard control, camera control, and probably some other things. The libraries also provide support for ramps and 3D movement which don't appear to easily integrate with the native feature.

Update Progress

I started working on updating the sidescroller library to use the new feature and, in a couple of hours of work, have it mostly working. I chose to start with the sidescroller library because it'll be the harder one to convert. Aside from 3D movement (which will likely always be handled in soft code), the sidescroller library contains every feature the pixel movement library has and then some. If this conversion is possible, converting the other library will be even easier.

Most of the pixel_move() proc is now handled by two calls to Move(). The set_pos() proc is now handled by overriding the Move() proc to udpate your px and py vars. The px and py vars are still useful because the native bound_x, x, and step_x vars make it difficult to compare the positions of two atoms (ex: is this atom to the left of that one?). If neither, one, or both atoms you're comparing are mobs (and have those bounds/step vars) you need to check the positions differently. With the pixel movement library's px, py, pwidth, and pheight vars belonging to all atoms you can compare the positions of any two atoms easily, there are no special cases.

The atom.Enter and mob.Cross procs now call the mob's can_bump() proc. I find this also to be simpler because the can_bump proc gives you one place to define what can stop a mob's movement. The mob's Bump() proc figures out the direction of the bump and calls the bump() proc (with a lowercase "b") with the same arguments it always had (the obstacle and the direction of the collision).

I'm still working on getting support for scaffolds but I don't foresee any huge problems there. The only remaining feature is camera control, since the new feature adds a little bit of its own. I don't expect huge problems there either (no more problems than the feature has always given me).

I expect to have it all working by tomorrow. It might take a day to test, but an update should be posted by this weekend.
Thanks for getting on this :). The main thing i like about the built in one is pretty much the ease of power of changing the bounding box. by being able to set it in to a icon at any point you like at any size. using those bound control parameters
Very nice! Kind of ironic that pixel movement came while you were on vacation. Probably a nice surprise to come back to. I'll still be using the Side Scroller Library and Pixel Movement in my current projects so I'm looking forward to the 490 update improving performance and functionality in both these libraries.
You can change an object's pwidth and pheight in the library just like you can change bound_width and bound_height. I think I'll have the library's pwidth and pheight vars take precedence (the bounds_width/height vars will be updated automatically to match the pwidth/pheight values). I don't like that only movable atoms have the bounds_ vars, so if you want to compare the positions of two atoms you'd handle it differently if they're two turfs, a turf and a mob, or two mobs.

I do like the built-in bounds/obounds() procs. They seem very useful but the mess of arguments they can take limits their usefulness. The library should be able to address this by converting most of the procs in procs.dm to use bounds() or obounds() instead.
KetchupKid wrote:
Very nice! Kind of ironic that pixel movement came while you were on vacation. Probably a nice surprise to come back to. I'll still be using the Side Scroller Library and Pixel Movement in my current projects so I'm looking forward to the 490 update improving performance and functionality in both these libraries.

It's only a nice surprise because the feature can easily be integrated with the libraries =)

I'm glad to hear you'll still be using the libraries. The API they provide is the product of being used in actual projects, so there's some method to the madness.

It seems minor, but by providing the developer with the vel_x and vel_y vars a lot of things are simplified. BYOND's control scheme was always simplistic but because tile-based movement is always simplistic, it wasn't an issue. If you imagine an attack that knocks an enemy back, in tile-based movement it'd be something like this:

mob/proc/knockback(mob/m)
step(m, get_dir(src, m))


There's a simple pixel movement equivalent, but it doesn't look right at 30-40 frames per second. By manipulating the mob's velocity and letting the library use that to manipulate its position, you can create a nicer looking effect:

mob/proc/knockback(mob/m)
m.vel_x += 10
The best part about this is that the biggest CPU hog in any of the pixel libraries you've made is the pathfinding. It works great, but since it's all done in softcode it's very CPU intensive. With this changeover, the built in walk_to, walk_towards, etc. procs will work with pixel movement, making pathfinding much more simple for the AI, and much lighter on the cpu. The biggest problem with Tanx is that the AIs pathfinding hogged so much of the CPU that the other systems suffered for it. Now that they'll be able to use the built in procs, shelled by the library, Tanx should run fine for even single core CPUs.

This excites me, as the only reason people don't play Tanx frequently is because of the insane CPU requirement in comparison to other BYOND games.
Bravo1 wrote:
Tanx should run fine for even single core CPUs.

Good, because that's all you get with BYOND.

Vermolius wrote:

Good, because that's all you get with BYOND.


Indeed, it's the main reason why Tanx isn't as popular as I expected it to be. People tell me it's fantastic but everyone who's said that was running on a dual core at the least. Most people who play on byond are mainly casual gamers who don't have dual cores, as a result, most people can't even play Tanx, let alone try to enjoy it.

Take your time Forum, Make your libraries all sexy and compatible for us. And don't leave out any of them goodies :p tehe
Bravo1 wrote:
The best part about this is that the biggest CPU hog in any of the pixel libraries you've made is the pathfinding. It works great, but since it's all done in softcode it's very CPU intensive. With this changeover, the built in walk_to, walk_towards, etc. procs will work with pixel movement, making pathfinding much more simple for the AI, and much lighter on the cpu.

Don't get your hopes up. The built-in pathfinding procs call Move() or step(), or something like that. They manipulate your position directly, they don't call the library's move() proc to manipulate the mob's velocity. The built-in pathfinding is most likely not compatible with the library.

I'm not sure how efficient their pathfinding is either. Hopefully they've made improvements, but user-made tile-based pathfinding algorithms used to easily out-perform the built-in ones (especially if your usage of the built-in routines repeatedly called step_to). You still get CPU savings on the actual movement, which will certainly lighten the load, but I'm not sure that their built-in pathfinding would offer a huge gain over soft-coded pathing.

There still may be ways to improve the AI's CPU usage. Most games don't use intelligent path planning for everything, they encode some data in the maps or compute some things at runtime to lessen the load. For example, place waypoints on the map and, at runtime, compute paths between adjacent waypoints. Then, to find a path from any tile to another you only need to compute the path from the current location to the first waypoint and from the last waypoint to the destination - the paths between waypoints were already computed when the map was loaded. There are probably some simpler things you can do - use move_towards (which doesn't compute a path) and when you bump into something (in other words, when move_towards didn't give you a good path), call move_to instead.
I've heavily skimmed this post and the comments, so I'm not sure if what I'm saying is redundant.

There are some trivial and non-trivial ways to optimise A* pathfinding. Waypoints are one way but it requires a lot of effort on the user-end. Using non-naive data structures to keep track of unexplored nodes is another. I think I heard somewhere BYOND's native pathfinding is almost brute-force, so looking into some of these optimizations is likely in your best interest.
I keep meaning to implement a priority queue and see how it works. I'm not sure how effective it will be. If you're finding short paths the overhead of a priority queue implemented in DM might be worse than the inefficiency of doing a linear search each iteration.

I recall Lummox saying that BYOND's tile-based pathfinding used a very inefficient algorithm (O(n^3)), but for their pixel-based walk_to I imagine it's implemented quite differently and could be more efficient. The post about the new pixel movement feature says that it has an A* algorithm but that it doesn't work for fast movers, so I get the impression it's quite a special case.

The biggest problem with built-in pixel movement is that it's all closed off to the user. There's no way to customize how it takes obstacles into account or how it executes moves to follow a path. For a tile-based game this is less of a problem because the games aren't very movement-centric, but with pixel movement games will absolutely be movement-centric. If you want to make some kind of game with a different type of movement system (left/right arrows turn you, up moves forwards) you're not getting any help from walk_to.

Using waypoints does require work on the user end, but most games will require implementing the entire pathfinding routine on the user end. That is, unless they find a way to make built-in features that support customizable path finding, but I doubt they are.
The libraries aren't quite ready to post, but I did some basic profiling. Running benchmarks\demo-1 in the pixel movement library, here are the results:

#   Lib   Native
30 20% 11%
60 41% 20%
90 64% 30%


The # column is the number of bouncing balls. The other columns are the CPU usage as reported by world.cpu (averaged over time). All trials were run at 40 fps. This was run on my laptop which is fairly slow (1.00 GHz dual core). I did some profiling to see how individual procs were affected, here are the results of that:

The pixel_move proc's self CPU time went from 87 μs per call to 60 μs per call. The big difference is in the pixel_move proc's total CPU time - this went from 180 μs per call to 77 μs per call. This dropped drastically for a couple of reasons. The set_pos proc (which is called from pixel_move) is now not really needed (it's handled internally by Move()) and the can_bump proc doesn't need to be called as often (at 1.2 μs per call it added up).

The good news is that it certainly does improve performance, it looks to be about a 2.5x performance increase. This isn't as game-changing as I'd have hoped for, but hopefully they're not done improving it.
Forum_account wrote:

The good news is that it certainly does improve performance, it looks to be about a 2.5x performance increase. This isn't as game-changing as I'd have hoped for, but hopefully they're not done improving it.



A 2.5x performance increase is more than enough for now. One of the main reason BYOND has never really flourished outside of the site is due to the lack of art or gameplay in most games. The problem was not the artists/developers, but instead the lack of features in DM to support the games. Now, games like Tanx will be much more common and BYOND will start to make a much larger impression.

Honestly though, the API of the pixel movement library is much easier to use than having to deal with the built in procs, in my opinion, considering added functionality like the key bindings, camera controls, procs like set_state() and gravity().

You may not realize it, but the initial library for pixel movement that you made may just have been the first step toward BYOND becoming a popular platform for developers. Now, the second big step has been taken, and with the PM API overlaid onto the built in code, you've made it incredibly easy to use as well.

Consider yourself the savior of BYOND, at least I do.
Bravo1 wrote:
A 2.5x performance increase is more than enough for now. One of the main reason BYOND has never really flourished outside of the site is due to the lack of art or gameplay in most games. The problem was not the artists/developers, but instead the lack of features in DM to support the games. Now, games like Tanx will be much more common and BYOND will start to make a much larger impression.

The performance boost is nice, but there's still a lot that's out of reach of DM developers. If you look at simple particle effects in other games (ex: Knytt Stories has a lot of enemies that shoot many projectiles at once). The motion is simple but having a mob that shoots 30 projectiles still bogs things down when you consider the limit on moving objects is still in the hundreds.

Honestly though, the API of the pixel movement library is much easier to use than having to deal with the built in procs, in my opinion, considering added functionality like the key bindings, camera controls, procs like set_state() and gravity().

Thanks! I think a lot of people are going to realize that, by itself, built-in pixel movement doesn't help nearly as much as they thought it would.

The library's API is easy to use because I've used it a lot and included a lot of user feedback. I've used in three projects (that I've told people about, I have plenty more on my harddrive) but what really helps is that I've written tons of demos for the libraries. My goal is to make popular features easy to implement and the demos reflect this. Wall-climbing, conveyor belts, projectiles, jumping, double jumping, enemies, AI, doors, pathfinding, movement schemes, etc. - it's all in the demos and most of these features are non-trivial and are less than 15 lines of code (and the lines of code are all very simple, they're not beastly lines with 4 nested function calls and a slew of bitwise operations).

Part of the problem is that BYOND's API just shouldn't be as good as the library's API. BYOND's pixel movement feature is general, the library is more specific. I try to keep it general, but it's still fairly specific. The concept of a velocity and movement loop that is automatically run each tick is common to many games (so it makes sense for the library to work this way) but isn't common to all games (so it wouldn't make sense for BYOND to work this way).

The other part of the problem is that whlie the BYOND staff claims to share this goal (making things simple), they're not putting it into practice effectively. They tend to make easy features easy to implement instead of making the slightly-more-complex but highly desired features be easy to implement. It's hard to make complex things easy but it's absolutely worthwhile. Comments like yours validate this.

You may not realize it, but the initial library for pixel movement that you made may just have been the first step toward BYOND becoming a popular platform for developers. Now, the second big step has been taken, and with the PM API overlaid onto the built in code, you've made it incredibly easy to use as well.

Hopefully the momentum will continue and positive steps will continue to be made. The next big step is better built-in support for mouse input (regular pixel updates), but we'll have to wait and see if the staff keeps at it or says "there, we implemented a big feature you've been asking for, now we can take a break from looking at the feature tracker."

Consider yourself the savior of BYOND, at least I do.

Thanks, but the whole community is what'll save BYOND. It's just been unfortunate that the community has been dragging BYOND down for so long. I think that events like this and games like NEStalgia prove that it would only take a few positive events to get BYOND back on track as a serious game development platform.

Maybe Tanx is the next step to BYOND getting better, so get back to work! =)
I'm still waiting for the new version of PM, I want to see how well it runs before I work any more on Tanx, but I am working on something else in the meantime. =P
Ok. I might have it ready by tomorrow, I'm not sure. I have the sidescroller library in pretty good shape (most of the demos work fine) but then I ran it with Tiny Heroes and ran into some problems that didn't come up in the demos. I expect fewer issues for the PM library because it's generally simpler. It might be ready sooner.
I will be waiting on this as well. We're going to test out Eternia with the new library and see if the changeover is worth it. We'll let you know the results of our testing as well.
Unfortunately it seems like set_pos() and can_bump() no longer work properly, both of which are used heavily for the projectiles -__-
Bravo1 wrote:
Unfortunately it seems like set_pos() and can_bump() no longer work properly, both of which are used heavily for the projectiles -__-

The only test cases I have are in the demos that come with the library and most of those seem to work okay. If you can explain what isn't working or post a demo, I can get it fixed.
Page: 1 2