{"id":"funwolf7/jumpbutton","name":"jumpbutton","scope":"funwolf7","platform":"roblox","description":"A simple library for detecting when the local player is holding the jump button in Roblox, with support for buffered inputs.","version":"1.0.0","latest":"1.0.0","versions":["1.0.0"],"license":"MIT","licenseRating":"safe","licenseCaveats":[],"licenseVerified":true,"dependencies":{},"integrity":"58aee31d5de07a2f7f748c48e633fb51dcd3a0b661b970db46a990808d0f754c","likes":0,"downloads":0,"install":"forest install funwolf7/jumpbutton","url":"https://forest.dev/p/roblox/funwolf7/jumpbutton","files":"https://api.forest.dev/ai/package/roblox/funwolf7/jumpbutton/files","readme":"[ReleasesPage]: https://github.com/funwolf7/JumpButton/releases\r\n[ModelPage]: https://www.roblox.com/library/14052977941\r\n\r\n# JumpButton\r\nA simple library for detecting when the local player is holding the jump button in Roblox, with support for buffered inputs.\r\n\r\n- [Download the latest release][ReleasesPage]\r\n- [Installation steps](#installation)\r\n- [Recommended usage](#usage)\r\n- [View the api](#api)\r\n\r\n## Why JumpButton?\r\nRoblox does not provide a good API method to listen for the jump button being held. Popular (but flawed) methods include:\r\n- Listening for spacebar presses\r\n\t- This doesn't support mobile or gamepad devices\r\n- `UserInputService.JumpRequest`\r\n\t- This fires several times after a jump, leading to the implementation of a debounce, which can be infuriating when rapidly pressing jump\r\n\t- The amount of time it fires afterwards is random, leading to inconsistent \"jump buffering\"\r\n\r\nJumpButton instead uses the `Humanoid.Jump` property. This is a viable option because it is what the ControlModule sets every frame. JumpButton reads this property every frame right after the ControlModule runs and checks if the property has changed since the last frame.\r\n\r\n**Note:** JumpButton does not listen for changes with an event, as `Humanoid.Jump` rapidly changes when the user jumps, which would ruin the library.\r\n\r\nJumpButton also includes support for consistent jump buffering. Input buffering is something that many games will do to make the game easier or more enjoyable. Specifically, if you press a button when it would do nothing, then it changes and would now do an action upon pressing it, it will automatically do the action. The window in which you are allowed to press the button early varies from game to game, from almost no window to unlimited time.\r\n\r\n## Downsides\r\nJumpButton has a few minor downsides:\r\n- It only works when a humanoid exists. When no humanoid exists, JumpButton will remain in the state it last was.\r\n- It will not detect inputs where the player pressed and released the jump button in the same frame.\r\n\t- `UserInputService.JumpRequest` has the same issue, so this likely isn't too big of a problem.\r\n\r\n## Installation\r\n**Note:** JumpButton can only run on the client\r\n> ### In studio:\r\n> Insert the [model][ModelPage] into some place accessible to the client.\r\n\r\n> ### External Editor:\r\n> Download the `JumpButton.luau` file from the [latest release][ReleasesPage] and insert it into your project in a place accessible to the client.\r\n\r\nOnce installed, regardless of method, simply `require` the ModuleScript, and you now have access to the functions it provides.\r\n\r\n## Usage\r\n\r\n### Basic usage\r\nIf you do not wish to use buffering, using the library is simple. You will only need a few functions.\r\n- [`JumpButton.OnPress`](#jumpbuttononpress) is an `RBXScriptSignal` that you can Connect to which will fire whenever the jump button is pressed.\r\n- [`JumpButton.OnRelease`](#jumpbuttononrelease) is an `RBXScriptSignal` that you can Connect to which will fire whenever the jump button is released.\r\n- [`JumpButton.isPressed()`](#jumpbuttonispressed) can tell you if the jump button is currently being held.\r\n\r\n### Advanced usage (buffering)\r\nWhen using buffering, it gets a bit more complicated.\r\n\r\nEvery time the jump button is pressed, JumpButton stores the timestamp (using `os.clock`), at which it was last pressed. This timestamp is set to nil when the jump button is released or when the buffer is killed (more on killing the buffer below).\r\n\r\nWhen an action that uses the jump button gets enabled, you should retrieve the buffer start using [`JumpButton.useBufferStart()`](#jumpbuttonusebufferstart), which returns the stored timestamp. (**Note:** only call this function once per action, and store the value if needed, as it will return nil the second time it is called. More information on why this occurs in the \"Killing the buffer\" section.)\r\n\r\nIf there is an unlimited buffer window (the button press can happen an unlimited amount of time before the action), then simply checking if the timestamp exists is enough. If there is a limit to the amount of time after the press, you must check first that it exists, and also that less time has passed since the buffer than the buffer duration.\r\n```lua\r\nlocal BufferDuration = 0.1\r\n\r\nlocal currentBufferStart = JumpButton.useBufferStart()\r\nif currentBufferStart and os.clock() - currentBufferStart <= BufferDuration then\r\n\tprint(\"buffered, immediately perform the action\")\r\nelse\r\n\tprint(\"not buffered, wait for a jump press to perform the action\")\r\nend\r\n```\r\nIf the check passes, then you should immediately perform whatever action was just enabled.\r\n\r\nWhen using JumpButton, you may find yourself using the same time window for most actions. If this is the case, then you can use [`JumpButton.setDefaultBufferDuration(newBufferDuration)`](#jumpbuttonsetdefaultbufferduration) to set a default duration, and then use [`JumpButton.useIsBuffered()`](#jumpbuttonuseisbuffered), which will automatically perform the time check based on the default buffer duration that has been set, returning true if it passes and false if not. If the default buffer duration is set to nil, then it will only check if the buffer start exists, allowing for an unlimited buffer duration.\r\n\r\n#### Killing the buffer:\r\nAn important idea with buffering is that one press of the button should only trigger one action. To allow for this, JumpButton implements ways to \"kill\" the buffer. This simply sets the buffer timestamp to nil, making it so that further checks of the buffer start will not cause more actions. You can manually kill the buffer by calling [`JumpButton.killBuffer()`](#jumpbuttonkillbuffer).\r\n\r\nIn order to make it easier for developers, all `use` functions (`JumpButton.useBufferStart` and `JumpButton.useIsBuffered`) automatically kill the buffer when called. The idea behind this is that if an action is checking the buffer, then most likely it will perform an action if the buffer timestamp exists, thus the buffer should be killed. If you wish to check the buffer timestamp without killing it, you can use `peek` functions ([`JumpButton.peekBufferStart()`](#jumpbuttonpeekbufferstart) and [`JumpButton.peekIsBuffered()`](#jumpbuttonpeekisbuffered)), which return the same things as their counterparts but without killing the buffer.\r\n\r\nThis also has the side effect that the `use` functions will return nil the second time if called twice in a row. If you need to use the result of these functions in multiple places, you should store the result as a variable and use the variable instead.\r\n\r\n#### Automatic buffer killing:\r\nThe humanoid jumping is an action triggered by the jump button, so JumpButton automatically listens for `Humanoid.Jumping` and kills the buffer whenever it fires. If this is not desireable, you can call [`JumpButton.setAutoKillOnJump(false)`](#jumpbuttonsetautokillonjump) to disable this feature.\r\n\r\n## API\r\n\r\n### JumpButton.OnPress\r\n```\r\nJumpButton.OnPress: RBXScriptSignal\r\n```\r\nAn `RBXScriptSignal` that fires whenever the result of [`JumpButton.isPressed`](#jumpbuttonispressed) changes from false to true.\r\n\r\n### JumpButton.OnRelease\r\n```\r\nJumpButton.OnRelease: RBXScriptSignal\r\n```\r\nAn `RBXScriptSignal` that fires whenever the result of [`JumpButton.isPressed`](#jumpbuttonispressed) changes from true to false.\r\n\r\n### JumpButton.isPressed\r\n```\r\nJumpButton.isPressed(): boolean\r\n```\r\nReturns true if the jump button is currently being held down, false otherwise.\r\n\r\n### JumpButton.useIsBuffered\r\n```\r\nJumpButton.useIsBuffered(): boolean\r\n```\r\nReturns whether or not there is a buffer, based on the default buffer duration. Specifically, if the time since the buffer began is less than or equal to the default buffer duration. If there is no default buffer duration, it will return true if there is a buffer start, false otherwise.\r\n\r\nThis function will automatically kill the buffer. If you do not wish to do so, use [`JumpButton.peekIsBuffered`](#jumpbuttonpeekisbuffered).\r\n\r\n### JumpButton.peekIsBuffered\r\n```\r\nJumpButton.peekIsBuffered(): boolean\r\n```\r\nReturns whether or not there is a buffer, based on the default buffer duration. Specifically, if the time since the buffer began is less than or equal to the default buffer duration. If there is no default buffer duration, it will return true if there is a buffer start, false otherwise.\r\n\r\nThis function will not affect the buffer start. If you want to automatically kill the buffer, use [`JumpButton.useIsBuffered`](#jumpbuttonuseisbuffered).\r\n\r\n### JumpButton.useBufferStart\r\n```\r\nJumpButton.useBufferStart(): number?\r\n```\r\nReturns the current buffer start, if any. The buffer start is a timestamp from `os.clock`. It is not affected by the default buffer duration.\r\n\r\nThis function will automatically kill the buffer. If you do not wish to do so, use [`JumpButton.peekBufferStart`](#jumpbuttonpeekbufferstart).\r\n\r\n### JumpButton.peekBufferStart\r\n```\r\nJumpButton.peekBufferStart(): number?\r\n```\r\nReturns the current buffer start, if any. The buffer start is a timestamp from `os.clock`. It is not affected by the default buffer duration.\r\n\r\nThis function will not affect the buffer start. If you want to automatically kill the buffer, use [`JumpButton.useBufferStart`](#jumpbuttonusebufferstart).\r\n\r\n### JumpButton.killBuffer\r\n```\r\nJumpButton.killBuffer(): ()\r\n```\r\nSets the current buffer start to nil, effectively preventing code from detecting a buffer. It will be set to a number when the jump button is pressed again.\r\n\r\n### JumpButton.setDefaultBufferDuration\r\n```\r\nJumpButton.setDefaultBufferDuration(newBufferDuration: number?): ()\r\n```\r\nSets the default buffer duration for the library. The default buffer duration is used for [`JumpButton.useIsBuffered`](#jumpbuttonuseisbuffered) and [`JumpButton.peekIsBuffered`](#jumpbuttonpeekisbuffered). If `newBufferDuration` is nil, these functions will not have a maximum time.\r\n\r\n### JumpButton.setAutoKillOnJump\r\n```\r\nJumpButton.setAutoKillOnJump(shouldAutoKill: boolean): ()\r\n```\r\nSets if JumpButton should automatically kill the buffer when `Humanoid.Jumping` fires on the local player's humanoid. Defaults to true.","readmeTruncated":false}