Sidescroller

by Forum_account
Sidescroller
This library gives you the basic movement system of a platformer. You can make an action/platform game in minutes!
ID:104499
 
Use this library to make your own sidescrolling action/platform games. This library adds tons of features on top of BYOND's built-in pixel movement to make game development super easy!

It comes with a basic movement system that can easily be extended. Many features (ladders, ramps, platforms, background images, camera control) are implemented for you and many others (wall-climbing, double jumps, etc.) are easy to add!

Quick Links
Do you have doubts about BYOND being able to handle action platform games? Here are some games that use this library (or parts of it):
Exordium & Terminus and A Miner Adventure by Forum_account
Doomed Dreams by DivineTraveller
Pascal's Challenge by SuperAntx

Check out this Dream Makers article about using this library to create a basic platformer!

If you have trouble using the library post on my forum for help. You can also use the forum to provide feedback. If there's something you don't like about the library I'd like to hear your comments and concerns so I can update and improve it.

If you're interested in making an isometric or top-down platformer, check out my pixel movement library.


Version 4.4 (posted 05-11-2012)
• Made the atom's default New() proc take the step_x/y vars into account. You can use them to define a pixel offset that gets applied to the object's px/py vars when it's created.
• Added two optional parameters to the atom.left() and atom.right() procs. These parameters specify the bottom and top heights of the bounding box. The default bottom is 1 and the default top is pheight - by default the box is as tall as the atom.
• Changed the front() proc to also take the bottom and top parameters like the atom.left() and right() procs.

Version 4.3 (posted 03-19-2012)
• Added the jump_speed var whose default value is 10. This is what your vel_y is set to by the default jump proc. This way you can change a mob's jump height without overriding any procs.
• Added the moved var which is set by the move() proc to the dir you tried to move in. This new var is used by the set_state() proc to determine when the "moving" state is used (previously, it used your velocity to determine if the moving state was used).
• Calls to slow_down() are also based on the new mob.moved var.
• Changed how a mob's dir is set. It's now set in the action() proc, not set_state().
• Added the limit var for the Path object. This is the limit of how many turfs will be checked by the pathfinding algorithm before it gives up. The default value is zero, which means there is no limit.

Version 4.2 (posted 02-11-2012)
• Changed the default behavior of mob.can_bump to be more like BYOND's default movement. Now dense mobs will bump all dense objects by default - you don't have to override the proc to make this happen anymore. I updated all demos to make sure they still work after this change.
• The Forum_account.Keyboard library is now included by a custom line in the library's .dme file, which should give a compiler error if you don't have the library. This will make it more obvious why the library doesn't compile, instead of giving 20 some errors about missing vars.
• Changed the way conveyor belts are implemented in the "v2.6" demo. They now make use of the flags and on_ground vars.
• Added the mob.on_ladder() proc which determines if the mob is standing over a ladder tile. The mob.on_ladder var determines if the mob is hanging on the ladder, the proc determines if they are simple over a ladder tile. The default behavior is to return 1 if the tile the mob overlaps most is a ladder. You can override this to change that (ex: make the mob have to be entirely inside the ladder tile to climb it).
• Added the v4.2 demo to show some of the new features.

Version 4.1 (posted 12-07-11)
• The library now uses the Forum_account.Keyboard library for handling keyboard input. All keyboard input functionality still exists, but most of it was moved to the client. The keys list and the lock_input, unlock_input, and clear_input procs belong to the client. The key_up and key_down procs still exist for the mob. The keyboard library can be downloaded here: http://www.byond.com/developer/Forum_account/Keyboard

Version 4.0 (posted 11-14-11)
• Removed the NATIVE and LIBRARY modes - the library now uses only the HYBRID mode. Since this is the only mode there's not an option for it.
• Removed the pixel-movement-native and pixel-movement-library files and changed the pixel-movement-hybrid.dm file to be called pixel-movement.dm instead,
• Renamed mob-movement.dm to movement.dm and moved the set_flags proc back to it.
• Renamed pixel-movement-common.dm to background.dm, since all it contained was code for handling backgrounds.
• Created collision.dm and moved a lot of code from the pixel_move proc to it.
• Added an optional argument to the front() proc. Calling front(4) will return a list of atoms within 4 pixels of the src object based on the direction its facing. Calling front(4, RIGHT) will force it to return a list of objects within 4 pixels of the object's right side, regardless of src's dir.
• Removed the offset_x and offset_y vars, you can now use pixel_x and pixel_y instead.
• Removed the FOUR_FLAGS flag from _flags.dm because all four flags are necessary for some of the library's internals.
• Changed the NO_STEPPED_ON flag to be called STEPPED_ON and made it enabled by default (this way all demos will work, but you can disable it to improve performance in your projects).

