Back to legacygamers.net
WARPGATE
WARP for 2025-07-16

Custom Hairstyles Guide

Twenty-three hairstyles. The client has forty-five. Character creation stops at 23 because the picker is one fixed grid of 24 cells. Your data.grf already holds sprites and palettes for 45. This page turns all of them on, then shows you how to add your own.

Patch Increase char create Hair limits (Reforged) + Allow 65k Hair StylesClient 2025-07-16 · 175220998Author Neo-Mind, CrazyBebopUpdated 2026-10-30
Requirements
WARP 07-16, rAthena, a data.grf that holds kRO's 45 hair sprites and palettes
You supply
Nothing for kRO's 45: the thumbnails ship with this release. Sprites, palettes and thumbnails for anything you add on top.
Time
About ten minutes to turn on kRO's 45. Adding your own depends on your art.
In short:
  • kRO ships 45 hair sprites but only 23 picker thumbnails. That gap is the whole problem.
  • The missing thumbnails ship with this WARP release: 22 styles, male and female, 44 files. You do not have to make them.
  • Two WARP patches and one server setting turn all 45 on. About ten minutes.
The hair picker, as the client draws it
Page 1 · styles 1-23

Which job are you doing?

The two are separate, and the first one is much shorter. Most people only need it.

Turn on the 45 you already havePath A · about 10 minutes · steps 1 to 3. No art to make. Copy one folder, tick two patches, change one line on the server.
Add hairstyles of your ownPath B · depends on your art · steps 4 to 6. You supply sprites and palettes. The generator further down turns them into picker thumbnails.
Note: Hair colours are a separate patch and a separate job: the Custom Hair Colours guide covers the palettes, the swatch art and the colour count. Paths here use the Korean folder names the client expects; copy them from an extracted data\ tree rather than typing them.

1 Copy in the missing thumbnails

A style with no thumbnail draws as a blank square. It still works when clicked, it just looks broken.

The character creation hair picker, four columns wide, with several cells drawn blank
This is what a missing thumbnail looks like. Not an error, just an empty square a player can still click.

This release ships the 44 files kRO leaves out, 22 male and 22 female, generated from kRO's own sprites:

WARP/Inputs/HairThumbnails/data\ (copy this folder into your client)

Merge it with the data folder already there. That is the whole step. The Korean folder names inside are already correct on disk, so you never have to type them.

Note: Prefer a GRF? Pack the same files at data\texture\À¯ÀúÀÎÅÍÆäÀ̽º\make_character_ver2\ instead. Loose files and GRF entries work equally well; loose is just less work.

2 Patch the client

In WARP, tick these and patch the exe your players actually run. The first two are both required: one makes a style choosable, the other makes it wearable. The third is optional and keeps a palette you forgot from taking the client down.

PatchWhat to enterWhat it does
Allow 65k Hair Styles Hair Style Limit: 45 Lets the client build sprite and palette filenames from the number itself instead of a 43-entry lookup table. Styles above your limit fall back to style 1 instead of leaving the character headless.
Increase char create Hair limits (Reforged) New Char Limits: 45
one field, default 45
Turns the grid's last cell into a next page button and raises the limit that decides which cells are allowed to draw.
Hair colour guard, and extra hair colours
optional, recommended
Hair Colours: 9, the client default Checks a hair colour's .pal exists before the client loads it, and ignores the colour if it does not. Without it a single missing palette crashes the game, which is covered below.
Note: WARP offers to copy the thumbnails for you. At the end of the run, Increase char create Hair limits (Reforged) asks Copy Hair Thumbnails, then Thumbnail Target. Yes writes the same 44 files as step 1 into the folder you pick, under data\texture\...\make_character_ver2. Point it at your client folder and step 1 is done for you. The default puts them beside the patched exe, so you move them across with it. If you already did step 1, answer no.
Note: Colours are a different patch, not a field here. This client draws nine hair colour buttons and Increase char create Hair limits (Reforged) does not touch them, so this dialog has no colour field. To offer more than nine, apply Hair colour guard, and extra hair colours and set its colour count: it pages the swatch row the same way this patch pages the style grid. The full recipe is in the Custom Hair Colours guide. Older WARP builds showed a Hair Color Limit field here; it was read by nothing and has been removed. A profile that still carries the old value keeps working, and the style limit is taken from it.
Note: Keep the two numbers equal. If the creation limit is higher than the Allow 65k limit, a player can pick a style that then loads style 1's hair instead of the one in the thumbnail, with no error. Allow 65k has to be at least as high as the creation limit; equal is the simplest thing to remember.

