This replaces the previous draft and is based on the new knowledge of client entrails of all sorts as acquired during those past 2 months. It is however still a draft in that it uncovers some new questions (at least new to me) and it requires anyway some feedback and discussion given its scope and crucial position in the SMG Communication Protocol. It's published as it is at this stage and by the promised deadline not because it's "complete and final" but mainly because I need to have this version exposed for further discussion in order to be able to advance it further.
While I was already trying in the previous draft to figure out more clearly the scope and nature of the desired hierarchy, this became clearer only after getting a better understanding of the various data the client uses and especially after further discussion in the SMG boardroom of the protocol specification. The previous observation that there are 3 types of information in there (structure, description, representation) is as correct now as it was then. But meanwhile, as I got to understand better all the different domains involved, the high-level view evolved to this:
- Game World
- Concrete objects
- Terrain
- Water
- Air
- Characters
- Structures/Items 1.
- Abstract objects
- Time
- Self
- Sector
- Concrete objects
- Representation
- Graphical
- 3D
- 2D
- Skin/GUI
- Audio
- Graphical
Before going further and into the hairier details, it's worth stating the important distinction that the protocol specification makes between the two types of "resources" that the client can ask for:
- Files - relevant protocol messages 4.4 File Request and 4.3 File Transfer.
- Objects - relevant protocol messages 4.7 Object Request and 4.8 Object Info (ie "Transfer")
The Files are - from the protocol's point of view - "big" resources that never contain other resources. Files are referenced by their full name that works therefore exactly like an id (although a text-id rather than a numerical id).
The "objects" are - from the protocol's point of view - "small" resources of a potentially composite sort. This means specifically two things: any object will always fit into one single message; an object may contain references to any number of other resources (ie references to other objects and/or to any number of files). An object is given (via a 4.8 message) as a list of tuples (id:type). Each such tuple is the reference (the "id" part) to one "property" of the object, where the term property is quite generic: any object can be at some time or another a "property" of another object. Note also that "id" is not necessarily a numeric id - a filename (with full path included, where relevant) is effectively the "id" of the actual file.
The hierarchy starts with the single object that has no id (otherwise put it has the "null" value as id). Since all things have to start from somewhere, so does Eulora's language of knowledge - in the beginning, it is always "null". If you think of the hierarchy correctly as a tree, this object with "null" as id is the root from which there can be ultimately any number of levels - the hierarchy is *not* restricted on either direction (ie any node can have in principle any number of children and any path may be arbitrarely long). The leaf nodes will *always* have "Final" as given type in the tuple (id:type). The id in the tuple (id:type) of a leaf node is either a filename (ie the id of a file, one can think of this as value given by reference) or otherwise a value that is used directly as it is, as data (e.g. helmet.png:Final or 5:Final). All values given at a leaf node will be one of the following basic types:
- int8/uint8
- int16/uint16
- int32/uint32
- int64/uint64
- float (4 bytes)
- position (3 int16 as per protocol specification)
- rotation (3 int8 as per protocol specification)
- text (2 uint8 giving total size, followed by up to 1470 characters.
- rgb (3 uint8 standing for red, green and blue 2 )
- rgba (4 uint8 storing red, green, blue, alpha)
- size2D (2 uint64 height,width)
- size3D (3 uint64 height, width, depth)
The root of all the world (the object with "null" as id) is the object that the server sends (via a 4.6 World Bulletin message) in response to an Object Request (4.7) that contains an unknown/non-existent object id. The hierarchy as I managed to flesh it out so far is given as id:type with comments after > :
-
Root > there is only ONE object of this type and that object has id "null"
- Top_Location_ID : Sector > current sector; player's character is somewhere in the subtree of this object (eg may be in a room that is in a house in this sector, perhaps).
- Self_Info_ID : Self > id of the abstract object, not the id of the player's concrete character object.
- Current_Date_ID : Date > euloran date
- Current_Time_ID : Time > euloran time
- Client_Skin_ID : ModSkin > graphical user interface resources
-
Sector
-
CurrentNameID : Name
- Value (text): Final
- Terrain_ID : Terrain > the heightmap (+ material palette)
- Air_ID : Air > ambiental light and weather (?)
- (Light_ID : Light)* > NB: zero or more; those are purely sources of light (NOT ambiental light which is a property of Air), without physical representation other than the light itself.
- (Water_ID : Water)* > bodies of water
- (Character_ID : Character)* > anything that is active/can move;
- (Structure_ID : Structure/Item)* > anything that is passive/can't move and is not terrain/air/water/weather
-
CurrentNameID : Name
-
Self > this includes all the stuff that is specific to self (ie known only about own Character) as opposed to the generic info given via Character type (ie info available for all characters encountered, whether self or not)
- CurrentPlayer_ID : Character > player's actual character with data that everyone can access/see
-
Current_Loc_ID : LocID > should the location ID be here? (otherwise in principle client can fully search the tree until it finds CurrentPlayerID as contained in some location)
- Value (uint32): Final
-
Date_Of_Birth_ID : DOB
- Value (date) : Final
- Vitals_Profile_ID : VitalsProfile
- Skills_Profile_ID : SkillsProfile
- Inventory_ID : Inventory
- Equipment_ID : Equipment
-
Inventory
- (Item_ID : Structure/Item)*
-
Equipment > How is equipment different really from Inventory? I can't see any real reason to make it a separate type. "Equip" is an action and as such it will fail if the item doesn't "fit" the destination, be it because it's not equippable or whatever. Similarly, the "how it looks" is a matter of checking what is in some slots if one so wants. The only thing: the meaning of "positions" in inventory should be defined, at least for those that have a specific meaning beyond "in the bag".
- (ItemID : Structure/Item)*
-
Date > this could be in principle simply unixtime number but that wouldn't match well/easily with custom year/month sizes (?) + presumably custom month names rather than numbers (?)
- Year_ID : Year
- Value (text) : Final > should those be numbers?
- Month_ID : Month
- Value (text) : Final > should those be numbers?
- Day_Of_Week_ID : DoW
- Value (text) : Final > should those be numbers?
- Year_ID : Year
-
Time
- Hour_ID : Hour
- Value (uint8) : Final
- Minute_ID : Minute
- Value (uint8) : Final
- Second_ID : Second
- Value (uint8) : Final
- Hour_ID : Hour
-
ModSkin > should this cover *also* layouts & windows & UI components or only strictly "art" resources? If it's the later, in principle it's simply a list of images (with at most width, height, alpha, transparency)??
- (UI_Art_ID : UI_Image | UI_Spritesheet) *
-
UI_Image
-
(Name_ID : Name)? > CS uses everywhere names for IDs and sprite sheets won't be fine with filename as name for each sprite; onth perhaps client should just generate its own "names" out of object id and/or filename if it needs them?
- Value (text) : Final
-
Size_2D_ID : Size
- Value (size2d) : Final
-
Transp_ID : Transparency
- Value (rgb) : Final
-
Alpha_ID : Alpha_Lvl
- Value (float) : Final
-
File_ID : Image > should all be .dds or .png or fixed format?
- Ref (text) : Final
-
(Name_ID : Name)? > CS uses everywhere names for IDs and sprite sheets won't be fine with filename as name for each sprite; onth perhaps client should just generate its own "names" out of object id and/or filename if it needs them?
- UI_Image_ID : UI_Image > for the sheet as a whole, it still has all the details
- (UI_Sprite)+
-
(Pos_ID : Position)? > for sprite sheets - position in parent image
- Value (position) : Final
-
(Name_ID : Name)? > CS uses everywhere names for IDs and sprite sheets won't be fine with filename as name for each sprite; onth perhaps client should just generate its own "names" out of object id and/or filename/whatever if it needs them?
- Value (text) : Final
- (VitalID : Vital)*
- Name_ID : Name
- Value (text) : Final
- Current_Value_ID : CurrentValue
- Value (uint8) : Final > assuming that those are still given as % of max
- (Skill_Group_ID : SkillGroup)*
- NameID : Name
- Value (text): Final
- (Skill_ID : Skill)*
- Name_ID : Name
- Value (text): Final
- Rank_ID : Rank
- Value (uint64): Final
- Practice_ID : Practice
- Value (uint8) : Final
> assuming given as %
- Knowledge_ID : Knowledge
- Value (uint8) : Final
> assuming given as %
- Name_ID : Name
- Value (text): Final
- Sex_ID : Sex > is this given and in what form? is it known for anyone or just for self?
- Value (uint8): Final
- Position_ID : Pos
- Value (position): Final
- Rotation_ID : Rot
- Value (rotation): Final
- Model_3D_ID : ModCal3D
- (Model_2D_ID : Mod2D)? > 0 or 1
- (Model_Audio_ID : ModAudio)? > 0 or 1
- (Model_Effects_ID : ModEffects)? > 0 or 1
- Name_ID : Name
- Value (text): Final
- Stack_Count_ID : StackCount > this will just be 1 for houses / some cases.
- Value (uint64): Final
- Quality_ID : Quality > this may be called "durability" for eg tools or houses but it's same thing anyway.
- Value (uint64): Final
- Position_ID : Pos
- Value (position): Final
- (Model_3D_ID : ModCal3D)? > ONE of the models 3d/2d should be present in general
- (Model_2D_ID : Mod2D)? > 0 or 1
- (Model_Audio_ID : ModAudio)? > 0 or 1
- (Model_Effects_ID : ModEffects)? > 0 or 1
- NameID : Name
- Value (text): Final
- Position_ID : Pos
- Value (position): Final
- Height_Map_ID : Heightmap > NB: while both materialmap and heightmap are images (and even of same type + same size, listing them as "IMAGE" type means that the role (i.e. which one is Heightmap and which one is MaterialMap should be defined somewhere else - would that be better/how?)
- Ref (text): Final
> filename, hence "Ref", currently "Island.png"
- Material_Map_ID : Materialmap
- Ref (text): Final
> filename, hence "Ref", currently "Island_alpha.png"
- (Material_ID : Material)* > material palette to use (eg sand, grass, stone)
- AmbientLightID : AmbientLight > all lights should be "dynamic" or at any rate the static/dynamic distinction is entirely client-side concern ; currently those values are given at different "times of day" + interpolated by client in between, but I don't see the *need* for hours in here; client can decide on its own if /when it wants to sample this and what/whether to interpolate or do anything else with the values it gets.
- Value (rgb) : Final
- Weather_ID : Weather
> therefore "water" could simply be in principle an item/structure with the "water" texture applied - TO CHECK.
- Item_ID : Structure/Item
> as such, those could be just part of the "sector" at some point + corresponding changes to light & sky, if any. TO CHECK
> however, there can be perhaps the point of having this separate to set specific params such as emission rate, velocity etc. ?
- Particle_Syst_ID: Particle_System > if going this route, this is TBF
-
BB_Size_ID : BoundingBox > this is used for collision detection
- Value (size3d) : Final
-
Skeleton_ID : Skeleton > this is MANDATORY; all moving stuff have to have a skeleton
- Ref (text) : Final
> this is a .csf file for now; should the format be a further level/property?
- (Animation_ID : ModAnim)* > a character may have any number of animations
- (Submesh_ID : ModMesh)* > parts/subparts of the model; NB: atm sockets is still not used/unclear!
-
Scale_ID : Scale > intended scale of the model, this is a transformation to apply before use
- Value (float) : Final
-
Translation_ID : Trans > pre-transform to apply, translation; same as for scale - could be standard and therefore spec not needed?
- Value (3xfloat): Final
-
Rotation_ID : Trans > pre-transform, rotation; same std issue as above.
- Value (4xfloat): Final > (x,y,z,angle)
-
RotX_ID : RotX > IF the model should be pre-rotated along the x-axis; again, should be std and be done with. Default is true
- Value (boolean): Final
-
FlipTex_ID : FlipTex > whether v coordinates of texture should be flipped (i.e. whether 0,0 in texture space should be top left or bottom left); default is false
- Value (boolean): Final
-
Name_ID : Name > name is used as an id by CS... eg "walk", "run", "jump"
- Value (text) : Final
-
File_ID : File > this is a .caf file for now; should format be a deeper level?
- Ref (text) : Final
-
Type_ID : TypeAnim
- Value (uint8) : Final > idle, travel, cycle, action, none, style_cycle currently from CS&PS - WTF?? do we even want such a thing?
- Vel_ID : Velocity
-
Time_ID : Interval > this is "interval for idle or override actions", in seconds
- Value (2xfloat): Final
-
Idle%_ID : Idle% > this is "probability (as %) of this action being the overriding action"
- Value (float) : Final
-
Base_ID : Base_Vel > speed of translation when animation is used on its own
- Value (float) : Final
-
MinVel_ID : Min_Vel
- Value (float) : Final
-
MaxVel_ID : Base_Vel > min and max are used by CS's internal "blender" to get what precise speed is required at one point or another
- Value (float) : Final
-
MeshFile_ID : MeshFile > format is .cmf ; should format be a lower level?
- Ref (text) : Final
-
Size_ID : Size > is this actually mandatory/needed here? Can't quite yet tell.
- Value (size3d) : Final
-
Name_ID : Name > name of this part of the model, eg "Head", "Neck", "Left_Arm"
- Value (text) : Final
- Material_ID : Material > CS allows several materials mixed on a mesh (though on occasion with this sort of thing it "allows" while at the same time complaininig if too many textures or too many this and too many that) but I'd stick to ONE material only.
- Material_ID : Material > while several materials can in principle be used, I'd rather stick to ONE material since *that* can combine several textures anyway.
-
(Vertice_ID : Vertex)* > one vertex as a minimum
- Value (position) : Final > this is given in model's own coordinate space
-
(Triangle_ID : Triangle)* > each triangle is given as (i1,i2,i3) where i1-3 are indices of the vertices given previously
- Value (3xuint64): Final
-
(Normal_ID : Normal)* > there should be one normal vector given for *each* vertex
- Value (3xfloat) : Final
-
(Colour_ID : RGBA)* > there should be the colour given for *each* vertex
- Value (4xfloat) : Final > this means r,g,b and alpha channel
-
(Texture_Map_ID : TexMap)* > there should be mapping from each vertex to a texture point (ie u,w coords)
- Value (2xuint) : Final > these are coordinates in the 2d, discrete space of the texture
- Texture_ID : Texture > NB: this currently is "texture2d" but it's unclear if the distinction is worth much (ALL textures are anyway 2d images, ffs)
-
Transparent_ID : rgb
- Value (3xfloat) : Final
-
Alpha_ID : Alpha > this is int in the current code, hm.
- Value (int8) : Final
-
Pos_ID : position
- Value (3xfloat) : Final
-
Size_ID : Size > height and width
- Value (2xint) : Final
-
Name_ID : Name > CS uses "names" in fact as IDs; so there can be several materials with same texture/file/data but different names...
- Value (text) : Final
- Texture_ID : Texture > CS works with materials (it wraps any plain texture into a material anyway)
- (Shader_ID : Shader)* > a material CAN have several shaders applied.
- (ShaderVar_ID : ShaderVar)* > those are used *across* shaders to customise them, hence put here as separate, ugh; I think though that they belong more logically as a property of each Shader.
> There are ALSO, "texture classes" but it's totally unclear if they bring anything useful or if they are anyway a server concern at all; from the manual (p. 331/644): texture class = collection of settings controlling how a texture is uploaded to the Graphics hardware (e.g. lookup, normalmap, nocompress) + "adding semantics".
-
Name_ID : Name
- Value (text) : Final
-
Image_ID : TexImage > at this stage it's unclear if stuff like size should be given explicitly since it should rather be either extracted from the file itself (?) or default/predefined (?)
- Ref (text) : Final
-
Name_ID : Name
- Value (text) : Final
- ShaderTypeID : Name > ugh; those are again predefined CS stuff/available shader types...
-
File_ID : File
- Ref (text) : Final
> filename containing the shader description; atm those are a bunch of xml files, full of dependencies & referencing one another + cs-specific.
-
Name_ID : Name > NB: those names need to match what shaders (those xml files) know/expect, for anything to work...
- Value (text) : Final
-
Value_ID : Texture|Float|2xFloat|3xFloat > the value of the shader variable has one of those types
- Value : Final
-
Name_ID : Name
- Value (text) : Final
-
CentreID : Centre
- Value (3xfloat): Final
-
ColourID : rgb
- Value (3xfloat): Final
-
AttenuationID : Attenuation > "type" of attenuation (?)
- Value (uint8) : Final
-
RadiusID : Radius
- Value (uint16) : Final
As full of holes and possibly over-wordy and all that as the above draft finds itself, it was still quite the toil to extract. Nevertheless, extracted and written down it had to be as I couldn't quite move any further without this step. Now that it's pinned down, I can go through it and discuss the questions/issues that are still unclear throughout. There are also a few aspects that are currently still entirely missing (not that the rest is guaranteed to be complete/final), namely:
- Some meta resources - most notably authorship of art files - are still missing entirely. I'd rather discuss/iterate first those concrete (relatively) parts extracted from client-entrails before moving on and fixing the details of that, since it's more likely to be actually easier anyway as it's way more clearly and sanely defined to start with.
- ModAudio - the definition of this is still missing as I never even bothered yet to get the SoundPlugin to work at all. Perhaps it can be added/fleshed out later on and then clients that know it / want it will use it, while the rest will simply ignore it as an unknown/un-usable part.
- ModEffects - this is also still missing but unlike the audio part, this could be more readily investigated and fleshed out more, by figuring out how to load/create effects from code directly, similar to the previous work on characters for instance.
- Water - this requires an investigation into creating water bodies from the code directly; specifically: some practical experience using CS's procedural textures and some tests to see if/to what extent this could/couldn't be folded into structure/item
- Weather - this requires an investigation into CS's particle systems at the very least (for snow/rain/etc) and some more reflection + testing to check if it makes perhaps more sense to fold this into Air anyway.
- This is just one type, the name is given like this to make it clear that both "items" such as an axe or a flower and "structures" such as a house or a bridge are in here. Basically anything that is not terrain/water/air and can't move by itself is in here (if it can move by itself then it's in Characters) [↩]
- NB: CS uses floats, with 1,1,1 for white and 0,0,0 for black.[↩]