Version 3.2 (posted 11-12-11)
• Added the HYBRID mode which can be set in _flags.dm. This is now the default mode. In hybrid mode the library uses some built-in pixel movement procs (ex: obounds) to improve performance but still uses the library's soft-coded pixel movement so it's possible to have ramps. The performance is on par with native mode (it's actually a little better).
• Added the v3.2 demo. It's similar to pathing-demo except it adds AI mobs that move randomly around the map. You can easily adjust the number of mobs. This demo is a handy way to see what the CPU usage will be for a certain number of moving mobs. It's also a handy way to test out pathfinding.
• Added pixel-movement-common.dm which contains some code that's common to all pixel movement modes.
• Moved the set_flags proc from mob-movement.dm to each of the mode-specific movement files because its implementation is different for each.
• Renamed icons.dmi to sidescroller-demo-icons.dmi.

Version 3.1 (posted 10-15-11)
• Added support for calls to set_pos of the form set_pos(atom/a). Passing a single atom to set_pos() will make the src mob be centered at that atom.
• Added a demo called game-demo-2. It combines a bunch of features (many which were already in other demos) and makes a simple game. Add your own graphics and maps and you're well on your way to making your own game!
• Added keyboard support for the shift, alt, and ctrl keys.
• Added a third argument to the bump() proc when native pixel movement is used. This argument is 1 for first time bump() is called after performing a single move and 0 all additional times.
• Added the camera.center() proc, which forces the camera to be within its bounds. This is useful when camera.mode = SLIDE and the camera is outside of the bounds and you want it to jump into position instead of slide into position. For example, start up the game-demo-2 demo with and without calling camera.center() and see the difference.

Version 3.0 (posted 09-11-11)
• Fixed a bug with fractional moves in the y direction. Thanks to Kaiochao for pointing it out!
• Added accel, decel, and gravity vars to mobs. These vars are all 1 by default and control the mob's acceleration and deceleration rates (gravity being the acceleration rate due to gravity).
• Added a demo called v3.0 that shows examples of using the new accel, decel, and gravity vars.
• Added support for BYOND's built-in pixel movement. This is enabled by default, but you can switch back to legacy mode by enabling a compiler flag in _flags.dm. The legacy mode uses the old soft-coded pixel movement which is necessary for supporting ramps.

Version 2.8 (posted 08-21-11)
• Changed the SCROLL_X and SCROLL_Y constants to be named REPEAT_X and REPEAT_Y. These names make more sense since they are used to determine in which directions the background repeats. You can make any background move horizontally and vertically, even if it doesn't repeat in those directions.
• Created the /Controls object which contains the vars up, down, left, right, and jump. These vars contain the keys that correspond to those actions. Each mob has an instance of the /Controls object, so to change a mob's jump key to Z just do: mob.controls.jump = "z"
• Fixed a bug with the way the stepped_on and stepping_on procs were called. Previously there were times when they wouldn't be called when you land on the ground while not moving horizontally at the same time. Now they should be called in all cases that they apply.
• Fixed a bug with the behavior of ramps (it was most noticeable in the scaffold ramps in the movement-demo). I think it was caused by the support for fractional moves, but I'm not sure. Whatever caused it, ramps seem to work fine now.
• Fixed another bug related to ramps. Some cases where you bumped a ramp from the side weren't being handled correctly.

Version 2.7 (posted 07-26-11)
• Changed the set_flags() proc to call nearby() instead of oview(2). I forget why it was using oview (I might have had a reason for doing that). This change makes the default movement loop run almost three times faster.
• Added support for fractional moves. Previously calling pixel_move(1.2, 0) was the same as calling pixel_move(1, 0) because the 1.2 would be rounded down. Now each move is always an integer move but the fractional parts accumulate. If you call pixel_move(1.2, 0) five times the mob moves six pixels - four of the moves are of one pixel, one move is of two pixels.
• Added _flags.dm which contains the definition of the compile-time flags.
• Added the LIBRARY_DEBUG flag. The library has the statement "if(trace)" in many of the movement procs. If you're not going to use the trace feature these aren't necessary, so you can comment out the "#define LIBRARY_DEBUG" line in _flags.dm to make the debugging functions no longer part of the compiled library.
• Added the NO_STEPPED_ON flag. Enabling the flag disables the definition of the atom.stepped_on, stepped_off, and stepping_on procs. If you're not using these procs you can enable this flag to improve performance.
• Added the FOUR_FLAGS flag which enables the on_left, on_right, and on_ceiling flags. It's enabled by default. Even if this flag isn't included, the on_ground flag is defined because it's used by the gravity, jump, and can_jump procs. Disabling this flag also removes the definitions of the atom's flags_left, flags_right, and flags_bottom vars.

Version 2.6 (posted 06-26-11)
• Made a lot of changes to mob-pathing.dm. I inlcuded the old version as _old-mob-pathing.dm in case your project relies on the old version.
• Changed the way path following works when you call move_to(). My hope is that in most cases the mob will do a better job of following the path. In the few cases it doesn't, mobs are quicker to recompute paths so it should correct its behavior.
• Added an argument to mob.movement() and mob.action(). Both take a number of ticks. The global movement loop keeps track of how many ticks have elapsed (it resets when it reaches 1000) and passes the number of ticks to these procs. This can be used for creating mobs that do something every 100 ticks (you can use the argument instead of creating your own counter).
• Made the left and right arrow keys cancel each other out. If you first press left, then press right, the library will act like you're not pressing left (keys[K_LEFT] will be 0, but key_up won't be called). If you release the right key, keys[K_LEFT] will be restored (provided you kept holding it the whole time). Previously if you held both left and right arrow keys you'd slowly move to the right.
• Changed the way platforms are handled. The library no longer defines the /mob/platform type. See game-demo\platforms.dm for the new implementation. The platforms now make use of the stepped_on and stepped_off procs.
• Fixed a bug in game-demo where you would respawn on the platform if you pressed an arrow key while dead.
• Added an example of boxes that can be pushed to the interaction-demo.
• Changed the way move() and climb() are called. Previous, if you were standing next to a wall and tried to move towards the wall, move() would not be called. Now it is. This also means that bump may be called in more situations.

