Getting Started

This page contains a top-down write-up of Echo:NPCs features. Newcomers are encouraged to start here, and read through this page in its entirety before jumping into the Manual.

Understanding Echo:NPC

Echo:NPC contains three main concepts:

  • States
  • State Transitions
  • Transition Effects

State refers to the current state of an entity. That is, the components that describe the entities behavior, such as scale, movement-speed, and variant.

State Transitions are ways of moving from one state to the next. Echo:NPC provides a feature-complete set of Transition Types including: Timers, Clicking, Proximity to Player and Reverse Proximity to Player. Users can also create their own transitions using the templating system.

Transition Effects are the actions that are run during state changes. These can be any command, including /say and /playsound, as well as entity events and Molang.

The format

The general format for an Echo:NPC template is this:

{
    "header": {
        > Entity-specific settings/configs are written here
    },
    "states": [
        {
            > The first state
        },
        {
            > The second state
        }
        > Add more states here
    ],
    "entity": {} < Entity definition, either fully defined, or taken from the entity templates.
}

In short, Echo:NPC should be thought of as a “decorator” syntax around a normal Bedrock entity. We add state definitions in states, and the header contains the config values.

The Echo Workflow

Echo creates two files:

  • The BP Entity file
  • The BP Animation Controller file

Echo does this by compiling the template, and exporting the created files (directly into your behavior pack, if you have things setup correctly!). This means when you are working with Echo, you generally should not edit the resulting Entity/AC files. Rather, change the template, and re-compile!

Simple States

Each individual state is listed under "states": [], and represents its own object {}. The data that gets placed in the states determines how the entity will act. Usually, entities will contain 1-5 states.

Lets take a look at a simple state:

{
    "name": "greetings",
    "text": [
        "Hey there feller!",
        "How are you doing today?",
        "Are you enjoying Echo:NPC?"
    ]
}

This simple NPC can be clicked three times. The first time he will say Hey there feller!. The second time, he will say How are you doing today?. The third time he will say Are you enjoying Echo:NPC?.

Its that easy to get your NPCs talking!

The reason this template can be so short is because of the settings. Things like default transitions are set into config files, meaning you don’t need to write things again and again!

Settings

Echo:NPC is designed for quick, powerful coding. For this reason, it comes packaged with a three-tiered settings structure, which allows users to quickly override default values, and reuse code-blocks. Settings are discussed in more detail on the settings page.

Sub states:

Each state can contain multiple sub-states. Sub-states are created implicitly. In the example above, three sub-states are created: One for each dialogue option. We can decorate these sub-states with commands, components, events, and other custom-content.

"text": [
    "Hey there feller!",         //first sub-state
    "How are you doing today?",  //second sub-state
    "Are you enjoying Echo:NPC?" //third sub-state
]

Complicated States

Echo:NPC works by taking these sub-states, and “decorating them” with content. For starters, we can use the transitions key to set HOW each sub-state is triggered:

note: The default transitions is interact (clicking), which we are overriding in this example.

{
    "name": "greetings",
    "transitions": {
        "1": "proximity 15",     //The first state will trigger when the player is within 15 blocks
        "2": "interact",         //The second state will trigger when the player clicks on the entity
        "2-end": "timer 3"       //Tge remaining states will each player after a 3 second delay
    },
    "text": [
        "Hey you! You there. Come over here!",
        "Thanks for joining me! [Click to interact]",
        "I hope you are enjoying Echo:NPC!",
        "It really is a pleasant day!",
        "Well, thats all I have for you. Bye-bye!"
    ]
}

The strange "1" and "2" format underneath transitions is called set-lang, and is described in more detail in the Set-lang documentation. In short, it allows users to specify which sub-states take on custom content.

Here is another example, showing the use of components and commands to make our entity interactive:

{
    "name": "greetings",

    //Set a unique scale for each of the first three sub-states
    "components": {
        "1": { 
            "minecraft:scale": { 
                "value": 0.5
            }
        },
        "2": { 
            "minecraft:scale": { 
                "value": 1
            }
        },
        "3": { 
            "minecraft:scale": { 
                "value": 2
            }
        }
    },
    "commands": {
        "4": "/give @p iron_sword" //Give the player a sword on the fourth sub-state
    },
    "text": [
        "I am very small!",
        "Now I am normal size!"
        "Now I am big!",
        "Here, take this sword, it was my fathers!"
    ]
}

What else can Echo:NPC do?

Using a consistent format, Echo:NPC can handle the following:

  • Text
  • Sounds
  • Commands
  • Components
  • Transitions
  • Component Groups

This content is considered “natively supported” by Echo:NPC.

Templates