3 Let the server accept them

The client can now ask for style 40. The server still has to allow it.

conf/import/battle_conf.txt
max_hair_style: 45

Set it to at least your highest style. Without this the character is created with a clamped or default hairstyle and the player's choice is quietly discarded.

Now check it end to end

Create a character, page to the second page, pick something past 23, then log in and confirm the hair matches the thumbnail you clicked. Creation and rendering are separate paths and can fail independently, so checking only one proves half of it.

A character in game wearing hairstyle 40, twin ponytails
Hairstyle 40, in game. Well past the picker's original 23.

What one hairstyle costs you

Everything comes in pairs, because male and female are separate assets all the way down. Each file fails differently when it is missing, which is useful to know before you start.

FileWhat it isMissing it means
<N>_³².spr + .actmale hair worn in game“File not found” popup, character goes headless
<N>_¿©.spr + .actfemale hair worn in gamethe same
¸Ó¸®<N>_³²_<C>.palone per style, gender and colourthe client crashes when a player picks that colour, unless Hair colour guard, and extra hair colours is applied
img_hairstyle<NN>.bmpmale thumbnail, 36 × 37, 24-bitblank cell, but it still selects and still works
img_hairstyle_girl<NN>.bmpfemale thumbnail, same formatthe same

Sprite and palette numbers are written plainly (46_³².spr, ¸Ó¸®46_³²_0.pal). Thumbnail numbers are zero-padded to two digits, so a single-digit style would be img_hairstyle07.bmp. Getting that padding wrong is the most common reason a cell renders blank.

Trap: Missing palettes crash the client.

Ship a palette for every style and every colour you offer, or players will crash the game just by clicking around character creation. This is not a cosmetic gap. Tested on 2026-08-14: pick a style whose palettes are missing, click any hair colour, and the client shows CPaletteRes :: Cannot find File. Press OK and it dies immediately with Exception Type: 0xc0000005, an access violation, and the Gravity error handler offering only Exit.

The reason is in the client: its sprite recolour loop reads palette[index] with no null check, so a palette that failed to load is dereferenced anyway. The client cannot recover from that on its own, and no arrangement of your data files talks it out of it.

Nine colours means nine .pal files per style per gender. For a pack that adds fifty styles for both genders that is 900 files. Plan for it before you commit to the style count, because a half-supplied set is worse than a smaller one.

There is a patch for this

Tick Hair colour guard, and extra hair colours in WARP and the client tests for the .pal before loading it, looking in your GRF as well as in loose data\ files. When the file is missing the colour is quietly ignored: no error box, no crash, the player keeps going. Treat it as a net rather than a substitute for shipping the files, because a guarded style still has no colours to offer. It also guards the other way round, when a player already has a colour selected and then picks a style that has no palettes.

4 Put the files where the client looks

Loose files in data\ are read directly. You do not need to repack a GRF.

Trap: Read this before you create a single folder.

Do not type the Korean folder names. On a Western Windows install the folders in data\ are not named 인간족 or 머리통. They are named with the raw CP949 bytes, which your system codepage renders as Latin-1 mojibake, and that mojibake is the real name.

A GRF stores names as raw bytes and matches them inside the archive with Windows uninvolved. A loose file goes through CreateFileA, so Windows maps those same bytes with the system ANSI codepage. Type real Korean and you create a folder the client never asks for. It does not error. It silently falls back to data.grf and your hairstyles simply do not exist.

So: extract the folders from data.grf with a GRF tool, or copy an existing data\ tree. Both write the correct bytes. Typing the names by hand is the one approach that reliably fails.

FolderShows as (codepage 1252)CP949 bytes
race rootÀΰ£Á·C0 CE B0 A3 C1 B7
hair¸Ó¸®ÅëB8 D3 B8 AE C5 EB
male³²B3 B2
female¿©BF A9
UI texturesÀ¯ÀúÀÎÅÍÆäÀ̽ºC0 AF C0 FA C0 CE C5 CD C6 E4 C0 CC BD BA

Which gives these full paths:

data\sprite\Àΰ£Á·\¸Ó¸®Åë\³²\46_³².spr (male sprite + .act) data\sprite\Àΰ£Á·\¸Ó¸®Åë\¿©\46_¿©.spr (female sprite + .act) data\palette\¸Ó¸®\¸Ó¸®46_³²_0.pal (one per colour) data\texture\À¯ÀúÀÎÅÍÆäÀ̽º\make_character_ver2\img_hairstyle46.bmp data\texture\À¯ÀúÀÎÅÍÆäÀ̽º\make_character_ver2\img_hairstyle_girl46.bmp
Note: Sanity check. Open data\sprite\ in Explorer. If you see Àΰ£Á·, that is correct and your box is codepage 1252. If you see 인간족, you are on a Korean-locale machine and your names are already right for it. The bytes are what matter, not what they look like.

