# API Reference

Purse unlocks APIs for the CoreGui backpack which were previously locked to other CoreGui scripts. To access the APIs, just require Purse like any other [module script](https://create.roblox.com/docs/reference/engine/classes/ModuleScript).

## Methods¶

The following code sample, placed within a child `LocalScript` of a `GuiButton`, uses `OpenClose()` to toggle the inventory on the button's `Activated` event.

Inventory Toggle Button

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15

    --!strict

    local ReplicatedStorage = game:GetService("ReplicatedStorage")

    local Purse = require(ReplicatedStorage.Purse)

    local button = script.Parent

    local function onButtonActivated()
        if Purse.OpenClose then
            Purse.OpenClose()
        end
    end

    button.Activated:Connect(onButtonActivated)

### OpenClose¶

    OpenClose(): ()

Toggles whether or not the inventory is visible.

### IsInventoryEmpty¶

    IsInventoryEmpty(): boolean

Returns true if the inventory is empty.

## Properties¶

### IsHotbarVisible¶

    IsHotbarVisible: boolean

Determines whether or not the hotbar is visible.

### IsOpen¶

    IsOpen: boolean

Returns true if the inventory is open.

### ModuleName¶

    ModuleName: string

Returns "Backpack".

### KeepVRTopbarOpen¶

    KeepVRTopbarOpen: boolean

Returns true.

### VRIsExclusive¶

    VRIsExclusive: boolean

Returns true.

### VRClosesNonExclusive¶

    VRClosesNonExclusive: boolean

Returns true.

## Events¶

The following code sample, placed within a child `LocalScript` of `StarterPlayerScripts`, uses `StateChanged` to detect when the inventory is toggled and prints its state to output.

Detect Inventory State

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13

    --!strict

    local ReplicatedStorage = game:GetService("ReplicatedStorage")

    local Purse = require(ReplicatedStorage.Purse)

    Purse.StateChanged.Event:Connect(function(isNowOpen)
        if isNowOpen then
            print("Inventory opened")
        else
            print("Inventory closed")
        end
    end)

### StateChanged¶

    StateChanged(isNowOpen: boolean): BindableEvent

Fires after the inventory is opened or closed.

### BackpackEmpty¶

    BackpackEmpty(): BindableEvent

Fires when the backpack becomes empty.

### BackpackItemAdded¶

    BackpackItemAdded(): BindableEvent

Fires when an item is added to the backpack.

### BackpackItemRemoved¶

    BackpackItemRemoved(): BindableEvent

Fires when an item is removed from the backpack.

Back to top


## :// Intro:

User friendly comprehensive Zone Query module
Zoner attempts to re-implement as many features of ZonePlus (and more).

## :// Background:

I started this project in AUGUST OF 2024 after ZonePlus was declared dead by the community.
This mainly started as a way to make *my FIRST **PUBLIC** resource* making something id use myself and have wanted to remake for a while.

--=====================================================================>

## :// Description:

Stand out feature is the **Parallel Zones implementation**.

In my skewed benchmarking, parallel Zone's doubled the amount of Zones able to be had simultationously (like 10k -> 20k) with no FPS drop (on the simplest detection mode)

--=====================================================================>

- Uses Rojo
- Fully and strictly typed + method documentation
- Lots of settings and customizability per Zone 100+ combinations

- External:
  - Uses [Zignal](https://github.com/Z0SC/Zignal)

- **[!]**: Has script injection for a CollisionGroup and a RemoteEvent used only upon a Zones creation to update tags on the Server *(There was nothing else I could do to keep it fully client sided AND have it operate and react to Streaming Enabled)*

--=====================================================================>

**[NOTICE]:**

*There are much simplier (less bloated) ways to query parts in Zones. This is mainly trying to implement all the features of ZonePlus and more for those who have used ZonePlus and are comfortable with its API. A "drag and drop" replacement with some API name changes.*

--=====================================================================>

## :// Links:

- [Github Repository](https://github.com/skyriverstudios/Zoner)
- [Uncopylocked Place](https://www.roblox.com/games/105253327037689/Zoner-Playground)
- [Marketplace Asset](https://create.roblox.com/store/asset/70548782318425/Zoner)
- [Documentation](https://skyriverstudios.dev/docs/Zoner/docs/intro)

--=====================================================================>


# luau-path

A Luau library to handle file paths based on the Rust [path](https://doc.rust-lang.org/std/path/struct.Path.html) library.

The library can be configured to use unix or windows style separator using the global variable `SYS_PATH_SEPARATOR`. The global should be defined to `'/'` or `'\'`.

When the global is not defined, it will default to `'/'`. If a `LUA_ENV` global variable is set to [`lune`](https://github.com/lune-org/lune), the path separator will be inferred from lune's [process](https://lune-org.github.io/docs/api-reference/process#os) built-in library.

## Installation

Add `luau-path` in your dependencies:

```bash
yarn add luau-path

Or if you are using `npm`:

```bash
npm install luau-path

## Content

This libary exports a `Path` class and the [`AsPath` type](#aspath-type).

```lua
local PathModule = require('@pkg/luau-path')

local Path = PathModule.Path

type Path = PathModule.Path
type AsPath = PathModule.AsPath

Constructors:

- [Path.new](#pathnew)
- [Path.from](#pathfrom)

Static functions:

- [Path.is](#pathis)

Path methods:

- [ancestors](#ancestors)
- [clear](#clear)
- [components](#components)
- [endsWith](#endswith)
- [equal](#equal)
- [extension](#extension)
- [fileName](#filename)
- [filePrefix](#fileprefix)
- [fileStem](#filestem)
- [hasRoot](#hasroot)
- [isAbsolute](#isabsolute)
- [isRelative](#isrelative)
- [join](#join)
- [parent](#parent)
- [pop](#pop)
- [push](#push)
- [setExtension](#setextension)
- [setFileName](#setfilename)
- [startsWith](#startswith)
- [stripPrefix](#stripprefix)
- [toPathBuf](#topathbuf)
- [toString](#tostring)
- [withFileName](#withfilename)
- [withExtension](#withextension)

## AsPath Type

```lua
type AsPath = string | Path | Components

### Path.new

```lua
function Path.new(path: string): Path

Creates a new path from the given `string`.

### Path.from

```lua
function Path.from(path: AsPath): Path

Creates a new path from a `string `or a [`Components`](#components) iterator, or return the given Path object.

This function errors if the value does not satisfy the `AsPath` type.

### Path.is

```lua
function Path.new(value: unknown): boolean

Returns `true` if the given value is a Path.

### toString

```lua
function Path:toString(): string

Converts the path to a string representation.

### toPathBuf

```lua
function Path:toPathBuf(): Path

Creates a new `Path` object that is a copy of the current path.

### isAbsolute

```lua
function Path:isAbsolute(): boolean

Returns true if the Path is absolute, i.e., if it is independent of the current directory.

- On Unix, a path is absolute if it starts with the root, so `isAbsolute` and [`hasRoot`](#hasroot) are equivalent.
- On Windows, a path is absolute if it has a prefix and starts with the root: `c:\windows` is absolute, while `c:temp` and `\temp` are not.

### isRelative

```lua
function Path:isRelative(): boolean

Returns `true` if the Path is relative, i.e., not absolute.

See [isAbsolute](#isabsolute)'s documentation for more details.

Examples

```lua
assert(Path.new("foo.txt"):isRelative())

### hasRoot

```lua
function Path:hasRoot(): boolean

Returns `true` if the Path has a root.

- On Unix, a path has a root if it begins with `/`.
- On Windows, a path has a root if it:
  - has no prefix and begins with a separator, e.g., `\windows`
  - has a prefix followed by a separator, e.g., `c:\windows` but not `c:windows`
  - has any non-disk prefix, e.g., `\\server\share`

Examples

```lua
assert(Path.new("/etc/passwd"):hasRoot())

### parent

```lua
function Path:parent(): Path?

Returns the Path without its final component, if there is one.

This means it returns `""` for relative paths with one component.

Returns `nil` if the path terminates in a root or prefix, or if it’s the empty string.

### ancestors

```lua
function Path:ancestors(): Ancestors

Produces an iterator over Path and its ancestors.

The iterator will yield the Path that is returned if the parent method is used zero or more times. That means, the iterator will yield `self`, `self:parent()`, `self:parent():parent()` and so on. If the parent method returns `nil`, the iterator will do likewise. The iterator will always yield at least one value, namely `self`.

### fileName

```lua
function Path:fileName(): string?

Returns the final component of the Path, if there is one.

If the path is a normal file, this is the file name. If it’s the path of a directory, this is the directory name.

Returns `nil` if the path terminates in `..`.

### stripPrefix

```lua
function Path:stripPrefix(base: AsPath): Path?

Returns a path that, when joined onto base, yields self.

If base is not a prefix of self (i.e., [startsWith](#startswith) returns `false`), returns `nil`.

### startsWith

```lua
function Path:startsWith(base: AsPath): boolean

Determines whether `base` is a prefix of `self`.

Only considers whole path components to match.

### endsWith

```lua
function Path:endsWith(child: AsPath): boolean

Determines whether `child` is a suffix of `self`.

Only considers whole path components to match.

### fileStem

```lua
function Path:fileStem(): string?

Extracts the stem (non-extension) portion of `self:fileName()`.

The stem is:

- `nil`, if there is no file name;
- The entire file name if there is no embedded `.`;
- The entire file name if the file name begins with `.` and has no other `.`s within;
- Otherwise, the portion of the file name before the final `.`

_See Also_

This method is similar to [`filePrefix`](#fileprefix), which extracts the portion of the file name before the _first_ `.`

### filePrefix

```lua
function Path:filePrefix(): string?

Extracts the prefix of `self:fileName()`.

The prefix is:

- `nil`, if there is no file name;
- The entire file name if there is no embedded `.`;
- The portion of the file name before the first non-beginning `.`;
- The entire file name if the file name begins with `.` and has no other `.`s within;
- The portion of the file name before the second `.` if the file name begins with `.`

_See Also_

This method is similar to [`fileStem`](#filestem), which extracts the portion of the file name before the _last_ `.`

### extension

```lua
function Path:extension(): string?

Extracts the extension (without the leading dot) of `self:fileName()`, if possible.

The extension is:

- `nil`, if there is no file name;
- `nil`, if there is no embedded `.`;
- `nil`, if the file name begins with `.` and has no other `.`s within;
- Otherwise, the portion of the file name after the final `.`

### join

```lua
function Path:join(path: AsPath): Path

Creates a new Path with `path` adjoined to self.

If path is absolute, it replaces the current path.

See [`push`](#push) for more details on what it means to adjoin a path.

### withFileName

```lua
function Path:withFileName(fileName: string): Path

Creates a new Path like `self` but with the given file name.

See [`setFileName`](#setfilename) for more details.

### withExtension

```lua
function Path:withExtension(extension: string): Path

Creates a new Path like `self` but with the given extension.

See [`setExtension`](#setextension) for more details.

### components

```lua
function Path:components(): Components

Produces an iterator over the Components of the path.

When parsing the path, there is a small amount of normalization:

- Repeated separators are ignored, so a/b and a//b both have a and b as components.
- Occurrences of . are normalized away, except if they are at the beginning of the path. For example, a/./b, a/b/, a/b/. and a/b all have a and b as components, but ./a/b starts with an additional CurDir component.
- A trailing slash is normalized away, /a/b and /a/b/ are equivalent.

Note that no other normalization takes place; in particular, `a/c` and `a/b/../c` are distinct, to account for the possibility that `b` is a symbolic link (so its parent isn't `a`).

### equal

```lua
function Path:equal(other: Path): boolean

Returns `true` if the current path is equal to the other path.

### push

```lua
function Path:push(path: AsPath): ()

Extends `self` with `path`.

If `path` is absolute, it replaces the current path.

On Windows:

- if `path` has a root but no prefix (e.g., `\windows`), it replaces everything except for the prefix (if any) of self.
- if `path` has a prefix but no root, it replaces `self`.
- if `self` has a verbatim prefix (e.g. `\\?\C:\windows`) and `path` is not empty, the new path is normalized: all references to `.` and `..` are removed.

Consider using [`join`](#join) if you need a new Path instead of using this function on a cloned Path.

### pop

```lua
function Path:pop(): boolean

Truncates `self` to `self:parent()`.

Returns `false` and does nothing if `self:parent()` is `nil`. Otherwise, returns `true`.

### setFileName

```lua
function Path:setFileName(fileName: string): ()

Updates `self:fileName()` to `fileName`.

If `self:fileName()` was `nil`, this is equivalent to pushing `fileName`.

Otherwise it is equivalent to calling [`pop`](#pop) and then pushing `fileName`. The new path will be a sibling of the original path. (That is, it will have the same parent.)

### setExtension

```lua
function Path:setExtension(extension: string): boolean

Updates `self:extension()` to `extension` or to `nil` if `extension` is empty.

Returns `false` and does nothing if `self:fileName()` is `nil`, returns `true` and updates the extension otherwise.

If `self:extension()` is `nil`, the extension is added; otherwise it is replaced.

If extension is the empty string, `self:extension()` will be None afterwards, not `""`.

**Caveats**

The new extension may contain dots and will be used in its entirety, but only the part after the final dot will be reflected in `self:extension()`.

If the file stem contains internal dots and extension is empty, part of the old file stem will be considered the new `self:extension()`.

### clear

```lua
function Path:clear(): ()

Clears the path, making it an empty path.

## License

This project is available under the MIT license. See [LICENSE.txt](LICENSE.txt) for details.

## Other Lua Environments Support

If you would like to use this library on a Lua environment, where it is currently incompatible, open an issue (or comment on an existing one) to request the appropriate modifications.

The library uses [darklua](https://github.com/seaofvoices/darklua) to process its code.


## Installation

Navigate to the [releases](https://github.com/ArvidSilverlock/Pilot.lua-Luau-LSP/releases) and download the latest `workspace.zip`, unzip it, and open it in Visual Studio Code.

You'll need to install the [Luau LSP](https://marketplace.visualstudio.com/items?itemName=JohnnyMorganz.luau-lsp) visual studio code extension.

Note that this is, by default, set up for usage with Visual Studio Code. If you're a neovim user or use some other editor, I trust you're smart enough to set it up properly on your own.

## Building From Source

> [!IMPORTANT]
> Do _not_ attempt this route if you are not technically oriented, many have tried, and failed, despite how simple it looks. Read the 'Installation' section if you think you fall into this category.

If you want to contribute, or want more control over the generation, you'll need to install this repo locally with some other tools to run the Luau code.

Install [lune](https://lune-org.github.io/docs), a Luau runtime, note, only install this when the steps require you to, and install it _within_ the specified directory (unless of course, you know what you're doing).

### Steps

git clone https://github.com/ArvidSilverlock/Pilot.lua-Luau-LSP.git
cd Pilot.lua-Luau-LSP

Once you are within the `Pilot.lua-Luau-LSP` directory, you need to install [lune](https://lune-org.github.io/docs).

Then run:

lune run pilot-generate

You should then open the generated `workspace` folder as the root folder in visual studio code.

Due to lune you have to add `--` after `pilot-generate` for any command options to work (i.e., `lune run pilot-generate -- -o ./workspace`).

### Optional

Install [rokit](https://github.com/rojo-rbx/rokit), a toolchain manager, you may have already installed this when installing lune.

Install [darklua](https://darklua.com), which has a Luau file bundler.

Install [selene](https://kampfkarren.github.io/selene), a Luau linter.

## Command Line Options

| Option                                          | Description                                                                                |
| ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--notypes`                                     | Skip generation of Pilot.lua type definitions.                                                                                |
| `--nodocs`                                      | Skip generation of Pilot.lua documentation.                                                                                |
| `--nomodules`                                   | Skip generation of Pilot.lua module definitions.                                                                                |
| `--novscode`                                    | Do not create a `.vscode` folder. This folder typically includes VS Code settings, Luau LSP configurations, code snippets, and a list of recommended extensions.     |
| `--snippet-casing=camel\|snake\|pascal\|manual` | Sets the casing style for variables in the `getp[oa]rt` VS Code snippets. - `manual`: Disables automatic casing based on class names. - Defaults to `camel`. |
| `--snippet-part-message="no "`            | Sets the default error message inserted by the `getpart` snippet.                                                                                |
| `--snippet-port-message="no  on "`  | Sets the default error message inserted by the `getport` snippet.                                                                                |
| `--darklua`                                     | Generate a `.darklua.json` file for DarkLua configuration.                                                                                |
| `--selene`                                      | Generate a `selene.toml` and `pilot.yml` file for Selene linting and Pilot integration.                                                                              |
| `--rokit`                                       | Generate a `rokit.toml` configuration file.                                                                                |
| `--wiki`                                        | Generate markdown files for all documentation in the designated wiki docs directory.                                                                                |
| `-o `                                     | Output directory for all generated files. - Defaults to `./workspace`.                                                                                |
| `--types-dir=<type-directory>`                  | Subdirectory (within the output directory) where types, documentation, and modules are placed. - Defaults to `types`.                                            |

## Credits

The source code for several roblox related projects are included within the `documentation/modules` directory, these include:

- [cxmeel/sift](https://cxmeel.github.io/sift/), under an MIT license.
- [evaera/roblox-lua-promise](https://eryn.io/roblox-lua-promise/), under an MIT license.
- [Ozzypig/repr](https://github.com/Ozzypig/repr/), under a WTFPL license.
- [jaipack17/Nature2D](https://jaipack17.github.io/Nature2D/), under an MIT license.
- [Sleitnick/rbxts-octo-tree](https://github.com/Sleitnick/rbxts-octo-tree/), under an MIT license (which is listed [here](https://www.npmjs.com/package/@rbxts/octo-tree) rather than on the github).

The following are from [Sleitnick/RbxUtil](https://github.com/Sleitnick/RbxUtil) and are all under an MIT license.

- Signal
- Symbol
- TableUtil
- Trove


### I'm Possible

Ever wanted to create 2D games, but step back because Roblox doesn't have a 2D physics engine? Well, now its possible! Use Nature2D to create versatile and smooth simulations and mechanics for your 2D games with minimum effort!

### Extensive

Nature2D is built for you to create possibly anything you can imagine. Its equipped with RigidBodies, Constraints and smooth collisions to help map out your imagination through code! RigidBodies and constraints can potentially be made with almost all UI elements, from Frames to TextBoxes.

### Verlet Integration

The library uses methods of [Verlet Integration](https://en.wikipedia.org/wiki/Verlet_integration) and [Convex Hull Collisions](https://en.wikipedia.org/wiki/Hyperplane_separation_theorem)! Create almost anything you can imagine. From bouncy boxes to destructible structures, even character movement in no time.


### Versatile, composable, predictable

Promises model asynchronous operations in a way that makes them delightful to work with. You can easily chain together multiple async functions and you don't have to worry about accidentally yielding.

### Rich API

This library includes many utility functions beyond the basic functionality which make composing and creating Promises a breeze.

### Cancellation

On second thought, we don't want that value anymore. Promises support cancellation, which allows you to prematurely stop an async task and clean up if needed.

## Why you should use Promises

The way Roblox models asynchronous operations by default is by yielding (stopping) the thread and then resuming it when the future value is available. This model is not ideal because:

  * Functions you call can yield without warning, or only yield sometimes, leading to unpredictable and surprising results. Accidentally yielding the thread is the source of a large class of bugs and race conditions that Roblox developers run into.
  * It is difficult to deal with running multiple asynchronous operations concurrently and then retrieve all of their values at the end without extraneous machinery.
  * When an asynchronous operation fails or an error is encountered, Lua functions usually either raise an error or return a success value followed by the actual value. Both of these methods lead to repeating the same tired patterns many times over for checking if the operation was successful.
  * Yielding lacks easy access to introspection and the ability to cancel an operation if the value is no longer needed.

This Promise implementation attempts to satisfy these traits:

  * An object that represents a unit of asynchronous work
  * Composability
  * Predictable timing


# selene

**selene** is a command line tool designed to help write correct and idiomatic Lua code.

  * **New to selene?** Read the [motivation behind its creation](https://kampfkarren.github.io/selene/motivation.html) and the [CLI guide](https://kampfkarren.github.io/selene/cli/index.html). If you already use [Luacheck](https://luacheck.readthedocs.io/en/stable/), you can read the [Luacheck comparison and migration guide](https://kampfkarren.github.io/selene/luacheck.html).
  * **Don't know what a linter is?** Check out [the wiki on linters](https://en.wikipedia.org/wiki/Lint_\(software\)) about what a linter does and how it's beneficial.
  * **Existing user?** Read the [changelog](https://github.com/Kampfkarren/selene/blob/master/CHANGELOG.md) to learn about any new features or bug fixes.
  * **Interested in what selene lints for?** Read the [list of lints](https://kampfkarren.github.io/selene/lints/index.html).
  * **Interested in contributing to selene's codebase?** Read the [contribution guide](https://kampfkarren.github.io/selene/contributing.html).
  * **Want to discuss selene or get help?** Join the [Roblox OS Community Discord](https://discord.gg/mhtGUS8). Note: selene is not Roblox exclusive, but it started its life for Roblox development.

## License

selene and all its source code are licensed under the [Mozilla Public License 2.0](https://www.mozilla.org/MPL/2.0/).