npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@rbxts/region

v0.0.3

Published

Simple API for checking when a specified part enters/exits a region using promises.

Downloads

5

Readme

region

A simple promise-based roblox-ts API that detects when parts enter defined regions.

But Why?

This package was adapted from the codebase of a few games I'd worked on. I had originally created this out of a need to heavily optimize region-based events across the client and server. Although it never got to realize its full potential, the improvements over previous methods was significant enough that I decided to spin this off into a separate API.

Most region APIs rely on events, which generally involve a lot of busy waiting in the background. This API relies on promises- and only runs when you need it to. Additionally, promises make it easy to deal with multiple method calls, even without provided wrappers such as RegionUnion or RegionNegation. All that combined with a highly efficient codebase makes for code that is both performant and extensible.

Usage

Region objects all inherit the same abstract class, making it easy to negate and union them.

Region

Region is an abstract class, but it's inherited by all classes in the API.

Region.enteredRegion

enteredRegion(part: BasePart, timeout?: number), step?: () => Promise<unknown>: Promise<void>

Returns a promise that resolves when the provided part enters the region.

step is an optional argument (that normally defaults to task.wait(0.1) for most Region classes) which can be used to provide a function that yields for a certain amount of time. This can be useful for tying checks to a specific event.

Region.leftRegion

leftRegion(part: BasePart, timeout?: number, step?: () => Promise<unknown>): Promise<void>;

Returns a promise that resolves when the provided part leaves the region.

step is an optional argument (that normally defaults to task.wait(0.1) for most Region classes) which can be used to provide a function that yields for a certain amount of time. This can be useful for tying checks to a specific event.

Region.isInRegion

isInRegion(point: Vector3): boolean

Returns true if the point is in the Region, false if not.

BasePartRegion

The most basic of these is the BasePartRegion which can either be created using the properties or an existing BasePart.

const regionPart = new Instance("Part");
regionPart.Position = new Vector3(0, 0, 0);
regionPart.Size = new Vector3(10, 20, 10);
regionPart.Shape = Enum.PartType.Cylinder;

const region = Region.fromPart(regionPart)

Alternatively, BasePartRegions can be created using the position CFrame, size, and shape of the desired region.

const region = new Region(new CFrame(0, 0, 0), new Vector3(10, 10, 10), Enum.PartType.Cylinder);

constructor

constructor(
  location: CFrame,
  size: Vector3,
  shape: Enum.PartType,
)

BasePartRegion.fromPart

fromPart(part: BasePart): BasePartRegion

An alternative to the constructor, this allows for the creation of BasePartRegions using BaseParts.

RegionUnion

RegionUnions are a great way to combine regions, though you can technically do it yourself with a little Promise.race. The main reason for using RegionUnions though, is that they're compible with both other RegionUnions and RegionNegations.

RegionUnion has all the same methods as BasePartRegion, it just combines the functionality of multiple BasePartRegions.

const regionPart0 = new Instance("Part");
regionPart0.Position = new Vector3(0, 0, 0);
regionPart0.Size = new Vector3(10, 20, 10);
regionPart0.Color = new Color3(0, 1, 0);
regionPart0.Shape = Enum.PartType.Cylinder;

const regionPart1 = new Instance("Part");
regionPart1.Position = new Vector3(0, 0, 0);
regionPart1.Size = new Vector3(10, 10, 10);
regionPart1.Color = new Color3(1, 0, 0);
regionPart1.Shape = Enum.PartType.Ball;

const region = new RegionUnion([BasePartRegion.fromPart(regionPart0), BasePartRegion.fromPart(regionPart1)]);

constructor

constructor(regions: Region[])

RegionUnion.getRegions

getRegions(point: Vector3): Region[]

Returns an array of regions (if any) a point is in.

RegionNegation

Like RegionUnion, RegionNegation takes multiple regions and combines them into a single region with the same methods as the BasePartRegion. The main difference is that the constructor takes a Region (can be any of the classes) and another Region to negate from that. Basically just like unions in Roblox, this allows for the formation of complex shapes.

const regionPart = new Instance("Part");
regionPart.Position = new Vector3(0, 0, 0);
regionPart.Size = new Vector3(10, 20, 10);
regionPart.Shape = Enum.PartType.Cylinder;

const negationPart = new Instance("Part");
negationPart.Position = new Vector3(0, 0, 0);
negationPart.Size = new Vector3(10, 10, 10);
negationPart.Shape = Enum.PartType.Ball;

const region = new RegionNegation(BasePartRegion.fromPart(regionPart), BasePartRegion.fromPart(negationPart));

constructor

constructor(region: Region, negation: Region)

Example

This is a short script that prints when a part enters or exits a region:

import { BasePartRegion, RegionNegation } from "@rbxts/region";
import { Workspace } from "@rbxts/services";

const regionPart = new Instance("Part");
regionPart.Position = new Vector3(0, 0, 0);
regionPart.Size = new Vector3(10, 20, 10);
regionPart.Shape = Enum.PartType.Cylinder;
regionPart.Anchored = true;
regionPart.Transparency = 0.5;
regionPart.Color = new Color3(0, 1, 0);
regionPart.Parent = Workspace;

const negationPart = new Instance("Part");
negationPart.Position = new Vector3(0, 0, 0);
negationPart.Size = new Vector3(10, 10, 10);
negationPart.Shape = Enum.PartType.Ball;
negationPart.Anchored = true;
negationPart.Transparency = 0.5;
negationPart.Color = new Color3(1, 0, 0);
negationPart.Parent = Workspace;

const region = new RegionNegation(BasePartRegion.fromPart(regionPart), BasePartRegion.fromPart(negationPart));

const part = new Instance("Part");
part.Size = new Vector3(1, 1, 1);
part.Position = new Vector3(0, 0, 0);
part.Anchored = true;
part.Shape = Enum.PartType.Ball;
part.Parent = Workspace;

function onEnter() {
	print("entered!");
	region.leftRegion(part).then(onLeave);
}

function onLeave() {
	print("left!");
	region.enteredRegion(part).then(onEnter);
}

region.enteredRegion(part).then(onEnter);

https://youtu.be/rmOMUbAeya0