Version 2.5 (posted 06-11-11)
• Added mob-debugging.dm which contains the Stat proc from world.dm and some new debugging features.
• Added the mob.start_trace() and mob.stop_trace() procs. When start_trace() is called, every movement related proc call will be logged. When stop_trace() is called, the log is displayed in the browser.
• Added a new demo called "v2.5" to showcase the new content.
• Created an example of variable height jumps in the "v2.5" demo.
• Fixed a problem with macro initialization - macros wouldn't work when you had a .dmf file with multiple windows.
• Added support for any value of world.icon_size.
• Added the mob.check_loc() proc. It doesn't do anything new, it just contains the functionality that looks for changes in the mob's x, y, and z coordinates to update your pixel coordinates when it detects that you manually changed the mob's loc. It's called from the global movement loop (world.movement), not from mob.movement, so if you override a mob's movement proc you don't lose this feature.

Version 2.4 (posted 04-28-11)
• Added a demo called "v2.4" which shows how to use the features that are new in this version. I used to add examples of new features into whatever existing demos were most relevant. I wish I had thought of doing it this way sooner!
• Added the flags_left, flags_right, flags_top, and flags_bottom vars which behave just like atom.flags except they let you define properties for individual sides of the atom. The mob's flags are binary ORed with the atom's flags var and the specific side's flags var.
• Added camera.dm which contains the set_camera proc (which was previously in pixel-movement.dm) and the /Camera object. A var called "camera" was added for mobs that's an instance of the Camera object. This object stores all properties related to the camera.
• The camera.mode var can be set to camera.FOLLOW or camera.SLIDE to switch between a camera that strictly follows the mob and one that speeds up and slows down to smoothly follow the mob.
• The camera.lag var can be used to specify the number of pixels the mob can move away from the camera before the camera will move to follow the mob.
• The camera.px and camera.py vars can be used to set the camera's position.
• The camera.minx, camera.maxx, camera.miny, and camera.maxy vars can be used to specify bounds on the camera's position. The set_camera proc's default behavior will not move the camera outside of these bounds.
• The camera can still do some weird things when you use EDGE_PERSPECTIVE, so I recommend not using it and instead using the minx, maxx, miny, and maxy vars to enforce camera bounds near the edge of the map.
• Added the stepped_off and stepping_on procs and changed how the stepped_on proc works. stepped_on is called only once when you first step on an atom, stepped_off is called once when you stop standing on an atom. stepping_on is called every tick for the whole time you're standing on top of the atom.
• Updated the reference to include all new vars, procs, and objects.

