Reference:Rio:Quick and dirty guide to NPCs in demo

Quick 'n Dirty guide to NPC's in the demo
Firstly, get the current PA-RPG demo up and running.

This document is going to look at building a character and putting him into the game, and by following this process we can start to see how Fife works 'under the hood' so to speak.

Start by running the demo (on linux, run run.py from the /fife/clients/parpg folder). Walk north and you should bump into this character:



If you right click, you'll get three options, 'Move here', 'Kick' and 'Inspect'. Selecting 'kick' gets you the response "Hey", and inspect gets "Engine told me that this instance has ID 6644 and object name chemist". He'll also occasionally spout some text, such as "Bring it on baby, I'm ready for action!"

So let's look at how this fellow is represented in game data. His graphic data can be found at /parpg/objects/agents/chemist. In here is the are a whole bunch of other folders (experiment/read/repair/stand/talk/walk) which hold all the animation frames, and an object.xml file which holds some more info. Most importantly, it holds the name for the object: the second line says object id="chemist".

Casually looking around you'll see that there aren't any data files for the chemist himself (his position, for example, must be somewhere....), so I did a quick grep -R "chemist" * and found that the interesting file we need to look at is /maps/shrine.xml. Here on line 56 we have



So this is where the engine gets the graphic imformation from... And a bit further down we see



There is nothing more special for the chemist. If after all you start up the demo again if you click any object in the game you will get exactly the same options as you do for the chemist. So he's not even an NPC as such yet! Whereas the girl that follows you is at least a little more interesting - she has more options! So let's check her out by inspecting her: name NPC:girl,ID 6672 and object name girl.

Now without going into all the gory detail of how I found everything out, here is how you add an extra option for this NPC. Firstly, in gui/instancemenu.xml, add a line:



under the kissButton. In scripts/agents/girl.py, at the end of the file add the code handle for this:

def HelloButtonHandler(self, myself, speaker): # 5000 is time in milliseconds to show text myself.say('Hello, World!',5000)

In scripts/world.py add another handler routine (mmm, thats right, we get to add 2 functions with the same name):

def HelloButtonHandler(self): self.hide_instancemenu self.instance_to_agent[self.instancemenu.instance.getFifeId].HelloButtonHandler(self.instancemenu.instance,self.hero)

Now run the demo again and right click the girl to get the Hello option, and to check it works. Finally, let's add the chemist as an NPC and give him some other options. Firstly we adjust his entry in shrine.xml - change line 6081 to:



This will also move him much closer to us. Next we need to add a chemist script into /scripts/agents, so we'll take a copy of the girl script and modify it to this:

from agent import Agent import fife from settings import Setting

TDS = Setting

_STATE_NONE, _STATE_IDLE, _STATE_RUN, _STATE_FOLLOW = 0, 1, 2, 3

class Chemist(Agent): def __init__(self, model, agentName, layer, uniqInMap=True): super(Chemist, self).__init__(model, agentName, layer, uniqInMap) self.state = _STATE_NONE #self.waypoints = ((67, 80), (75, 44)) #self.waypoint_counter = 0 self.hero = self.layer.getInstance('PC')

def onInstanceActionFinished(self, instance, action): pass

def getNextWaypoint(self): return l

def start(self): pass

def idle(self): self.state = _STATE_IDLE self.agent.act('stand', self.agent.getFacingLocation, False)

def run(self, location): pass

def GiveOxygenButtonHandler(self, myself, speaker): myself.say('Thanks buddy!',2000)

Notice I've added a different handler right at the bottom - the 'GiveOxygen'. We need to add this to the /gui/instancemenu.xml file:



The last set of alterations have to made to the world.py file. Add another handler underneath HelloButtonHandler:

def GiveOxygenButtonHandler(self): self.hide_instancemenu''' self.instance_to_agent[self.instancemenu.instance.getFifeId].GiveOxygenButtonHandler(self.instancemenu.instance,self.hero)

After line 10, at the top, add:

from agents.chemist import Chemist

Change line 114 to reference the chemist:

self.hero, self.girl, self.chemist, self.clouds, self.beekeepers = None, None, None, [], []

At line 133 insert some new code to set him up:

self.chemist = Chemist(self.model, 'NPC:chemist', self.agentlayer) self.instance_to_agent[self.chemist.agent.getFifeId] = self.chemist self.chemist.start

Save all these files, exit and run the demo again. Walk up and right click, select 'Give Oxygen' and you should get:



Phew! Now you can play around with the chemist script and try to see what some of this does. Hope this is of some use to you!