Making a simple moving NPC

Here you will find the tools to get you started. If you are new, inexperienced or just unfamiliar with what we do, this is the place to try your hand at creating content.
Post Reply
User avatar
Posts: 239
Joined: 14 Nov 2016, 23:20
Location: Brazil

Making a simple moving NPC

Post by jesusalva » 22 Feb 2020, 17:20

Reference Book: Simple Moving NPCs
This is a reference tutorial. It could be rewritten to something easier to read/understand and added to wiki later by volunteers. :D

So you found out place XXX-X is too boring, and could use people moving around?

It's time for Moving NPCS!
Client Data
1. For moving NPCs, we need NPCs to inheir player structure. So open npcs.xml

Here's an example of a move-able NPC:

Code: Select all

    <npc id="463">
        <!-- Yannika, Hinnaks sandwich-making wife. -->
        <menu name="Talk" command="talk 'NAME'"/>
What you need is:
  • The NPC ID. It must be over 400 and unique. Usually, just pick the next free ID available, skipping those with ID >800 which are reserved.
  • The comment. People reading source code must know what the NPC is about.
  • In this order: A body and a hair (optional) for the NPC. The bodies are under races/ folder, and the hairstyles under hairstyles.
  • Hair color. In the example above, they'll be Fire Red. You can find the hair colors on itemcolors.xml - be mindful between "hair" and "hairS"! You can see which one to use on the begin of items.xml
Once those are done, you'll declare the equipment sprites in the order they should be rendered.

Their syntax is:

Code: Select all

<sprite> PATH/TO/SPRITE|#DYE-COLOR </sprite>
Do not attempt to dye items which do not accept dyes.

Once finished, add the menu option of talking, save, and finish!

Protip: You'll make that a Merge Request against clientdata repository. Please refrain from sending us the whole XML file if possible.
Server Data
1. We need to declare a NPC constant for the new NPC ID you've just added.
In db/constants.conf, declare the new NPC constant:

Code: Select all

    NPC_AWESOMENPC:            463
Where 463 is the new NPC ID you've created on client data.
Rename NPC_AWESOMENPC to something at least a bit descriptive. (eg. NPC_MOUBOO or NPC_VALIA).

2. Create the NPC file.
It'll mimic this structure:

Code: Select all

// Evol Scripts
// Author:
//    <your name here>
// Description:
//    <what your NPC does>

XXX-X,x,y,0	script	Awesome NPC Name	NPC_AWESOMENPC,{



    initpath "move", 54, 43,
             "dir", DOWN, 0,
             "wait", 27, 0,
             "move", 43, 43,
             "dir", UP, 0,
             "wait", 27, 0,
             "move", 48, 45,
             "dir", DOWN, 0,
             "wait", 20, 0;

    .sex = G_OTHER;
    .distance = 5;
  • XXX-X, X, Y - are the map coordinates. That reads as: map XXX-X.tmx (x,y)
  • The "0" after coordinates is the direction its facing. "0" is south (the default)
  • It's called Awesome NPC Name. Keep it under 23 chars. If you have multiple NPCs with same name, you can put a # at the end, followed by an identifier. eg. Student#1. NPC names must be unique and are case-sensitive!
This NPC only says "hello" to player, which is what hello(); function does. Every second, it'll execute a function called domovestep(); (which is the movement logic).

Inside the OnInit block is where the magic happens.
The initpath function
This function is built like this:
keyword, arg1, arg2,

Now let's analyse the code:

Code: Select all

    initpath "move", 54, 43,
             "dir", DOWN, 0,
             "wait", 27, 0,
             "move", 43, 43,
             "dir", UP, 0,
             "wait", 20, 0;
Right at the begin, it'll move to (54, 43).
These coordinates must be nearby, as NPCs are not capable of crossing huge distances in one go.

Once it finishes, it'll change its direction to be facing DOWN.
Direction only takes one argument, so we add a 0 to keep the structure.

After that, it'll wait 27 seconds before moving again.
Again, wait only takes one argument, so we add a 0 to keep the structure.

After this, it'll move to (43, 43). Once finished it'll change its direction to be facing UP (with an extra 0 to keep structure). Then it'll wait a bit, 20 seconds.

Once it finishes, it mets a ; (semicolon). initpath is a command/function/keyword, and those only end when you give it a semicolon.

It'll go back to start when it finishes, so the first movement usually points to wherever the NPC default position is.

Code: Select all

will put this to work. You're finished.

If you're testing locally, run make maps so your localhost learns about this new NPC. There's no need to run that for the merge request.

And now you have a moving NPC!
Keywords for initpath
Initpath accepts a few params besides move and dir.
Keep in mind "no arguments" means "put a 0, 0, at the end", for example.
The most common are:
  • dir - Direction (UP/DOWN/LEFT/RIGHT). One argument.
  • sit - Makes NPC to sit. No arguments.
  • stand - Makes NPC stand. No arguments.
  • wait - Makes NPC to wait X seconds. One argument.
  • emote - Makes NPC shows an emote. One argument. eg. E_JOY
  • warp - Makes NPC to warp. Unlike move, it will not have any animation.
  • speed - Allows NPC to run or walk slower. One argument.
  • say - Makes NPC say something to everyone see.
  • call - Calls a custom function to do whatever. Accepts up to two arguments, as usual.
  • move - Makes NPC walk somewhere.
The function is authored by 4144. Other keywords are available (eg. class, flags, etc.) but are less used.
Jesusalva (aka. Jesusaves)
Post Reply