{"id":15722598,"url":"https://github.com/britzl/platypus","last_synced_at":"2025-04-30T15:49:39.881Z","repository":{"id":35903855,"uuid":"129953167","full_name":"britzl/platypus","owner":"britzl","description":"Defold platformer engine","archived":false,"fork":false,"pushed_at":"2024-02-21T08:53:20.000Z","size":125,"stargazers_count":62,"open_issues_count":5,"forks_count":10,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-03-14T02:51:12.245Z","etag":null,"topics":["defold","defold-library"],"latest_commit_sha":null,"homepage":"","language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/britzl.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-04-17T19:12:08.000Z","updated_at":"2025-02-20T09:44:17.000Z","dependencies_parsed_at":"2024-02-21T09:45:36.932Z","dependency_job_id":"8411a624-6fd6-4763-9ce8-00f54e12c037","html_url":"https://github.com/britzl/platypus","commit_stats":null,"previous_names":[],"tags_count":25,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/britzl%2Fplatypus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/britzl%2Fplatypus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/britzl%2Fplatypus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/britzl%2Fplatypus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/britzl","download_url":"https://codeload.github.com/britzl/platypus/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246355249,"owners_count":20763973,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["defold","defold-library"],"created_at":"2024-10-03T22:08:37.186Z","updated_at":"2025-03-31T15:31:00.763Z","avatar_url":"https://github.com/britzl.png","language":"Lua","funding_links":[],"categories":["Libraries"],"sub_categories":["Programming Language"],"readme":"# Platypus\nDefold platformer engine.\n\n# Setup\nYou can use the extension in your own project by adding this project as a [Defold library dependency](http://www.defold.com/manuals/libraries/). Open your game.project file and in the dependencies field under project add:\n\nhttps://github.com/britzl/Platypus/archive/master.zip\n\nOr point to the ZIP file of a [specific release](https://github.com/britzl/Platypus/releases).\n\n# Example\nSee an example of Platypus in action by running the `grottoescape.collection` of this project or try [the HTML5 demo](https://britzl.github.io/Platypus/).\n\n\n# Usage\n\n## Creating an instance\nUse `platypus.create()` to create a Platypus instance. Use this to control a single game object. Each frame you need to call `platypus.update()` and `platypus.on_message()`.\n\n\tfunction init(self)\n\t\tself.platypus = platypus.create(config)\n\tend\n\n\tfunction update(self, dt)\n\t\tself.platypus.update(dt)\n\tend\n\n\tfunction on_message(self, message_id, message, sender)\n\t\tself.platypus.on_message(message_id, message)\n\tend\n\n\n## Player movement\nUse `platypus.left()`, `platypus.right()`, `platypus.up()`, `platypus.down()` and  `platypus.move()` to move the player. The movement will happen during the next call to `platypus.update()`.\n\n\tfunction init(self)\n\t\tself.platypus = platypus.create(config)\n\tend\n\n\tfunction update(self, dt)\n\t\tself.platypus.update(dt)\n\tend\n\n\tfunction on_message(self, message_id, message, sender)\n\t\tself.platypus.on_message(message_id, message)\n\tend\n\n\tfunction on_input(self, action_id, action)\n\t\tif action_id == hash(\"left\") then\n\t\t\tself.platypus.left(250)\n\t\telseif action_id == hash(\"right\") then\n\t\t\tself.platypus.right(250)\n\t\tend\n\tend\n\n## Jumping\nPlatypus supports normal jumps when standing on the ground, wall jumps when in contact with a wall in the air and double jumps. You can also perform a \"forced\" jump that will perform a jump regardless of state. This can be useful when implementing rope mechanics and other such functions where there is no ground or wall contact.\n\nUse `platypus.jump()` to perform a jump and `platypus.abort_jump()` to reduce the height of a jump that is already in progress.\n\n\tfunction init(self)\n\t\tself.platypus = platypus.create(config)\n\tend\n\n\tfunction update(self, dt)\n\t\tself.platypus.update(dt)\n\tend\n\n\tfunction on_message(self, message_id, message, sender)\n\t\tself.platypus.on_message(message_id, message)\n\tend\n\n\tfunction on_input(self, action_id, action)\n\t\tif action_id == hash(\"jump\") then\n\t\t\tif action.pressed then\n\t\t\t\tself.platypus.jump(800)\n\t\t\telseif action.released then\n\t\t\t\tself.platypus.abort_jump(0.5)\n\t\t\tend\n\t\tend\n\tend\n\n## Double jump, wall jump and wall slide\nPlatypus supports double jumps when config.allow_double_jump is set to true. A double jump is performed automatically when a second jump is done before and up until reaching the apex of the first jump. It is not possible to perform a double jump when falling\n\nPlatypus supports wall jumps when config.allow_wall_jump is set to true. A wall jump is performed automatically when jumping while having wall contact while falling or wall sliding. The wall jump pushes the player out from the wall in question.\nNormally, user can alter your movement right after bounced from a wall, but when you set config.const_wall_jump - the bounce will be always the same and user won't be able to alter it.\n\nPlatypus supports wall slide when config.allow_wall_slide is set to true. A wall slide will be performed automatically when the player has wall contact while falling and moving (using platypus.left() or platypus.right()) in the direction of the wall. Platypus offers also to abort_wall_slide(), for example, when the control key is released, so user is no longer pushing toward the wall.\n\n\n## Collision detection\nPlatypus uses ray casts to detect collisions (configured when creating a Platypus instance).\n\n## State changes\nPlatypus will send messages for certain state changes so that scripts can react, for instance by changing animation.\n\n\tfunction init(self)\n\t\tself.platypus = platypus.create(config)\n\tend\n\n\tfunction update(self, dt)\n\t\tself.platypus.update(dt)\n\tend\n\n\tfunction on_message(self, message_id, message, sender)\n\t\tself.platypus.on_message(message_id, message)\n\t\tif message_id == platypus.FALLING then\n\t\t\tprint(\"I'm falling\")\n\t\telseif message_id == platypus.GROUND_CONTACT then\n\t\t\tprint(\"Phew! Solid ground\")\n\t\telseif message_id == platypus.WALL_CONTACT then\n\t\t\tprint(\"Ouch!\")\n\t\telseif message_id == platypus.WALL_JUMP then\n\t\t\tprint(\"Doing a wall jump!\")\n\t\telseif message_id == platypus.DOUBLE_JUMP then\n\t\t\tprint(\"Doing a double jump!\")\n\t\telseif message_id == platypus.JUMP then\n\t\t\tprint(\"Jumping!\")\n        elseif message_id == platypus.WALL_SLIDE then\n\t\t\tprint(\"Sliding down a wall!\")\n\t\tend\n\tend\n\n\n# Platypus API\n\n## Functions\n\n### platypus.create(config)\nCreate an instance of Platypus. This will provide all the functionality to control a game object in a platformer game. The functions will operate on the game object attached to the script calling the functions.\n\n**PARAMETERS**\n* `config` (table) - Table with configuration values\n\nThe ```config``` table can have the following values:\n\n* `collisions` (table) - Lists of collision groups and bounding box size (REQUIRED)\n* `debug` (boolean) - True to draw ray casts\n* `reparent` (boolean) - True if the Platypus game object should be reparented when having ground contact. This is useful when having horizontally moving platforms. Defaults to true. (OPTIONAL)\n* `gravity` (number) - Gravity (pixels/s) (OPTIONAL)\n* `max_velocity` (number) - Maximum velocity of the game object (pixels/s). Set this to limit speed and prevent full penetration of game object into level geometry (OPTIONAL)\n* `wall_jump_power_ratio_x` (number) - Amount to multiply the jump power with when applying horizontal velocity during a wall jump (OPTIONAL)\n* `wall_jump_power_ratio_y` (number) - Amount to multiply the jump power with when applying vertical velocity during a wall jump (OPTIONAL)\n* `allow_double_jump` (boolean) - If double jumps are allowed (OPTIONAL)\n* `allow_wall_jump` (boolean) - If wall jumps are allowed (OPTIONAL)\n* `const_wall_jump` (boolean) - If true - prevents user from changing velocity while bounced from a wall. Set to false by default, to keep legacy behavior. (OPTIONAL)\n* `allow_wall_slide` (boolean) - If true - wall slide is allowed (by pushing forward on a wall while falling) (OPTIONAL)\n* `wall_slide_velocity` (number) - \"gravity\" that applies when sliding down the wall (generally should be lower than overall gravity, to simulate sliding) (OPTIONAL)\n\nThe `collisions` table can have the following values:\n\n* `groups` (table) - List with collision groups. Used when separating collisions.\n* `left` (number) - Distance from game object center to left edge of collision area. Used by ray casts to detect ground and wall contact and when separating collisions using rays.\n* `right` (number) - Distance from game object center to right edge of collision area. Used by ray casts to detect ground and wall contact and when separating collisions using rays.\n* `top` (number) - Distance from game object center to top edge of collision area. Used by ray casts to detect ground and wall contact and when separating collisions using rays.\n* `bottom` (number) - Distance from game object center to bottom edge of collision area. Used by ray casts to detect ground and wall contact and when separating collisions using rays.\n* `offset` (vector3) - Offset from the game object center to the center of the collision area. Use this when your sprite and collision area isn't centered around the game object center. Defaults to (0, 0, 0).\n\nThe `groups` table should map collision group hashes as keys to which collision directions to detect collisions with:\n\n\t{\n\t\t[hash(\"ground\")] = platypus.DIR_ALL,\n\t\t[hash(\"onewayplatform\")] = platypus.DIR_DOWN,\n\t\t[hash(\"onewaydoor\")] = platypus.DIR_LEFT,\n\t}\n\n**RETURN**\n* `instance` (table) - The created Platypus instance\n\nThe `instance` table has all of the instance functions describe below in addition to the values from `config` (either provided values or defaults) and the following fields:\n\n* `velocity` - The current velocity of the game object\n\nYou can modify any of the instance values at runtime to change the behavior of the platypus instance.\n\n\n### instance.update(dt)\nUpdate the Platypus instance. This will move the game object and send out state changes.\n\n**PARAMETERS**\n* `dt` (number) - Delta time\n\n\n### instance.on_message(message_id, message)\nForward received messages from the on_message lifecycle function to this instance function. This will handle collision messages and custom messages generated by the Platypus instance itself\n\n**PARAMETERS**\n* `message_id` (hash) - Id of the received message\n* `message` (table) - The message data\n\n\n### instance.left(velocity)\nMove the game object to the left during next update. This will override any previous call to `instance.left()` or `instance.right()` as well as the horizontal velocity of `instance.move()`.\n\n**PARAMETERS**\n* `velocity` (number) - Amount to move left (pixels/s)\n\n\n### instance.right(velocity)\nMove the game object to the right during next update. This will override any previous call to `instance.left()` or `instance.right()` as well as the horizontal velocity of `instance.move()`.\n\n**PARAMETERS**\n* `velocity` (number) - Amount to move right (pixels/s)\n\n\n### instance.up(velocity)\nMove the game object up during next update. This will override any previous call to `instance.up()` or `instance.down()` as well as the vertical velocity of `instance.move()`.\n\n**PARAMETERS**\n* `velocity` (number) - Amount to move up (pixels/s)\n\n\n### instance.down(velocity)\nMove the game object down during next update. This will override any previous call to `instance.up()` or `instance.down()` as well as the vertical velocity of `instance.move()`.\n\n**PARAMETERS**\n* `velocity` (number) - Amount to move down (pixels/s)\n\n\n### instance.move(velocity)\nMove the game object during next update. This will override any previous call to `instance.left()`, `instance.right()`, `instance.up()`, `instance.down()` and `instance.move()`.\n\n**PARAMETERS**\n* `velocity` (vector3) - Amount to move (pixels/s)\n\n\n### instance.jump(power)\nMake the game object perform a jump. Depending on state and configuration, this can either be a normal jump from standing on the ground, a wall jump if having wall contact and no ground contact, or a double jump if jumping up and not falling down.\n\n**PARAMETERS**\n* `power` (number) - Initial takeoff speed (pixels/s)\n\n\n### instance.force_jump(power)\nMake the game object perform a jump, regardless of current state.\n\n**PARAMETERS**\n* `power` (number) - Initial takeoff speed (pixels/s)\n\n\n### instance.abort_jump(reduction)\nAbort a jump by \"cutting it short\". This will reduce the vertical speed by some fraction.\n\n**PARAMETERS**\n* `reduction` (number) - Amount to multiply vertical velocity with\n\n\n### instance.abort_wall_slide()\nAbort a slide down a wall (could be used when releasing the pushing control key)\n\n\n### instance.has_ground_contact()\nCheck if the game object is standing on the ground\n\n**RETURN**\n* `ground_contact` (boolean) - True if standing on the ground\n\n\n### instance.has_wall_contact()\nCheck if the game object is in contact with a wall\n\n**RETURN**\n* `wall_contact` (boolean) - True if in contact with a wall\n\n\n### instance.is_falling()\nCheck if the game object is falling. The game object is considered falling if not having ground contact and velocity is pointing down.\n\n**RETURN**\n* `falling` (boolean) - True if falling\n\n\n### instance.is_jumping()\nCheck if the game object is jumping. The game object is considered falling if not having ground contact and velocity is pointing up.\n\n**RETURN**\n* `jumping` (boolean) - True if jumping\n\n\n### instance.is_wall_jumping()\nCheck if the game object is jumping after a bounce from a wall. The game object is considered falling if not having ground contact and velocity is pointing up.\n\n**RETURN**\n* `wall_jump` (boolean) - True if jumping after a bounce from a wall.\n\n\n### instance.is_wall_sliding()\nCheck if the game object is sliding down a wall.\n\n**RETURN**\n* `wall_slide` (boolean) - True if sliding down a wall.\n\n\n### instance.toggle_debug()\nToggle debug draw of ray casts.\n\n\n### instance.set_collisions(collisions)\nChange the rays and bounds for collision detection.\n\n**PARAMETERS**\n* `collisions` (table) - collisions table with `top`,`left`,`right` and `bottom` keys\n\n\n## Messages\n\n### platypus.FALLING\nSent once when the game object starts to fall\n\n### platypus.GROUND_CONTACT\nSent once when the game object detects ground contact\n\n### platypus.WALL_CONTACT\nSent once when the game object detects wall contact\n\n### platypus.JUMP\nSent when the game object jumps\n\n### platypus.WALL_JUMP\nSent when the game object performs a wall jump\n\n### platypus.DOUBLE_JUMP\nSent when the game object performs a double jump\n\n### platypus.WALL_SLIDE\nSent when the game object starts sliding down a wall\n\n\n# Credits\n* Grotto Escape tiles - Ansimuz (https://ansimuz.itch.io/grotto-escape-game-art-pack)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbritzl%2Fplatypus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbritzl%2Fplatypus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbritzl%2Fplatypus/lists"}