> For the complete documentation index, see [llms.txt](https://docs.ragnasync.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ragnasync.com/features/character-head-builder.md).

# Character Heads

Upload custom hair and hat sprites for your server's character renderer

## Overview

The Character Head Builder allows server administrators to upload their custom Ragnarok GRF files for character head rendering in Discord embeds. This includes hairstyles, headgear/accessories, and palettes.

***

## Required Preparation

Before uploading, you must create a GRF file containing your custom sprites using GRF Editor or similar tools.

**Download GRF Tools:** <https://irowiki.org/wiki/Tools>

Your GRF should contain only the custom sprites and configurations you want to use—you don't need to include the entire client.

***

## GRF Structure Requirements

Your GRF should contain files organized like this:

| Content Type  | GRF Path                                              |
| ------------- | ----------------------------------------------------- |
| Hair Sprites  | `data/sprite/ÀÎ°£Á·/¸Ó¸®Åë/³²/*.spr` / `¿©/*.spr`     |
| Hat Sprites   | `data/sprite/¾Ç¼¼»ç¸®/³²/*.spr` / `¿©/*.spr`          |
| Hat Config    | `data/luafiles514/lua files/datainfo/accessoryid.lub` |
| Hat Names     | `data/luafiles514/lua files/datainfo/accname.lub`     |
| Hair Palettes | `data/palette/¸Ó¸®/*.pal`                             |

***

## Upload Process

1. Login to the dashboard at <https://ragnasync.com/login> using your `discord_server_guid` found in your `channels.conf` file

{% hint style="danger" %}
**Warning:** Never share your `discord_server_guid` with anyone. This is your secure private key for accessing the dashboard.
{% endhint %}

2. Navigate to **Builder > Char Heads**
3. Select or drag your GRF file onto the upload area (max 500MB)
4. The system automatically extracts and processes:
   * Sprite files (.spr/.act) for hair and accessories
   * Palette files (.pal) for color variations
   * Lua configuration files for hat ID mappings
5. Once uploaded, changes take effect immediately—no restart required

***

## Automatic Configuration

When you upload a GRF file, the system automatically:

1. Parses `accessoryid.lub` to extract hat ID mappings
2. Parses `accname.lub` to extract sprite file names
3. Generates a hat library for rendering

No manual configuration is required.

***

## Lua Config Status

After uploading, the dashboard shows the status of your Lua config files:

| Status        | Meaning                                                                                                                                                                                            |
| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Generated** | We found `accessoryid.lub` and `accname.lub` in your GRF and built a hat lookup table. Custom hats render by their item ID.                                                                        |
| **(missing)** | Your GRF didn't contain those Lua files. Sprites and palettes still load, but hats can only render if their item IDs happen to match the **default** library — any custom hats won't render by ID. |

A common reason for "(missing)" is a sprite-only GRF — e.g. a hat update GRF built by extracting just `data/sprite/...` paths. To fix, rebuild the GRF to also include:

* `data/luafiles514/lua files/datainfo/accessoryid.lub` (or `.lua`)
* `data/luafiles514/lua files/datainfo/accname.lub` (or `.lua`)

The older `data/lua files/datainfo/...` paths are also accepted.

***

## Character Head Rendering

Character heads are rendered at **40x40 pixels** and display:

* Hair style and color
* Head top accessory
* Head mid accessory
* Head bottom accessory
* GM indicator (yellow background + label) for group\_id > 5

***

## Preview

***

## Fallback Behavior

If no custom GRF is uploaded, the system uses a default sprite set with standard Ragnarok appearances. These default sprites may not match your server's custom hairstyles or headgear — to get accurate character representations, upload your server's GRF file.

{% hint style="info" %}
Without a custom GRF, character images will appear as generic Ragnarok characters that don't reflect your server's actual sprites.
{% endhint %}

### Per-slot fallback for unknown hat IDs

If a character has a `head_top`, `head_mid`, or `head_bottom` ID that isn't in your uploaded hat library (or in the default library when no GRF is uploaded), only that slot is randomized — the rest of the character renders from their real stored appearance. You'll see the correct hair, hair color, and any hat IDs the library *does* know about, with the unknown slot replaced by a random hat each render.

This usually means an item ID was assigned in-game that your GRF's `accessoryid.lub` / `accname.lub` doesn't cover. Re-uploading a GRF that includes those Lua files for the missing IDs will resolve it.

***

## Message Avatars

Not all Discord messages use character head avatars. The avatar shown depends on the message type:

| Message Type                           | Avatar                                          |
| -------------------------------------- | ----------------------------------------------- |
| Player chat messages                   | Character head (rendered from GRF data)         |
| NPC messages                           | Your server logo (set on the dashboard)         |
| System messages (drops, refines, etc.) | Your server logo, unless the route sets its own |

If you notice your server logo appears on some messages but not others, this is expected — player chat messages show the speaking character's head instead.

System messages are the exception you control: each **message route** picks its own avatar, so a monster kill or drop can show the monster's sprite instead of your logo. See [Message Routing](/ragnascript/message-routing.md#avatar-options).

***

## Discord Avatar Caching

Character heads are used as webhook avatars for in-game chat messages on Discord. Be aware that Discord caches avatar images aggressively:

* Avatar images are cached by Discord's CDN for extended periods
* After uploading new sprites, previously sent messages will retain their old avatars
* Only new messages will display the updated character heads
* Discord may take some time to refresh cached avatars even for new messages

There is no way to force Discord to clear its avatar cache for existing messages.

***

## Troubleshooting

| Issue                   | Solution                                                                                                                                                       |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Upload fails            | Ensure file is a valid .grf format and under 500MB                                                                                                             |
| Hats not showing        | Check Lua Config status on the dashboard. If it says "(missing)", your GRF needs `accessoryid.lub` and `accname.lub` in `data/luafiles514/lua files/datainfo/` |
| Wrong accessories       | Check that sprite names in accname.lub match actual file names                                                                                                 |
| Preview not updating    | Clear browser cache or wait a moment for processing                                                                                                            |
| Old avatars on messages | Discord caches avatars—only new messages will show updated sprites                                                                                             |