5 Make the thumbnails

Drop your sprites and palettes below and the thumbnails come back out. Everything happens in your browser; nothing is uploaded.

Note: Always generate from the sprite the thumbnail is for. Do that and the picker can never show one hairstyle over another, because the two come from the same file. A pack found in the wild numbered its files 24 to 46 but they were copies of kRO's 23 down to 1 in reverse, so the second page showed the first page's art over completely different hair. The directory listing looked perfectly healthy.
Note: Two looks, and it is your choice. A hair sprite is the whole head, skin and eyes included. kRO's own thumbnails are hair only, cut out like a wig, and that is the default here. Untick Hair only and you get the whole head instead, which reads more like a portrait. Both are valid; the second is what a lot of custom packs use.
Note: Hair only needs the palettes. The cut is worked out from the colour palettes: the slots that change between one hair colour and the next are the hair, and whatever stays the same is face. So drop the .pal files in with the sprites. If a style has none, that tile keeps its face and is marked no palettes, so a fallback never passes silently for a choice.

Drop hair .spr and .pal files here, or click to choose them.
Everything happens in your browser. Nothing is uploaded.

untick to keep the whole head

Names come from the sprite's own filename, so 46_³².spr becomes img_hairstyle46.bmp and 46_¿©.spr becomes img_hairstyle_girl46.bmp. Each file is 36 × 37, 24-bit, with magenta FF00FF as the transparent colour, which is what the picker expects. If a head looks turned away, raise Frame until it faces front and regenerate. Art bigger than 36 × 37 is clipped, not scaled, so a very long style loses its ends. Crop it first if that matters.

Trap: Generate 24 and up, never 1 to 12.

kRO's picker order is shuffled for the low styles, so cell N there does not show sprite N. Cell 1 shows sprite 2, cell 3 shows sprite 7, and so on. Regenerating those and overwriting kRO's files would put the wrong art in them.

There is no reason to: kRO already ships correct thumbnails for 1..23, and this release ships 24..45. Start at 46, where the numbering is straightforward. If you compare a generated 1 to 12 against kRO's and it looks wrong, that is this, not a fault in your set.

Measured on 2026-08-14 by matching each kRO thumbnail to the sprite it was cut from. Male: 1→2, 2→1, 3→7, 4→5, 5→4, 6→3, 7→6, then 8 up are the same number. Female: 1→2, 2→4, 3→7, 4→1, 6→3, 7→6, 8→12, 9→10, 10→9, 12→8, then 13 up are the same number.

Note: Check yourself against art that exists. Run sprites 13..23 through the generator and compare with the thumbnails kRO ships for those numbers. They will not be byte identical, since kRO's were drawn and these are photographed, but each should clearly be the same hairstyle. If they are not, your frame number is wrong and the rest of the set will be too.

6 Raise the limits again

Three separate numbers decide what a player can reach. They all have to clear your highest style.

LimitWhereCeiling
Styles offered in creationWARP, Increase char create Hair limits128
Highest style the client will loadWARP, Allow 65k Hair Styles65535
max_hair_styleconf/import/battle_conf.txtn/a
Note: There are floors too. Allow 65k Hair Styles will not take a number below 43, the size of the client's hair name table. Increase char create Hair limits (Reforged) cancels at 23 or less, because the stock grid already offers 23 and there would be nothing to page.
Trap: New files alone change nothing. The page count and the draw limit are written into the exe when you patch. Dropping in new sprites and thumbnails does not add a page by itself. Re-run WARP with the higher number whenever you extend the set.
Note: 128 is a hard ceiling in creation. The limit is written into the client's own draw comparison, which tests the style index against a sign-extended byte, so 127 is the largest value that fits and 128 styles is the most the picker can offer. The patch refuses anything higher rather than wrapping negative and blanking the whole grid. @hstyle and item scripts still reach further.

The way the picker pages

The page size is fixed at 23 and your limit rarely divides by it, so decide your number here rather than after you have cut the art.

Warning: A style with no thumbnail draws as an empty cell.

The picker draws from the bitmaps, not from the sprites. A hairstyle whose sprite is present but whose img_hairstyle<NN>.bmp is missing still holds its cell and still selects: the cell just draws blank. It is not an error and nothing in the log mentions it, so a player cannot tell it from a dead cell.

