Tribe Rework: Difference between revisions
→Idea: improved and updated |
|||
Line 51: | Line 51: | ||
==Tribal Object== | ==Tribal Object== | ||
The tribal object will suffer some changes in order to support the above-mentioned capabilities: | |||
*a knowledge array of strings: it contains only the name of the knowledge received by the tribe from completing recipes. They act more as tokens to prove completion. They are needed because recipes may require knowledge. (E.g.: if we want our tribe to build axes for it's warriors, we need the ironworks knowledge) | |||
* | *an array of Recipe pointers which acts more as a priority queue for keeping recipes. Initially, only the tribal recipe will be there. After initialization, persistent recipes (which will never expire) will be pushed there and act as goals for the tribe. Based on the goals, normal recipes will be pushed there... and if requirements are not met... recipes to meet the requirements... and the list can go on forever. | ||
*some memory entries which act as registers for sending data to tribe members. (E.g.: the memory named activeLocation, in which the tribal object will place location data for the tribe members to locateOp on them... as the place of the new building, or the place of a resource, or the place of a nearby tribe) Using this we can load data in the register, and fire a reaction to send members to work on "tribe:memory:activeLocation", for example. | |||
* | |||
==Parser Class== | ==Parser Class== |
Revision as of 16:15, 9 July 2011
Idea
Prerequisite
For this system to work, an npctype named "AbstractTribesman" needs to be declared in 'data/npcbehave.xml'.
The functioning of the tribe system is based on the following steps:
Step #1 (Loading Stuff)
(executed only once, on NPCClient's startup. No further interrogation on the database should be done)
On NPCClient's startup everything is loaded into the classes.
The Recipe Manager loads all available recipes from mysql:'tribe_recipes'.
During load, the Recipe Manager parses the requirements and keeps them in the Recipe Class. (Recipe::requirements<Recipe::Requirement>)
The Tribal Object receives all the information regarding the tribe:
- resources from mysql:'sc_tribe_resources'
- memories from mysql:'sc_tribe_memories'
- knowledge from mysql:'sc_tribe_knowledge'
- basic tribe information from mysql:'tribes' (including the ID of the tribal recipe, more details below)
- npc's are loaded by the psNPCClient and assigned to the tribe
Further on, each Tribal Object is linked to in the Recipe Manager. (a pointer is sent and loaded into a csArray) For each tribe loaded, the Recipe Manager does the following:
- assembles a data structure named 'TribeData'
- links the tribal recipe belonging to this tribe to 'TribeData'
- parses the information in the tribal recipe and assign the stats to csStrings in 'TribeData'
- computes a tribal npctype having as parent the 'AbstractTribesman' npctype. The difference is done by adding reactions to whatever the tribe reacts to. (attacking any player nearby or simply greeting them, sleeping at day or at night, etc)
Step #2 (RunTime)
(executed once on startup and each time a recipe is completed)
The Tribal Object selects the top recipe which needs execution and sends it to the Recipe Manager.
The Recipe Manager parses the contents of the recipe:
- checks for requirements. If requirements are met it proceeds with parsing the algorithm (see step #3). If requirements are not met, it pushes the Recipes with achieves the requirement on top of the tribe's recipe list
Step #3 (Recipe's Algorithm)
(executed for each step the algorithm has, each time a recipe needs execution)
The Recipe has an algorithm stored as a csArray<csString>. When an algorithm needs an execution, the Recipe Manager takes each string and parses it. Depending on the rules we set, the Recipe Manager will tell the tribal object which perceptions to fire on their npcs.
(E.g.: If the recipe's algorithm require us to send 10 workers to build a town hall, the tribal object will be told to fire a "go to work" perception on 10 worker tribesman)
Tribal Object
The tribal object will suffer some changes in order to support the above-mentioned capabilities:
- a knowledge array of strings: it contains only the name of the knowledge received by the tribe from completing recipes. They act more as tokens to prove completion. They are needed because recipes may require knowledge. (E.g.: if we want our tribe to build axes for it's warriors, we need the ironworks knowledge)
- an array of Recipe pointers which acts more as a priority queue for keeping recipes. Initially, only the tribal recipe will be there. After initialization, persistent recipes (which will never expire) will be pushed there and act as goals for the tribe. Based on the goals, normal recipes will be pushed there... and if requirements are not met... recipes to meet the requirements... and the list can go on forever.
- some memory entries which act as registers for sending data to tribe members. (E.g.: the memory named activeLocation, in which the tribal object will place location data for the tribe members to locateOp on them... as the place of the new building, or the place of a resource, or the place of a nearby tribe) Using this we can load data in the register, and fire a reaction to send members to work on "tribe:memory:activeLocation", for example.
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.