Habbo: Avatar Rendering Basics
Tags: habbo, opensource, games, javascript
Published: 2020-09-18 22:49:42

Hey there!
In this article, I'm going to explain how you can render a pretty figure like this one:
![angry](https://dev-to-uploads.s3.amazonaws.com/i/yo6rt5at4hk6qea6ir7l.jpeg)

> The avatar images in this article were rendered using [Open Hotel Client](https://github.com/open-hotel/open-hotel-client/tree/structure-migration). If you like habbo or games development in general, please consider contributing to the project or joining the team. My e-mail is at the bottom of this article.

Oh right, and it can also walk, swim, lay and face 8 different positions! Sounds like a lot of work, and it's indeed something susceptible to a bunch of edge cases.

The goal here is to learn how [Habbo](https://habbo.com) handles their assets to build an avatar.
![std](https://dev-to-uploads.s3.amazonaws.com/i/a65bp39uo5lmusehs138.jpeg)
 
# Naming convention

An avatar figure is built using a combination of multiple body and clothing parts. You can use the [habbox standalone avatar imager](http://labs.habox.org/generator-avatar) to try some combinations and get a string that describes your character.
![habbox](https://dev-to-uploads.s3.amazonaws.com/i/ksfonmu38pgok4z1mxnl.png)

At Open Hotel, we provide the same options as the habbox standalone imager for the avatar rendering (which is also [the default habbo api pattern](https://www.habbo.com/habbo-imaging/avatarimage?figure=hd-180-1)). [Those](https://github.com/open-hotel/open-hotel-client/blob/structure-migration/src/ui/views/game-page.vue#L44) are:
```js
{
  look: 'hd-180-1.hr-110-61.ch-210-66.lg-280-110.sh-305-62',
  action: 'mv,respect',
  direction: 2,
  head_direction: 2,
}
```
 
### Figure parts

In this example, our encoded avatar figure is:
```
hd-195-1.hr-679-61.ha-1012-110.ch-804-1341.lg-275-110.sh-3089-110
```

Each figure part is separated by a `.`, and each one of these parts can be described as:
`figureType-imageID-colorID1-colorID2...-colorIDn`

### Actions

Actions change the way we build the avatar figure. Take by example the std, laugh and mv actions:
![actions](https://dev-to-uploads.s3.amazonaws.com/i/syjropnmt0xc6u0sxxh0.png)

Notice that multiple actions can occur at the same time, like sitting and waving. According to the action applied, some body parts might stay the same, while others are changed.

## Figure Parts Example

### Combining parts

Let's try to render them separately at Open Hotel and see what we get:

`hd-195-1`: Body + face with key `195` and color `1`
![hd](https://dev-to-uploads.s3.amazonaws.com/i/ukw3tcndyj6xq07w8wuz.png)
 

`hr-679-61`: Hair with key `1012` and color `61`
![hr](https://dev-to-uploads.s3.amazonaws.com/i/zopzfd5b61jb1v623vw4.png)
 

`ha-1012-110`: Hat with key `1012` and color `110`
![ha](https://dev-to-uploads.s3.amazonaws.com/i/a88wxv6krihz41ew1dvd.png)
 
`ch-804-1341`: Shirt with key `804` and color `1341`
![ch](https://dev-to-uploads.s3.amazonaws.com/i/7o0oi7ysigqazk6bgkav.png)

`lg-275-110`: Trousers with key `275` and color `110`
![lg](https://dev-to-uploads.s3.amazonaws.com/i/8yuajtah3sf9cqy6dw0l.png) 

`sh-3089-110`: Shoes with key `3089` and color `110`
![sh](https://dev-to-uploads.s3.amazonaws.com/i/w5ymuxr2jvbl0yb2pay0.png)
 
All figures combined:
![all](https://dev-to-uploads.s3.amazonaws.com/i/tqk87onq4qkizuyvoogz.png)

> Notice: the figure part `key` is different from the figure part `id`, as you can see in the `Figure Data` section of this article.

Take a look below at the hairs `hr-110-61`, `hr-677-61`, `hr-3048-61`, `hr-165-61`. All of them with color `61`:
![hairs](https://dev-to-uploads.s3.amazonaws.com/i/cny55x6lz7w0hhjczw9x.png) 

# Figure Data

Open Hotel provides a file called [figuredata.json](https://github.com/open-hotel/open-hotel-resources/blob/master/dist/figuredata.json). This file holds information we need to get the right image for each one of our figure parts.
It is based on habbo's `figuredata.xml`, but we converted it to json to make it easier to use.

By using it, we can selectively lazy-load the image files as we need, since it wouldn't be practical to load everything in memory at once.

It basically holds two first-level keys:

- `pallete` is a dictionary that maps a `palleteid` to a dictionary of colors.

- `settype` keeps track of the `palette`, the metadata (like gender) and the images we need to use for each figure part.

Let's try a step-by-step render for the `hr-679-61` figure (hair 679 with color 61). Since it's a hair, it's held under the [hh_human_hair](https://github.com/open-hotel/open-hotel-resources/tree/master/dist/hh_human_hair) `lib`.


```js
// figuredata.json
{
  "palette": {
    // 3. get color "61" hex from palette "2"
    "2": {
      "32": { "color": "DFA66F" },
      "61": { "color": "2D2D2D" }
    },
  },
  "settype": {
    // 1. Access the figure type, which is "hr"
    "hr": {
      // 2. Access the palette with id 2
      "paletteid": "2",
      "set": {
        // 4. Get hair with key 679
        "679": {
          // Both genders accept this hair
          "gender": "U",
          "parts": [
            {
              // 5. Since type is hr, get this part 
              // id and move to figureMap.json
              "type": "hr",
              "id": 27,
              "colorable": 1,
              // for part sets with more than one
              // color, multiple color indexes can be used
              "colorindex": 1
            },
            {
              // hrb is used when the avatar is using a hat
              "type": "hrb",
              "id": 27,
              "colorable": 1,
              "colorindex": 1
            }
          ]
        },
      }
    }
  }
}
```

# Figure Map

The [figuremap.json](https://github.com/open-hotel/open-hotel-resources/blob/master/dist/figuremap.json) holds the libraries names mentioned at the `Naming Convention` section.

At figuremap.json, the first-level keys are:

- [libs](https://github.com/open-hotel/open-hotel-resources/blob/master/dist/figuremap.json#L2)
An array with all the libraries names.

- [parts](https://github.com/open-hotel/open-hotel-resources/blob/master/dist/figuremap.json#L1020)
A dictionary that maps a partset name and a part id to an index of the `libs` array.

To get the lib we need, let's follow the steps:
```js
// figuremap.json
{
  "libs": [
    // ...
    // 3. Get the lib id from the 1004th position of the array
    { "id": "hh_human_hair" },
  ],
  "parts": {
    "ha": {
      // ...
    },
    // 1. Access the "hr" partset
    "hr": {
      // 2. Access the part with id 27 and get its lib index
      "27": 1004,
    }
  }
}
```

Now we have all the information we need to get our hair image, we just need to [build](https://github.com/open-hotel/open-hotel-client/blob/structure-migration/src/game/imager/avatar/AvatarChunk.ts#L44) the image file name.

### Image files naming

The resultant file name should be:
`hh_human_hair_h_std_hr_4_2_0`, where each part of the file indicates:

- `hh_human_hair`: this file is a part of the human hair `lib`
- `h`: the image size (it could be `sh` if it were zoomed out). At Open Hotel we're not using `sh` images, since zoom is handled by [pixi-viewport](https://github.com/davidfig/pixi-viewport)

- `std`: the image's action. `std` is the standard, but it could be `wlk` for walking, or `sml` for smile.
> For some reason, the action `mv` matches the files with the `wlk` action name. This mapping happens at [animations.json](https://github.com/open-hotel/open-hotel-resources/blob/master/dist/HabboAvatarAnimations.json). I might cover animations in detail in a future article.

- `hr`: the figure part, which in the case is `hair`.

- `4`: the figure part id for this specific hair.

- `2`: the position, which can vary from 0 to 7 rotation clock-wise

![positionsN](https://dev-to-uploads.s3.amazonaws.com/i/miw4jgvu00urao29fadg.png)
 

- `0`: the animation frame. Actions like `std` only have one frame (frame 0), but for animations like walking (`mv`) and waving(`wave`), more frames are required.

## Conclusion

This tutorial might be confusing, but that's because a lot of mappings are required, and animating can get even more complicated.

The goal here is to provide a general idea of how the rendering process works at Habbo and also encourage people to contribute to [Open Hotel](https://github.com/open-hotel).

The current client active branch is [structure-migration](https://github.com/open-hotel/open-hotel-client/tree/structure-migration). If you run this branch, you should be able to look at the code that actually rendered the images present in this article.

If you're interested in contributing or have any questions, you can contact me at trickstival@gmail.com.

Thanks!!