Version 2.3 (posted 04-17-11)
• Added the mob.face(atom) proc which makes the mob turn to face a specified atom.
• Added the atom.flags var and changed how the mob's flags (on_ground, on_left, on_right, and on_ceiling work). This change is backwards compatible. The atom.flags var is a bit mask that gets binary ORed with on_ground. See the reference entry for atom.flags in _readme.dm for more information.
• Added icy floors to movement-demo to show how the new atom.flags var can be used.
• Changed the mob.background proc to add support for scrolling backgrounds. The first argument is still the image file, the second argument is the scrolling mode, 0 for no scrolling, SCROLL_X for horizontal, SCROLL_Y for vertical, and SCROLL_X+SCROLL_Y for both.
• Added the mob.backgrounds list so that a single player can have multiple backgrounds displayed at the same time.
• background-demo has been updated to make use of the new background features. Check it out!
• Updated the reference in _readme.dm.
• Removed hair.dm. Apparently the accessorization of the base icon didn't attract many more users (it was an April Fool's joke anyway).

Version 2.2 (posted 03-27-11)
• Added the mob.action() proc to mob-movement.dm. This new proc contains code that used to be part of movement(). It doesn't do anything new, this split just lets you modify a mob's movement behavior without overriding movement().
• Added the move_speed and climb_speed vars. These are used to limit the mob's movement speed in the move() and climb() procs.
• Changed the name of the terminal_velocity var to "fall_speed".
• Replaced the turf.platform var with the atom.scaffold var. It does the same thing but also allows you to make mobs and objs that behave as scaffolds. The name had to change because mobs already had a var called "platform".
• Added support for sloped tiles that have scaffold = 1. I also added some of these tiles to movement-demo.
• Added a new demo called mario-demo that shows how to create some features from Super Mario Bros.
• Changed the way collisions are resolved. Previously you'd be pushed in the direction opposite of the attempted motion, now you're pushed outside of the tile in whatever direction is shorter.
• Made some minor changes in mob-pathing.dm to the way that mobs follow paths or move towards tiles to address the problem shown here.
• Added hair.dm which adds a random hair overlay to all mobs.

Version 2.1 (posted 03-06-11)
• Added mob-pathing.dm which contains two new procs: mob.move_to() and mob.move_towards(). These procs behave like DM's built-in walk_to and walk_towards procs.
• Added a demo called "pathing-demo" which shows how the pathfinding features are used.
• Updated the reference at the bottom of _readme.dm. I hadn't done this in a while, so many vars and procs weren't documented - now they are.

Version 2.0 (posted 02-27-11)
• Removed the warning that would sometimes be displayed when the library detected that certain keyboard macros weren't defined. If you suspect that macros aren't firing you can set SIDESCROLLER_DEBUG = 1 to see if key presses are being caught.
• Added the shooter-demo, which contains two different types of projectiles.
• Changed the order that potential obstacles are considered in the pixel_move proc. Cardinal directions (up, down, left, and right) are now checked before diagonals. See the pixel_move proc and nearby() proc (in procs.dm) for more info.
• Removed common\interface.dmf. The macro definitions are no longer needed, so BYOND's default interface is fine for the demos.