kRO ships sprites and palettes for styles 1 to 45 but picker thumbnails for 1 to 23 only, which is why 24 to 45 need the thumbnail pack even though their art is already in the GRF. Check every style you add has both.

The grid is 24 buttons, four columns by six rows. The first 23 are hairstyles and the 24th is the page button, so each page holds 23. That cell draws img_hairstyle99.bmp and img_hairstyle_girl99.bmp if you supply them, which is where the > arrow goes. This release does not ship them and they are not in the thumbnail pack, so by default the cell is empty: it still pages, it just gives the player nothing to aim at. Make the pair yourself at the same 36 × 37, 24-bit, magenta FF00FF format as any other thumbnail, or leave them out and accept an empty pager cell. Above 98 styles the arrow is dropped, because the pager needs an index the draw limit will not touch. The style under a cell is page × 23 + cell, counting the first page as zero.

PageStyles
11 - 23
224 - 46
347 - 69
470 - 92
593 - 115
6116 - 128
Note: Three things that follow from that. The pager only goes forward and wraps back to page 1; there is no back button. Filenames follow the style number, never the page. And unless your limit divides exactly by 23, the last page ends with spare cells that have no style behind them, which are inert.

Troubleshooting

Symptom
Cause
Fix
Nothing changed at all
The folder names are in the wrong codepage, so the client is reading data.grf instead.
See the trap in Path B, step 4.
Cell 24 does nothing
Increase char create Hair limits is not applied, or its style count is still 23.
Apply it with New Char Limits 45 (step 2) and patch again.
Page 2 cells are blank
No thumbnail for those numbers, or the filename is not zero-padded to two digits.
Copy in the thumbnail pack (step 1), or zero-pad the name: img_hairstyle07.bmp.
Cells blank past a certain number, but they still select and the hair loads
The draw limit. Increase char create Hair limits is set lower than that style, so the picker refuses to draw the cell while the click still works.
Raise it and re-patch.
A cell on the last page pops “file not found” and the head vanishes
A spare cell past your limit. Pages are always 23 wide.
This release already seeds spare cells blank and drops the click, so re-patch with the current WARP 07-16. If you are pinned to an older build, set your creation limit to a multiple of 23 so the last page has no spare cells.
Thumbnail shows, character is bald
The .spr/.act pair is missing or misnamed. The picker and the worn sprite are different files.
Add the male and female .spr and .act at the paths in step 4.
Bald only after choosing a high number
Allow 65k Hair Styles is not applied, so the loader never learned to build the filename from the number. The picker was patched, the loader was not.
Apply it with the same limit as the creation patch (step 2) and patch again.
The client crashes on hairstyle 43
Allow 65k Hair Styles from before the Part 2 update read one entry past the end of the client's 43-entry hair table.
Update WARP0716 and patch again from the clean exe. The current patch also asks for your highest style (step 2).
Wrong hair, not the one in the thumbnail
Allow 65k Hair Styles is applied but its limit is below that style, so the loader clamped it to style 1.
Raise it to your highest style and re-patch.
Right in creation, wrong in game
max_hair_style is below that number, so the server clamped it.
Raise it in conf/import/battle_conf.txt (step 3).
Hair is the wrong colour or invisible
No palette for that style and colour. Palettes are per style and per colour.
Supply the missing .pal.
“Cannot find File: ...pal”, then the client shuts down
That style has no palette for the colour that was clicked. The client dereferences the failed palette anyway and access-violates.
Supply the missing .pal, and tick Hair colour guard, and extra hair colours so any gap you miss is ignored rather than fatal.
Generated thumbnails have a face on them
Either Hair only is unticked, which is a choice, or the tile is marked no palettes, meaning there were no .pal files for that style so hair could not be told from skin.
Drop the palettes in with the sprites.

Checklist

Check off items as you complete them. Progress is saved in your browser.

Before you ship

0 / 8
  • Thumbnails in place for every style you offer, zero-padded, male and female
  • img_hairstyle99.bmp and img_hairstyle_girl99.bmp if you want an arrow on the pager cell rather than an empty one
  • Male and female .spr and .act for anything past 45
  • Palettes for every style and every colour you offer, with none missing, because an unguarded gap crashes the client
  • Both limit patches applied to the exe players actually run, plus Hair colour guard, and extra hair colours if you want the crash netted
  • The two limits set to your highest style, and equal to each other
  • max_hair_style raised on the server
  • One character created from the last page, logged in, hair matches the thumbnail