# Characters (/ink/character)





Before to read this section, it is recommended to read <DynamicLink href="/start/character#initialize">how to create and use characters in Pixi’VN</DynamicLink>.

Use [#use]

Associate a character with a dialogue [#associate-a-character-with-a-dialogue]

You can associate a character with a dialogue in &#x2A;**ink***. To do this, you need to use the following syntax:

```ink title="ink"
{character_id}: {text}
```

* `character_id`: is the character `id` defined in **JavaScript/TypeScript**.
* `:`: is the separator between the character and the text.
* `text`: is the dialogue text.

<CodeBlockTabs defaultValue="ink/start.ink">
  <CodeBlockTabsList>
    <CodeBlockTabsTrigger value="ink/start.ink">
      ink/start.ink
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="values/characters.ts">
      values/characters.ts
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="main.ts">
      main.ts
    </CodeBlockTabsTrigger>
  </CodeBlockTabsList>

  <CodeBlockTab value="ink/start.ink">
    ```ink
    === start ===
    mc: Hello, I'm Liam.
    -> DONE
    ```
  </CodeBlockTab>

  <CodeBlockTab value="values/characters.ts">
    ```ts
    import { CharacterBaseModel, RegisteredCharacters } from "@drincs/pixi-vn";

    export const mc = new CharacterBaseModel("mc", {
        name: "Liam",
    });

    RegisteredCharacters.add(mc);
    ```
  </CodeBlockTab>

  <CodeBlockTab value="main.ts">
    ```ts
    import "./values/characters";

    // ...
    ```
  </CodeBlockTab>
</CodeBlockTabs>

<CharacterDialogueExample />

Use character name in dialogues text [#use-character-name-in-dialogues-text]

You can use the character name in dialogues. To do this, you need to use the following syntax:

`[` + `character_id` + `]`

* `[` and `]`: are the delimiters to identify the character.
* `character_id`: is the character `id` defined in **JavaScript/TypeScript**.

<CodeBlockTabs defaultValue="ink/start.ink">
  <CodeBlockTabsList>
    <CodeBlockTabsTrigger value="ink/start.ink">
      ink/start.ink
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="values/characters.ts">
      values/characters.ts
    </CodeBlockTabsTrigger>
  </CodeBlockTabsList>

  <CodeBlockTab value="ink/start.ink">
    ```ink
    === start ===
    Hello, [mc].
    -> DONE
    ```
  </CodeBlockTab>

  <CodeBlockTab value="values/characters.ts">
    ```ts
    import { CharacterBaseModel, RegisteredCharacters } from "@drincs/pixi-vn";

    export const mc = new CharacterBaseModel("mc", {
        name: "Liam",
    });

    RegisteredCharacters.add(mc);
    ```
  </CodeBlockTab>
</CodeBlockTabs>

<CharacterDialogueTextExample />

To do this, you'll first need to implement the functionality to replace the id with the character's name. To do this, you can use one of the following methods:

<Callout title="Templates" type="info">
  In all templates, this implementation is already included.
</Callout>

<Accordions>
  <Accordion title="i18next_implementation" id="i18next-implementation">
    If you are using [i18next](https://www.i18next.com/) for translation, you can use the following method:

    <CodeBlockTabs defaultValue="utils/ink-utility.ts">
      <CodeBlockTabsList>
        <CodeBlockTabsTrigger value="utils/ink-utility.ts">
          utils/ink-utility.ts
        </CodeBlockTabsTrigger>

        <CodeBlockTabsTrigger value="i18n.ts">
          i18n.ts
        </CodeBlockTabsTrigger>
      </CodeBlockTabsList>

      <CodeBlockTab value="utils/ink-utility.ts">
        ```ts
        import { onReplaceTextBeforeTranslation } from "@drincs/pixi-vn-ink";

        export function initializeInk() {
            onReplaceTextBeforeTranslation((key) => { // [!code focus]
                return `{{${key}}}`; // [!code focus]
            }); // [!code focus]
        }
        ```
      </CodeBlockTab>

      <CodeBlockTab value="i18n.ts">
        ```ts
        import { RegisteredCharacters } from "@drincs/pixi-vn";
        import i18n from "i18next";
        import Backend from "i18next-chained-backend";
        import { initReactI18next } from "react-i18next";

        export const useI18n = () => {
            if (!i18n.isInitialized) {
                i18n.use(Backend)
                    .use(initReactI18next)
                    .init({
                        debug: false,
                        fallbackLng: "en",
                        lng: "en",
                        interpolation: {
                            escapeValue: false,
                        },
                        load: "currentOnly",
                        missingInterpolationHandler(_text, value, _options) { // [!code focus]
                            let key = value[1]; // [!code focus]
                            let character = RegisteredCharacters.get(key); // [!code focus]
                            if (character) { // [!code focus]
                                return character.name; // [!code focus]
                            } // [!code focus]
                            return `[${key}]`; // [!code focus]
                        }, // [!code focus]
                    });
            }
        };
        ```
      </CodeBlockTab>
    </CodeBlockTabs>
  </Accordion>

  <Accordion title="replacement_implementation" id="replacement-implementation">
    To use the character name in dialogues, you can take advantage of the <DynamicLink href="/ink/replacement">possibility of replacing portions of text</DynamicLink>. For example, you can use the following method:

    ```ts title="utils/ink-utility.ts"
    import { RegisteredCharacters } from "@drincs/pixi-vn";
    import { onReplaceTextAfterTranslation } from "@drincs/pixi-vn-ink";

    export function initializeInk() {
        onReplaceTextAfterTranslation((key) => { // [!code focus]
            let character = RegisteredCharacters.get(key); // [!code focus]
            if (character) { // [!code focus]
                return character.name; // [!code focus]
            } // [!code focus]

            // if return undefined, the system will not replace the character id // [!code focus]
            return undefined; // [!code focus]
        }); // [!code focus]
    }
    ```
  </Accordion>
</Accordions>

Edit [#edit]

You can edit a character's information in &#x2A;**ink***, for example, you can change the character's name. To do this, you need to use the following syntax:

```ink title="ink"
# rename {character_id} {new_name}
```

* `#`: is the hashtag symbol to identify a hashtag command.
* `rename`: is the command to rename a character.
* `character_id`: is the character `id` defined in **JavaScript/TypeScript**.
* `new_name`: is the new name for the character.

<CodeBlockTabs defaultValue="ink/start.ink">
  <CodeBlockTabsList>
    <CodeBlockTabsTrigger value="ink/start.ink">
      ink/start.ink
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="values/characters.ts">
      values/characters.ts
    </CodeBlockTabsTrigger>
  </CodeBlockTabsList>

  <CodeBlockTab value="ink/start.ink">
    ```ink
    === start ===
    mc: Hello, I'm [mc].
    # request input string
    mc: My name is:
    # rename mc {_input_value_}
    mc: My name is [mc]
    -> DONE
    ```
  </CodeBlockTab>

  <CodeBlockTab value="values/characters.ts">
    ```ts
    import { CharacterBaseModel, RegisteredCharacters } from "@drincs/pixi-vn";

    export const mc = new CharacterBaseModel("mc", {
        name: "Liam",
    });

    RegisteredCharacters.add(mc);
    ```
  </CodeBlockTab>
</CodeBlockTabs>

<CharacterEditExample />

To do this, you'll first need to implement the functionality to rename the character.  To do this, you can use one of the following methods:

<Callout title="Templates" type="info">
  In all templates, this implementation is already included.
</Callout>

<Accordions>
  <Accordion title="custom_hashtag_script_implementation" id="custom-hashtag-script-implementation">
    Using the possibility of <DynamicLink href="/ink/hashtag">customizing hashtag commands</DynamicLink>. For example, you can use the following method:

    ```ts title="utils/ink-utility.ts"
    import { RegisteredCharacters } from "@drincs/pixi-vn";
    import { HashtagCommands } from "@drincs/pixi-vn-ink";

    export function initializeInk() {
        HashtagCommands.add((script, props, convertListStringToObj) => { // [!code focus]
            if (script[0] === "rename" && script.length === 3) { // [!code focus]
                let character = RegisteredCharacters.get(script[1]); // [!code focus]
                if (character) { // [!code focus]
                    character.name = script[2]; // [!code focus]
                } // [!code focus]
                return true; // [!code focus]
            } // [!code focus]
            return false; // [!code focus]
        }); // [!code focus]
    }
    ```
  </Accordion>
</Accordions>

Character emotions [#character-emotions]

You can use the <DynamicLink href="/start/character#character-emotions">character emotions</DynamicLink&#x3E; in &#x2A;**ink***. To do this you just need to use a special ID composed of:

`character_id` + `@` + `emotion`

* `character_id`: is the character `id` defined in **JavaScript/TypeScript**.
* `@`: is the separator between the character and the emotion.
* `emotion`: is the emotion defined in **JavaScript/TypeScript**.

For example:

```ink title="ink"
{character_id}@{emotion}: {text}
```

<CodeBlockTabs defaultValue="ink/start.ink">
  <CodeBlockTabsList>
    <CodeBlockTabsTrigger value="ink/start.ink">
      ink/start.ink
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="values/characters.ts">
      values/characters.ts
    </CodeBlockTabsTrigger>
  </CodeBlockTabsList>

  <CodeBlockTab value="ink/start.ink">
    ```ink
    === start ===
    mc@happy: Hi, I'm Liam. I'm very happy today.
    -> DONE
    ```
  </CodeBlockTab>

  <CodeBlockTab value="values/characters.ts">
    ```ts
    import { CharacterBaseModel, RegisteredCharacters } from "@drincs/pixi-vn";

    export const mc = new CharacterBaseModel("mc", {
      name: "Liam",
    });

    export const mcHappy = new CharacterBaseModel(
      { id: "mc", emotion: "happy" },
      {
        name: "Liam happy",
      }
    );

    RegisteredCharacters.add([mc, mcHappy]);
    ```
  </CodeBlockTab>
</CodeBlockTabs>

<CharacterEmotionsExample />
