EasySprite | Spritesheet Handler & Animator

Easy Sprite!


Roblox Store | Github

This module is a forked version and spiritual successor of SimpleSprite by @0bBinary. With added quality of life changes and bugfixes.

This has been designed with the intent to be as lightweight as possible, non-intrusive and easily expandable.

I’m also developing a game which utilizes this module, so I will personally maintain it.


  • It abstracts (simplifies) the grid math used in Sprite Sheets so you don’t have to deal with it.
  • Allows you to flip images!, save space in your sprite sheet for left-right animations.
  • Comes bundled with a module that allows you to set custom playback (fps) for your spritesheets
  • The library is strictly typed, it’s unlikely you will need to look at the API.
  • Lightweight, in total it’s around ~200 lines of code
  • Can be used from Server or Client

Differences from SimpleSprite

  • No restrictions to sizing your ImageLabel object, can use either scale or offset
  • No naming of cells
  • No lists (replaced by SpriteSequencer)
  • Animation Playback speed based on fps rather than waitLength
  • Only ImageLabel support.


This only has two objects: SpriteSheets and Sequences

local EasySprite, SpriteSequence = require(pathToEasySprite), require(pathToSpriteSequencer)

--lets create our spritesheet:
local mySpriteSheet = EasySprite.new(
	'rbxassetid://00000000000', --assetId of the texture
	Vector2.new(700, 700), --pixel dimensions of the texture (width, height)
	Vector2.new(100, 100) --pixel cell size (width, height)

mySpriteSheet.display(1) --displays the first cell (counted from left to right)
mySpriteSheet.flip() --flips the spritesheet horizontally

--[[ now lets playback our sprite sheet!
    create a sequence from cell 1 to 10  ]]
local mySequence = SpriteSequence.fromRange(mySpriteSheet, 1, 10)
mySequence.play(framesPerSecond, isLooping)




--creates spritesheet
handler.new(ImageLabel, assetId: string, imgSize: Vector2, cellSize: Vector2)

SpriteSheet.display(cell: number) --shows cell at position
SpriteSheet.flip() --flips cell horizontally
SpriteSheet.isFlipped(): boolean --true if currently flipped
SpriteSheet.extend(spritesheet2) --appends all cells to the end of SpriteSheet

SpriteSheet.totalCells --the total cells in the sheet
SpriteSheet.currentCell --currently displaying cell


--creates sequence from list of cells
handler.new(spritesheet, cells: {number}): Sequence
--creates sequence from range
handler.fromRange(spritesheet, from: number, to: number): Sequence

Sequence.play(fps: number, looping: boolean): void
--[[NOTE: playing more than one sequence on a single image label
   simply overwrites the previous one]]
Sequence.stop(): void
Sequence.isPlaying(): boolean

This is my first ever published resource, hope you enjoy!



Very Nice!!!, I Will deff use this, Could you please provide example files/place?, like the one seen at the top of the post, it would be really helpful to check some things and test them

1 Like

Here you go! this is the file I used for the showcase
Showcase.rbxl (58.5 KB)

Updated showcase to v1.1.1

1 Like

While i was testing the module, i noticed a error, if you put Vector2.one * 700 in image size and Vector2.one * 100 in the cell size, it will work, but if you put another value, it will throw a error, is this normal?, because i am trying to test more sizes even if it doesn’t, but i don’t want it to throw a error so it stops working, the error is “index nil out of range in spritesheet” coming from that, even if the range it’s correct (0 , 47), anyways, do you recommend any way to know the correct cell size and image size for any spritesheet ?, is there any website for that?

this is my spritesheet

hmm? its meant to work with your spritesheet’s image size & cellsize.

Sorry if the example file is confusing, Vector2.one * 700 is the same as doing Vector2.new(700, 700)
The spritesheet I used in my example file is 700x700

this is what you’re meant to do:

you’re supposed to set the image size to your sprite image’s pixel size when creating the spritesheet.

In the case of the spritesheet you posted, it goes over Roblox’s 1024x1024 limit, (yours is 3486x3486). Roblox downscales your image down to 1024x1024 if you’re over the limit (which can distort and make the proportions of your image inconsistent)

yes there is this tool which can help you figure it out:


after downscaling and using the linked tool, this is my result!
imgsize Vector2.new(1024,1024)
cellsize Vector2.new(146,146)

1 Like

Due to this limitation, I’m currently working on an update to the module that will allow you to merge separate spritesheets (separate image urls) to have a single, continuous spritesheet.

Should be releasing this later today


thank you so much

This text will be blurred

1 Like

Version 1.1.0

Sprite extensions! (Image Merging)

Too many sprites for a single image? You can now combine multiple imageids into a single spritesheet!

New API:

sheet1.extend(sheet2) :
append all the cells from sheet2 to the end of sheet1 !


local sheet1 = EasySprite.new(

local sheet2 = EasySprite.new(
	Vector2.new(1000, 600),
sheet1.extend(sheet2) --adds all sheet2 cells to end of sheet1

this means you can create one continuous sequence from multiple imageIds!

local sequence = Sequencer.fromRange(sheet1, 1, sheet1.totalCells)
sequence.play(30, true)

Version 1.2.0

Native Codegen

Both EasySprite and Sequencer now use --!native as it has demonstrably shown performance improvements


New API:

Sequence.isPlaying(): boolean
returns true if the sequence is currently being played with sequence.play()

1 Like

Patch 1.2.1

further optimizations on spritesheet.display(),
replaced costly assertion concat with if statement error