|
|
(14 intermediate revisions by the same user not shown) |
Line 1: |
Line 1: |
| ==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.
| |
|
| |
| ==Recipe Manager==
| |
|
| |
| '''Recipe'''
| |
|
| |
| Definitions:
| |
| *Unique Recipe: recipe which can be executed only once. Like recipes to gain a knowledge, or build unique buildings.
| |
| *Persistent Recipe: recipe which never ends. Usually, these recipes will contain tribe information or goals which tribe will follow forever.
| |
|
| |
| A recipe object holds all details regarding the process of doing tasks.
| |
|
| |
| It holds:
| |
| *flag to signal a unique recipe
| |
| *flag to signal a persistent recipe
| |
| *a requirement data structure which flags it's name, type and number of entitites required
| |
| *csStringArray for holding algorithm steps
| |
| *csArray for holding requirements
| |
|
| |
|
| |
| '''Recipe Manager'''
| |
|
| |
| It holds:
| |
| *a list of enrolled tribes and a tribeData structure for each of them
| |
| *a list of recipes loaded
| |
|
| |
| Main operations the Recipe Manager does are explained above in the 'idea' tab.
| |
|
| |
| It's in development how the recipe manager should track recipes. I'll add more details as soon as I got a good picture of it.
| |
|
| |
| ==Database changes==
| |
|
| |
| The database needs to suffer some changes for this to work.
| |
|
| |
| '''tribe table'''
| |
|
| |
| Added a column to hold the tribal recipe.
| |
|
| |
|
| |
| '''tribe_recipes table'''
| |
|
| |
| It will contain all the recipes described by:
| |
| *ID
| |
| *Recipe Name
| |
| *Requirement Script
| |
| *Algorithm
| |
| *Persistent
| |
| *Uniqueness
| |
|
| |
|
| |
| {| border="1"
| |
| !ID
| |
| !Name
| |
| !Requirement
| |
| !Algorithm
| |
| |-
| |
| | 1
| |
| | "Mine Coal"
| |
| | "tribesman(gatherer,1);item(pickaxe,1);"
| |
| | "goToMemory(coal);equip(pickaxe);dig;goTo(hoilme);alterResource(coal,1)"
| |
| | 0
| |
| | 0
| |
| |-
| |
| | 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)"
| |
| | 0
| |
| | 0
| |
| |}
| |
|
| |
|
| |
| '''sc_tribe_knowledge table'''
| |
|
| |
| It keeps the knowledge gained by the tribe.
| |
|
| |
| {| border="1"
| |
| !id
| |
| !tribe_id
| |
| !knowledge
| |
| |-
| |
| | 1
| |
| | 1
| |
| | "Leatherwork"
| |
| |-
| |
| | 2
| |
| | 1
| |
| | "Mineworks"
| |
| |}
| |
|
| |
| == Provisional Functions ==
| |
|
| |
| Below is a list of functions which will be used to script recipes. Please note that this list is provisional. It will become final as soon as we have a solid list which allows us to do anything tribe-related.
| |
|
| |
| {| border="1"
| |
| !function
| |
| !type
| |
| !arguments
| |
| !effect
| |
| |-
| |
| |brain(x)
| |
| |tribe info
| |
| |{ civilised, savage, inhuman }
| |
| |decides the advancement of this tribe
| |
| |-
| |
| |aggressivity(x)
| |
| |tribe info
| |
| |{ warlike, neutral, peaceful }
| |
| |decides how tribe members will react to entities coming near them
| |
| |-
| |
| |growth(x)
| |
| |tribe info
| |
| |{ expansionist, normal, conservatory }
| |
| |decides the expansion rate of the tribe
| |
| |-
| |
| |unity(x)
| |
| |tribe info
| |
| |{ organised, normal, cowards }
| |
| |decides how members will react if a fellow is attacked
| |
| |-
| |
| |tribesman(x,y)
| |
| |requirement
| |
| |x is a tribe member type, y is a number
| |
| |used by recipes to require able-to-work tribesman
| |
| |-
| |
| |resource(x,y)
| |
| |requirement
| |
| |x is a resource type, y is a number
| |
| |used by recipes to require an amount of resources
| |
| |-
| |
| |knowledge(x)
| |
| |requirement
| |
| |name of knowledge (knowledges discussed above)
| |
| |requires a knowledge
| |
| |-
| |
| |item(x,y)
| |
| |requirement
| |
| |x is an item's name, y is the number of items
| |
| |requires items
| |
| |-
| |
| |recipe(x,y)
| |
| |requirement
| |
| |x is a recipe's name, y is the number of recipes
| |
| |require a recipe
| |
| |-
| |
| |alterResource(x,y)
| |
| |algorithm step
| |
| |x is the resources name, y is the value to alter with
| |
| | Pretty self-explaining :D
| |
| |-
| |
| |loadLocation(x,y,z)
| |
| |algorithm step
| |
| |x,y,z are float numbers
| |
| |loads this location into tribe:memory:activeLocation
| |
| |-
| |
| |go()
| |
| |algorithm step
| |
| |none
| |
| |makes the npcs go to tribe:memory:activeLocation
| |
| |-
| |
| |locateMemory(x)
| |
| |algorithm step
| |
| |x is a memory's name
| |
| |loads the memory's location into tribe:memory:activeLocation
| |
| |-
| |
| |locateResource(x)
| |
| |algorithm step
| |
| |x is a resource name
| |
| |loads the nearest resource of this type into tribe:memory:activeLocation
| |
| |-
| |
| |}
| |
|
| |
| Much more algorithm steps will be added soon.
| |
|
| |
| == AbstractTribesman npctype ==
| |
|
| |
| This npctype is a parent for all npctypes tribe members will have. It holds behaviors only.
| |
|
| |
| == 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.
| |