

[spoiler][ModeSeven is a publicly avaliable font developed by Andrew Bulhak][/spoiler]
Whats new in V1.31 - 3.3.2026
- Added (proper) support for the Dogu15 rig after users @Int_lligence and @jonmxI found issues with overlapping textures.
This is a minor update to 1.3, Dedicated spritemaps for other meshed rigs are still experimental and WIP.
What's new in V1.3 - 7.2.2026
- Changed “spritesheet” to “spritemap”, the modulescript which applies the clothing onto the character’s body.
- Spritemaps are now stored in their own locations.
- (EXPERIMENTAL) Added dedicated spritemap profiles for Robloxian 2.0 and Man Rig
- Added function getObjectId() which returns the object’s memory location as a string. Used for future use only
- Added function getSpritemaps() which returns a clone of the spritemaps in the _SPRITEMAP table
- For the optional_spritemap parameter for the new() constructor, You can either pass the modulescript instance (spritemap script) or pass on the name of the spritemap.
- Moderate code adjustments
What's new in V1.2 - 10.10.2025
- The size and position of the sprites now change when the body proportion changes. Before, Changing the body proportions e.g. Height, Width would result to the clothing becoming off.
- Look at the below example comparing both behaviours of ACC 1.2 (current) and 1.1 (previous) when changing body proportions

- Look at the below example comparing both behaviours of ACC 1.2 (current) and 1.1 (previous) when changing body proportions
- Added the method “ChangeTexturePropertyFromBodyPartName()” which changes any property of a
Textureinstance from the body part name - Added IMAGE_SIZE global in the spritesheet modulescript where you can now specify your own image sprite size.
- Updated spritesheet_applicator
- Updated SpritesheetR15
What's new in V1.1 - 23.9.2025
I have now fixed the issue on R15 rigs where the clothing detail (on arms and legs) just disappear in the joints portion of the body part.
- Added method
getClothingTexturesFromBodyPartName(bodyPartName)which returns all clothing textures from the given body part name - Added spritesheet data
jointsNegateOffsetR15which allows the clothing textures to not stretch over R15 body joints
Older Releases
advanced_classic_clothing_1.3.rbxm (14.1 KB)
advanced_classic_clothing_1.2.rbxm (12.4 KB)
advanced_classic_clothing_1.0.rbxm (8.5 KB)
advanced_classic_clothing_1.1.rbxm (10.5 KB)
About ACC:
Advanced Classic Clothing is my first Open-source project which reimplement how classic clothing is wrapped around a standard humanoid rig. And with that I present Advanced classic clothing!
This modulescript brings in some QOL improvements for 2D classic clothing which can be used in game where flexible character creation is implemented. This eliminates the need to re-upload the same piece of clothing with minor changes. This makes the old 2D classic clothing infinitely customizable and more expressive in my opinion.
Now I wrote this entirely from scratch in around 4 days which means there are lots of bugs in issues listed under Known issues which I suggest you read first
Features include:
- Support for high resolution textures
(standard Shirt and Pants instance already support HQ clothing)(see post 4) - Allow for classic clothing to layer on top of each other (with Zindex support)
- Overlap over the dreaded modesty layer for R15 rigs, (an unintentional feature)
- ANIMATE clothing by using
OffsetStudsUandOffsetStudsV - Ability to create custom profiles for different clothing e.g. 2D shoes, gloves, belts, etc
- Literally anything that the standard Texture property offers, excluding MaterialVariant
Potential uses of ACC
- Any roleplay/LARP game which offers customizable uniform [spoiler](look at me!) shout ER:LC[/spoiler]
- Programmable differences to minor parts of clothes/objects within clothes e.g. Colour, Transparency
- Avatar clothing customization menu/Dress-up games
- Retain classic clothing after the
humanoidis deleted (e.g. for a Statue or a permanent ragdoll)
BASIC USAGE - Get started
Step 1
First you need to aquire Advanced Classic Clothing
Now, to use advanced classic clothing, you need to require it.
--[[
Type: Script/LocalScript
RunContext: Legacy/Client/Server
]]
local advanced_classic_clothing = require(path.to.advanced_classic_clothing)
Step 2a - Add Shirt
To apply a clothing to a character model, you now need to create a new object:
- The first parameter is the name of the shirt, It can be anything you like.
- Second is the image Id of the shirt
- Third is a valid R6 or R15 character model
- and Finally the type of clothing. Defaults is “shirt” or “pants”. It is not case sensitive.
local shirt_id= "rbxassetid://119117418244968" -- Has to be an ImageID, not a clothing ID!!
local character = path.to.your.character
local new_shirt = advanced_classic_clothing.new("My_Shirt",shirt_id,character,"shirt")
Now the script detects and uses the correct spritesheet data for the specific humanoid and applies each face of the clothing image to the correct side of the bodyparts.
Now you should get this:
From now on I will continue with the R15 rig. Steps for blocky R6 is the same.
Step 2b - Add Pants
Now we want to add in the pants. You simply do advanced_classic_clothing.new() again except you change the image Id to a pants image and set the clothingType to “pants”
local pants_id = "rbxassetid://77995515363451"
local new_pants = advanced_classic_clothing.new("My_Pants",pants_id,character,"pants")
Now you should get this:
Step 3 - Change ZIndex
Now you see the straps are overlapping over the jacket. Normal firefighting gear has the straps under the jacket. We can fix this by using the ChangeZIndex method stored in the advanced_classic_clothing object.
new_shirt:ChangeZIndex(1)
new_pants:ChangeZIndex(0)
--[[
above code is functionally the same as:
new_shirt:ChangeTextureProperty("ZIndex",1)
new_pants:ChangeTextureProperty("ZIndex",0)
]]
Now the shirt is on top of the textures for the pants torso, resulting to this:
Step 4 - Change clothing properties
Finally, we want to change the property of the texture. There is a method which takes in the name of the property which is part of the Texture class and allows us to change the value of it.
You can change the pants transparency to 0.75 using this:
new_pants:ChangeTextureProperty("Transparency",0.75)
Step 5 - Deleting the object
To delete the advanced_classic_clothing object but retain the clothing textures on the character you use:
new_shirt:DestroyMethods()
Doing so means that you can no longer change Texture properties or the ZIndex.
To remove the object and all the clothing textures:
new_shirt:Destroy()
--[[
This method uses the spritesheet_applicator's DestroyAllInstances()
method to remove any created sprites..
]]
And that’s it! You have basically mastered the arts of adding advanced classic clothing!
Final code
local advanced_classic_clothing = require( game:GetService("ReplicatedStorage"):WaitForChild("advanced_classic_clothing"))
local shirt_id= "rbxassetid://119117418244968"
local character = script.Parent
local new_shirt = advanced_classic_clothing.new("My_Shirt",shirt_id,character,"shirt")
local pants_id = "rbxassetid://77995515363451"
local new_pants = advanced_classic_clothing.new("My_Pants",pants_id,character,"pants")
new_shirt:ChangeTextureProperty("ZIndex",1)
new_shirt:ChangeZIndex(1)
new_pants:ChangeZIndex(0)
new_pants:ChangeTextureProperty("Transparency",0.75)
new_shirt:Destroy()
ADVANCED - Create your own spritesheet and Animate 2D clothing
If you want to create your own spritesheet modulescript then see this post I made detailing more information about it.
I have taken inspiration from this guide from the ROBLOX Docs which allows me to animate clothing and make some interesting effects.
I have created this cloud texture using PaintDotNet and uploaded it as an image with the same resolution and aspect ratio as a clothing template. I then binded the movement to OffsetStudsU to create this effect:

Now you can create your own animated retroslop
Code
local advanced_classic_clothing = require( game:GetService("ReplicatedStorage"):WaitForChild("advanced_classic_clothing"))
local shirt_id= "rbxassetid://113746328831574"
local character = script.Parent
local new_shirt = advanced_classic_clothing.new("My_Shirt",shirt_id,character,"shirt")
local pants_id = "rbxassetid://113746328831574"
local new_pants = advanced_classic_clothing.new("My_Pants",pants_id,character,"pants")
new_shirt:ChangeTextureProperty("ZIndex",1)
new_shirt:ChangeZIndex(1)
new_pants:ChangeZIndex(0)
local runservice = game:GetService("RunService")
local colour = Color3.new(0.666667, 1, 1)
new_shirt:ChangeTextureProperty("Color3",colour) -- light blue
new_pants:ChangeTextureProperty("Color3",colour)
function animate(deltatime,clothing_assets,studsPerTick)
local real = (1/60) / deltatime
for _,textures in clothing_assets do
if textures:IsA("Texture") then
textures.OffsetStudsU += (studsPerTick * real)
end
end
end
local shirt_assets = new_shirt:getAllClothingTextures()
local pants_assets = new_pants:getAllClothingTextures()
runservice.Heartbeat:Connect(function(dt)
animate(dt,shirt_assets,0.01)
animate(dt,pants_assets,-0.01)
end)
How it works
This takes a standard classic clothing template and uses Texture instances to recreate each side of a body part with the applied clothing.
I used my spritesheet modulescript which converts bitmap pixels into Roblox studs and applies its offsets and sizes to a texture accordingly. (It does this by taking the 2D size of an object and the resolution of the target spritesheet image)
The main script reads a table containing the name of the bodypart where it then contains information on how and where to apply the faces of a 2D clothing asset to that bodypart.
API Methods
| Method/Constructor Name | Method Description |
|---|---|
| new(name : string,imageId,humanoidModel : Humanoid,clothingType : string,optional_spriteSheetdata : string) : advanced_clothing_object | Creates a new advanced_classic_clothing object (optional_spriteSheetdata is only needed if you want to force another spritesheet) |
| ChangeTextureProperty(property : string,value : any) : nil | Changes the texture property using its name and applies it with the specified value |
| ChangeZIndex(zindex : number) : nil | Change the ZIndex value for all the texture instances |
| getClothingType() : string | Returns the clothing type parsed in new() |
| getAllClothingTextures() : {} | Returns a cloned table containing all the Textures that make up the clothing |
| [V1.1] getClothingTexturesFromBodyPartName(bodyPartName : string) : {} | Returns all clothing textures (if any) from the given body part name |
| [V1.2] ChangeTexturePropertyFromBodyPartName(bodyPartName : string,property : string, value : any) : nil | Apply the specified property and value of textures specified in bodyPartName |
| [V1.3] getSpriteMaps() : {} | Returns a clone of the spritemap table stored in _SPRITEMAP |
| DestroyMethods() : nil | Destroys the advanced_classic_clothing object but keeps the textures (effectively making it read-only) |
| Destroy() : nil | Same as DestroyMethods but removes all clothing textures |
Example explanation
EDIT: Made it shorter and removed incorrect information, mb
In the example I used my firefight (fire fighter) outfit I have saved on ROBLOX, mainly because I have the original .pdn files that made up those clothing assets.
The pants and shirt images are split into different layers. From the base clothing background to the sowlines and even to small details e.g. the radio and uniform nameplate.
Then the images are converted into black and white with some of the layers requiring a higher contrast or brightness, without losing some of the details. Brighter areas of the image allow different colours to be applied while the darker details have no effect in the change of colour
Each of those layers get their own advanced_layerable_clothing object where from there contains methods to modify all it’s Texture properties, from the image colour, transparency and even the ZIndex.
Known issues
- (R6) Blocky rig clothing does not wrap around the beveled edges
- This is because the Texture property thinks there is no mesh applied which results to it not wrapping properly. Purely a visual bug and if your game aesthetic don’t require beveled edges on characters, then this bug may be a feature for you.
- (R6) R6 with meshed parts has clothing displayed incorrectly
- Literally don’t even try, I even mentioned that the blocky R6 is only supported.
- (R6 + R15) Some of the textures are rotated incorrectly
e.g. Feet treads are rotated heel first
- I can’t really find a fix for this, you might just rotate the problem bottom hands and feet faces up-side-down using an image editor.
- (R6 + R15) Clothing with alpha has sharper borders
- This is not really an issue, rather an unintentional feature (but I still feel the need to mention it), If you have a clothing asset that has transparent areas, you might find them to have a border around non-transparent parts of the image, It is just how the image resampler works when stretching an image that is not it’s native size. Bet they go well with the highlight property and create some anime-like borders.
- Clothing appears darker than usual
- This is purely a lighting issue, it is noticeable on certain devices and on the highest quality level in the settings. Unfortunately there is no fix for this issue.
Disadvantages
The biggest issue was writing down spritesheet profiles for the different rig types. R6 is easy to manage, however R15 took 350 lines of code and one entire night to complete. Thankfully, for both R6 and R15 I have written a default rig profile for you to read and make changes to.
There is also the issue with potentially spamming a bunch of textures into a small area. print(6 * 14) --84+ possible texture instances in r15!!!!The majority of us may not feel the performance impact[spoiler] (even with a computer from 2011)[/spoiler] but those who have low end devices may feel the performance impact this may present (though do correct me on that)
And even tho I mentioned R6 many times, I still don’t recommend it’s usage due to how severely limited; the mordern stuff that is just broken compared to R15. ROBLOX’s choice to deprecate R6 is a whole other discussion.
Image gallery
Black and white layars which contains components of the shirt(Bug) Bottoms of hands and feet are rotated the wrong way
(Bug) Why you shouldn’t use ACC with R6 and MeshParts.
Standard shirt instance (left) and Advanced Classic Clothing (right). Notice how the details around sowlines and the reflectors are more sharper. Honestly gives out some Borderlands vibes to it.
Remarks
Other useful/related resources:
- The *Proper* Way to Futureproof R6
- OP @SubtotalAnt8185 created a tutorial to apply R6 to R15. Also had issues applying 2D clothes to the custom rig although I haven’t personally tested yet
- 1.0 [Blocky] Layered Clothing - Resources
- Layered clothing using 3D models (UGC)
- And this model where I used the spritesheet applicator for the first time
*Because of ROBLOX’s excellent support for R6, this is only limited to the default (blocky) rig, and even that has some slight issues. Don’t worry, R15 is no better.
Proposed project name change
The current name for this project is “Advanced Classic Clothing”. I’ve been debating whether to change the name to “B2C” (Better 2D clothing), mainly because “advanced Classic Clothing” doesn’t really roll-off the tongue. imo B2C sounds cooler too.


























