Forest Logo
search
package_2

objectpool

By @gamingguy84

Roblox

Mirrored

ObjectPool

A high-performance generic object pooling module for Roblox Instances written in strict Luau.

Designed for systems that frequently create and destroy Instances such as:

  • Bullets
  • Particle effects
  • NPCs
  • Sound emitters
  • UI elements
  • Trails and beams
  • Temporary gameplay objects

The module minimizes allocation pressure and garbage collection overhead by reusing cloned Instances instead of repeatedly allocating new ones.

Features

  • Strict Luau support (--!strict)
  • Generic typing
  • Explicit self parameters (no colon syntax)
  • Dynamic pool expansion
  • Prewarming support
  • Acquire / Release lifecycle
  • Bulk release support
  • Destroy support
  • Optional reset callbacks
  • Defensive validation
  • Low allocation overhead
  • Automatic transient state reset

Installation

Place Notwork in an accessible location (e.g. ReplicatedStorage)

Require it normally via require

Example:

local bulletTemplate = ReplicatedStorage.Assets.Bullet

local bulletPool = ObjectPool.new(
	bulletTemplate,
	100, -- initial size
	25   -- expansion size
)

API

ObjectPool.new

Creates a new pool.

ObjectPool.new(
	template: T,
	initialSize: number?,
	expandSize: number?,
	reset: ((instance: T) -> ())?
): Pool<T>

ObjectPool.Acquire

Acquires an Instance from the pool.

ObjectPool.Acquire(
	self: Pool<T>,
	parent: Instance?
): T

ObjectPool.Release

Returns an Instance to the pool.

ObjectPool.Release(
	self: Pool<T>,
	instance: T
)

The module throws errors for:

  • Releasing foreign instances
  • Double releasing
  • Using a destroyed pool

ObjectPool.ReleaseAll

Releases every active object.

ObjectPool.ReleaseAll(
	self: Pool<T>
)

ObjectPool.Prewarm

Adds additional preallocated Instances.

ObjectPool.Prewarm(
	self: Pool<T>,
	amount: number
)

ObjectPool.Expand

Manually expands the pool.

ObjectPool.Expand(
	self: Pool<T>,
	amount: number?
)

If no amount is specified, ExpandSize is used.

ObjectPool.Destroy

Destroys the pool and all managed Instances.

ObjectPool.Destroy(
	self: Pool<T>
)

ObjectPool.GetAvailableCount

Returns available pooled objects.

ObjectPool.GetAvailableCount(
	self: Pool<T>
): number

ObjectPool.GetInUseCount

Returns currently active objects.

ObjectPool.GetInUseCount(
	self: Pool<T>
): number

Automatic Reset Behavior

The module automatically resets common transient state when objects are released.

BasePart properties:

  • AssemblyLinearVelocity = Vector3.zero
  • AssemblyAngularVelocity = Vector3.zero
  • Anchored = false
  • Parent = nil

ParticleEmitter properties:

  • Enabled = false

Trail properties:

  • Enabled = false

Beam properties:

  • Enabled = false

Sound properties:

  • Playing = false
  • TimePosition = 0

Custom Reset Logic

You may provide a custom reset callback.

local function resetBullet(bullet)
	bullet.Transparency = 0
	bullet.Color = Color3.new(1, 1, 1)
end

local bulletPool = ObjectPool.new(
	bulletTemplate,
	100,
	25,
	resetBullet
)

The custom reset callback executes after built-in transient reset behavior.

Type Support

The module is fully generic.

local pool: ObjectPool.Pool<BasePart>

Works with any Roblox Instance subtype.

Example: Bullet System

local ObjectPool = require(ReplicatedStorage.Packages.ObjectPool)

local bulletTemplate = ReplicatedStorage.Assets.Bullet

local bulletPool = ObjectPool.new(
	bulletTemplate,
	200,
	50
)

local function fireBullet(origin: CFrame)
	local bullet = ObjectPool.Acquire(
		bulletPool,
		workspace.Projectiles
	)

	bullet.CFrame = origin
	bullet.AssemblyLinearVelocity =
		origin.LookVector * 500

	task.delay(5, function()
		ObjectPool.Release(bulletPool, bullet)
	end)
end

Performance Notes

Object pooling significantly reduces:

  • Instance allocation spikes
  • Garbage collection pauses
  • Physics initialization overhead
  • Replication churn

Best suited for:

  • High-frequency spawning systems
  • Fast projectiles
  • Visual effects
  • Temporary gameplay entities

Best Practices

  • Prewarm Large Systems
ObjectPool.Prewarm(pool, 500)

Avoid runtime allocation spikes during gameplay.

  • Always Release

Every acquired object should eventually be released.

Bad:

local bullet = ObjectPool.Acquire(pool)

Good:

local bullet = ObjectPool.Acquire(pool)

ObjectPool.Release(pool, bullet)
  • Avoid Manual Destruction

Do not manually destroy pooled objects.

Bad:

bullet:Destroy()

Good:

ObjectPool.Release(pool, bullet)

Package Details

Install command (Click to copy)


Version

0.0.2

License

MIT

check_circle

Safe for commercial use

Automated license review — not legal advice.