Tribe Rework
Idea
Based on the UML above:
Step #1
On NPCClient's startup everything is loaded into the classes.
The Tribal Object receives all the information regarding the tribe. (Resources, NPCs, Memories, Knowledge, Needs, Traits)
The Recipe Manager receives all available recipes.
The Parser Class receives the correspondence between the steps done in the recipe's algorithm and the basic operations which are currently implemented. It also receives the correspondence between the tribal needs and the recipes required to accomplish those needs.
This Step is executed only once, on startup. No further interrogation on the database should be done.
Step #2
The Tribal Object sends the need list to the parser class and awaits for the computed NPCType and the targets on which to apply.
Step #3
The Parser Class reads the NeedList and chooses which recipe to apply. (in respect of the information in the database)
Step #4
The Recipe Manager returns the required recipe(s) to the Parser Class. If the Recipe's requirements are met, then it assemblies the NPCType for the tribe members and sends it to the Tribal Object. Otherwise, it updates the Tribe's NeedList with the missing dependency.
Step #5
The Parser Class sends the assembled NPCType to the Tribal Object.
The Recipe Manager keeps track of the recipe. It keeps information like the completion of the tasks or the status of the resources.
Step #6
The Tribal Object assigns the resulted NPCType to the targeted members.
Example:
On startup, the tribe has the initial need to expand. It sends the need to the parser class. The parser class asks for a recipe and gets 'Gather Food' which requires 3 tribe members. Based on the tribe stats it constructs a NPCType and sends it to the Tribal Object which assigns it to 3 gatherers/hunters. Once enough food is gathered, the Recipe Manager will announce the Tribal Object to free the 3 tribesmen from their duties, and set them idle so the next recipe call can use them.
Tribal Object
Much of the Tribe object needs re-done in order to apply this.
- The NeedList needs to be a set of persistent Recipes (recipes that never end). These reflect the tribe unique attributes and targets.
Note: It is different from the current concept of Needs. I consider the tribe needs should be uniquely assigned to Tribes only, not to individuals. Members should have no independent Needs, but instead be fully controlled by the Tribal Object by assigning different NPCTypes in respect of the tribe's targets.
- Methods to communicate with the Parser Class and the Recipe Manager need to be added.
- A method to load tribe initial needs.
- Tribe needs can be held like an array of ints (representing the IDs of the recipes)
Parser Class
Will act only as a translator from basic csStrings to NPCTypes based on rules written in the database.
Creating the NPCType
Currently, the NPCs behave based on NPCTypes declared in data/npcbehave.xml. ( [[1]] )
My idea was to dynamically generate these scripts (containing behaviors and reactions) on run-time, based on all information the parser class has on the tribe. (rules on generation can be added, deleted, altered at any-time without interfering with anything else but this class).
Recipe Manager
This class will hold links to all the tribes and recipes loaded in-game. Besides, it needs to keep track to all actions done by the tribe regarding the recipes.
More info will be added.
Database changes
The database needs to suffer some changes for this to work.
tribe_need table
It will contain only the initial recipes id and the tribe id they are assigned to.
Of course, on npcclient's shutdown... the current state can be written here.
Much like:
Counter | tribe_id | recipe_id |
---|---|---|
1 | 0 | 10 |
2 | 0 | 12 |
3 | 1 | 10 |
recipe table
It will contain all the recipes described by:
- ID
- Recipe Name
- Requirement Script
- Algorithm
ID | Name | Requirement | Algorithm |
---|---|---|---|
1 | "Mine Coal" | "tribesman(gatherer,1);item(pickaxe,1);" | "goToMemory(coal);equip(pickaxe);dig;goTo(home);alterResource(coal,1)" |
2 | "Build Well" | "tribesman(builder,3);item(shovel,3);" | "selectLocation(x,y,z);goTo(x,y,z);alterResource(food,-1);dig;alterResource(food,-2);addBuilding(well)" |
correspondence table
The correspondence table should contain the matches between the basic algorithm functions and the operations needed to be done.
The requirements will only check if certain npcs, items, recipes exist. They don't need a database.
Functions in the algorithm section will be described by a succession of operations from here.
id | function | operation |
---|---|---|
1 | equip | EquipOp |
2 | dig | DigOp |
3 | goTo | MoveTo |
Note: Special tribe operations like "selectLocation, selectMemory, alterResource" might be hardcoded.
Pros & Cons
Pros
- It won't use any other data sources besides the sql database
- Independent pieces can be altered without the need to change the whole system. Adding moods will only affect the Parser Class that will slightly change the behavior before assembling and sending to the Tribal Object.
- There's no need to change the code in order to add or change tribes.
- The parser class can assemble NPCTypes for regular non-tribe npcs too.
Cons
- It will put a higher load on the NPCClient. I'm not to good at predicting but... it shouldn't make it "a piece of 20tons rock" :).
- For the start... I might be needed to assembly the NPCType and send it as an xml IDocumentNode so I can use the already-made API there.
Notes
- It would be great if MathScript could be used for the tasks above. Please let me know if it's possible. I like to avoid reinventing the wheel.
- Awaiting the green light.