As discussed above, Echo:NPC fundamentally works by patching pieces of json-code together. These json chunks, referred to as snippets or templates are primarily contained within settings.json. Users can use these snippets in their own template files to quickly create powerful entities.

Additionally, users can create their own templates by defining them in custom_settings.json. In this way, users can create themselves a powerful library of custom functionality.

Lets bring back a simple entity, containing no templating:

{
    //Settings information can be moved into the settings files
    "header": {
        "default_state": "main",
        "output_type": "world",
        "default_transition_types": ["interact"],
        "manifest_id": "190bdd50-7266-4991-849a-88df60b8f567"
    },
    "states": [
        {
            "name": "main",
            "components": { //Repeating components can be turned into templates
                "1": {
                    "minecraft:scale":{
                        "value": 2
                    }
                },
                "2": {
                    "minecraft:scale":{
                        "value": 0.5
                    }
                },
                "3": {
                    "minecraft:scale":{
                        "value": 1
                    }
                }
            },
            "text": [
                "Look! I'm big",
                "Look! I'm small",
                "Just right!"
            ]
        }
    ],
    //Entity definitions can be moved into the template files
    "entity": {
        "format_version": "1.13.0",
        "minecraft:entity": {
            "description": {
                "identifier": "sirlich:npc",
                "is_spawnable": true,
                "is_summonable": true,
                "is_experimental": false
            },
            "components": {
                "minecraft:push_through": {
                    "value": 1
                },
                "minecraft:health": {
                    "value": 5,
                    "max": 5
                },
                "minecraft:physics": {},
                "minecraft:nameable": {}
            },
            "component_groups": {},
            "events": {}
        }
    }
}

Lets look at it again, with improvements:

{
    //Simplify header by moving defaults into custom_settings.json
    "header": {
        "output_type": "world",
        "manifest_id": "190bdd50-7266-4991-849a-88df60b8f567"
    },
    "states": [
        {
            "name": "main",
            //Repeating components can be stored as templates.
            "custom_components": {
                "1": ["scale 2"],
                "2": ["scale 0.5"],
                "3": ["scale 1"]
            },
            "text": [
                "Look! I'm big",
                "Look! I'm small",
                "Just right!"
            ]
        }
    ],
    //Entity definitions can be stored as templates.
    "entity": "default sirlich:npc"
}

Multiple States

Often, we want to create entities with multiple states. While it is technically possible to put everything into a single state, this quickly becomes unwieldy, since the sub-state indexes become very long. By creating entities with multiple states, we can split up the logic into nicely named chunks.

For example:

"states": [
    {
        "name": "introduction",
        "text": [
            "Hi!",
            "Welcome to the Planet X Theme Park!",
            "Here we have many fun things to do!"
        ],
        "next": "bye" //When we run out of dialogue in this state, where should we go?
    },
    {
        "name": "bye",
        "text": [
            "Bye now!",
            "Enjoy the park!"
        ],
        "next": "bye" //When we reach the bottom of the 'bye' state, loop again to the top (endless loop)
    }
]

Randomization

Sometimes, we want to use randomization in our entities. For example, instead of ALWAYS going to a specific state, we want to randomly choose between multiple states. This can be done with randomizers. Here is an example:

Randomizers go at the top level of Echo (just like entity, states, etc)

"randomizers": {
    "random_bye": {
        "echo:bye": 5,
        "echo:bye_2": 1
    }
}

This randomizer will select between the bye state, and the bye_2 state. The number associated with each state is the weight (chance) that the state will be picked.

Confused by the weird echo: syntax? Read on till the end, or visit the dedicated randomizers document.

Simple States

Sometimes, we don’t need the power that Echo:NPC normally provides. When we don’t need sub-states or dialogue, we can use a special state type called single, which allows us to easily create simple functionality, without worrying about set-lang or text-lists.

You can read more about Single States in the Manual.

A full template example:

{
    "header": {

        //Set the manifest ID so Echo can export directly into your pack
        "manifest_id": "190bdd50-7266-4991-849a-88df60b8f567", 
        "output_type": "dev",

        //Echo needs to know what state to "start" your entity in.
        "default_state": "main"
    },
    "states": [
        {
            "name": "main",
            "text": [
                "Hey there!",
                "Welcome to Echo:NPC!",
                "I hope you are enjoying the tool."
            ]
        }
    ],

    //Create the entity based off of the 'default' template.
    "entity": "default sirlich:my_entity"
}

Confused about that last part? Echo provides a few templates you can use, when writing entities. If you don’t want to use these templates, you can simply replace the template-string, with your entity-definition:

"entity": {
    "format_version": "1.14.0",
    "minecraft:entity": {
        "description": {
            "identifier": "sirlich:example",
            ....
            etc

This allows you to add whatever default behavior you want. Echo will use this as a base when adding its own content.