Version 1.9 (posted 02-14-11)
• When a mob is walking down a ramp they will "stick" to the ramp. This way the mob is continually on the ground and can jump while walking down the ramp.
• Changed the name of the turf's "is_ladder" var to just "ladder".
• Added the "platform" var to turfs. This allows you to create platforms that mobs can walk on top of or drop through.
• Added an example of the new platform var to movement-demo
• Added the ability for mobs to drop through platforms by holding down while pressing the jump key (space bar)

Version 1.8 (posted 01-26-11)
• Added a demo called "movement-demo" which shows simple ways to create alternative movement styles. It contains three different types of mobs (normal, climber, and flyer) each with a different movement style.
• Changed the way keyboard input is handled. The library adds keyboard macros for each client to track which keys are pressed. See keyboard.dm for more details.
• Renamed common\keyboard.dmf to common\interface.dmf because it is not used to define keyboard macros, but is still used for the interface.
• Changed the values of the K_LEFT, K_RIGHT, K_UP, and K_DOWN keyboard constants so the values match the macro names ("west" instead of "left" now)
• General code cleanup. Some procs were moved to different files for more logical groupings.
• Added more comments within code and at the top of each file.

Version 1.7 (posted 12-22-11)
• Made some changes to the atom.inside proc. It now has three forms: atom.inside() returns a list of all atoms inside of src. atom.inside(atom/a) returns 1 if a is inside src. The original atom.inside(qx,qy,qw,qh) still exists.
• Changed the order of some things in the mob's default movement proc.
• Made some parts of the mob's movement proc execute only for mobs that have clients connected.
• Removed the get_left, get_right, get_ground, and get_ceiling procs. They were replaced by the set_flags proc which sets the on_ground, on_left, etc. flags. If you need a list of atoms on a mob's right call mob.right(1).
• Replaced x_bump and y_bump with the single bump proc. The first argument to bump is the atom you're bumping and the second argument is the direction (UP, DOWN, LEFT, or RIGHT).
• Added the mob.at_edge proc which checks if the mob is standing at the edge of a platform
• Added the mob.dense proc which checks if a list contains an atom that the mob can bump.
• Made the enemies in the interaction-demo move (see interaction-demo/enemy.dm)

Version 1.6
• Added procs.dm which contains some helper procs meant to compensate for the loss of useful tile-based procs like get_step. See the reference or procs.dm for a description of each new proc.
• Added a new demo called "interaction-demo". This demo shows how you can use these new procs to interact with objects.

Version 1.5
• Added world.dm which contains some options and the global movement loop.
• Added a global SIDESCROLLER_DEBUG flag which enables some error messages and a debugging statpanel tab.
• Added gravity proc for mobs. It is called every tick by the movement proc and applies gravity when applicable (mob is off the ground and not on a ladder).
• Added an error message when the set_pos proc moves an object to a null location (off the edge of the map).
• Added a return value for pixel_move: it returns 1 if any move was made and 0 otherwise.
• Added the terminal_velocity var for mobs. This var limits how fast a mob can be falling.
• Changed all pixel movement vars & procs to be defined for /mob instead of /atom/movable. Objs are still mobile (their loc can change) but they don't have pixel movement.
• Removed OVERRIDE_WORLD_LOOP and moved the global movement loop to be a member of the world datum (see world.dm). To override the default movement behavior just override world.movement().

Version 1.4 (BIG UPDATE!)
• The movement loop now detects when the mob's loc was changed. This lets you still move mobs by changing their loc, you don't need to use mob.set_pos (but you still can)
• Added default behavior for the move, climb, jump, and key_down procs. The behavior that was previously defined in the demos for these procs is now the default behavior.
• Added some demos and renamed existing ones:
• simple-demo - shows very basic features
• background-demo - shows how to create and manage a background image
• ramps-demo - shows how to create sloped tiles
• game-demo - a complete game with bullets and moving platforms
• Removed set_dir, set_action, and compute_state procs. The set_state proc will now handle all of the icon_state behavior. set_state is called from the mob's default movement proc.
• Changed constant names (ex: STATE_STANDING is now just STANDING).
• The default movement proc can now call move(UP) and move(DOWN) too.
• Changed the global movement loop (see the world_loop proc in mob-movement.dm)
• Does not call the movement proc for objs anymore, just for mobs.
• If you set OVERRIDE_WORLD_LOOP = 1 the loop will stop (so you can replace it with your own)

Version 1.3
• Integrated documentation with DM's reference. See this page for instructions on how to set this up.
• Removed the on_platform var.
• Removed the can_move proc.

Version 1.2
• Added scrolling backgrounds and a background demo.
• Changed the way your loc is computed. It now takes into account your width and height so that your loc is the tile you overlap the most.

Version 1.1
• Fixed the .zip file.
This is a great demo.
Ramps aught to be altered so mobs walking down them cling to the ground when they're not already jumping.
There seems to be a problem when jumping onto a ladder or jumping while pressing either left or right arrows. The character will keep moving, but sometimes it will stop when you press another key and sometimes it wont.
SuperAntx wrote:
Ramps aught to be altered so mobs walking down them cling to the ground when they're not already jumping.

I need to test it more, but so far it seems as though this was easier than I thought it would be.

I can post the code (it's very simple) but since this is the only change I've made since version 1.8 was posted, it's not worth incrementing the version number just for this one feature.
Very fun and amusing lib. Nice job on this.
An amazing resource that I look forward to using in many projects.
An amazing resource that I look forward to using in many projects.
Very fun and amusing lib. Nice job on this.

Thanks! If you guys have any problems using the library, feel free to ask questions on my forum.
Good job!
Very helpful library
It's a great library - my only problem is that school computers don't let me download it through BYOND. If only there was a direct link...

What would be nice is the ability to also modify the max speed, acceleration, and deceleration of a mob... though since I can modify the lib myself, I could put it in for myself.
You can control the mob's max movement speed with the move_speed var. You can make the other changes you mentioned by overriding procs, you don't have to modify the library itself. The easiest way is probably to copy the mob.move and mob.gravity procs into your project and modify them there. This way you're not modifying the library, so if you have two projects that use it you won't cause problems in one project because you made changes for the other.
A friend of mine is a bit shy, and wants to use your library, but he prefers the world icon size at 64, because that's the icon size his pixel artist prefers to give him. I'm not sure how complicated it is to convert the library so it can use this size, so the feature request is for the library to adapt to the world icon size.
Chowder wrote:
A friend of mine is a bit shy, and wants to use your library, but he prefers the world icon size at 64, because that's the icon size his pixel artist prefers to give him. I'm not sure how complicated it is to convert the library so it can use this size, so the feature request is for the library to adapt to the world icon size.

It turns out I have this implemented already, I just need to post the update. It'll be available later today.

Edit: The update has been posted. The library should now work with any value of world.icon_size.
Check out this analysis of the camera in Super Mario World. Some of the camera locking features would really nice.
SuperAntx wrote:
Check out this analysis of the camera in Super Mario World. Some of the camera locking features would really nice.

It seems like most of that should be possibly by setting camera.minx, maxx, miny, and maxy. This seems to be more in demo territory than library territory. The "platform locked" mode means you set the camera's miny and maxy when you are touching the ground:

mob
action()
..()
if(on_ground)
camera.miny = py
camera.maxy = py


Something like that. I'll look into it more and see if there are any additional features the library would need, but it looks like it's quite possible. The only thing I can think of is changing/extending camera.lag to allow separate lag values for the x and y directions, but I'm not sure that'd be necessary.
SuperAntx wrote:
Check out this analysis of the camera in Super Mario World. Some of the camera locking features would really nice.

I was thinking about this again.

I'm not sure how much I'd have to modify the camera controls, but I've always wanted to add some way to limit movement based on the camera. Like old platformers where the screen would only scroll in one direction and you couldn't move off the other edges of the screen to backtrack.
i injoyed it alot keep up the Good Work
Hey Forum_account can you help me make a sidescroller big fan of your tutorial can you help me make mine?
Marcus55 wrote:
Hey Forum_account can you help me make a sidescroller big fan of your tutorial can you help me make mine?

I barely have time too work on my own games! If you have any questions about my tutorials, demos, or libraries, you can post your questions on my forum: http://www.byond.com/members/Forumaccount/forum
Page: 1 2