Eulora Client Graphics: Main Types and Formats

June 22nd, 2020 by Diana Coman

Having made by now a full graphics generator that produces everything, from textures to meshes and full animations too1, I can also finally get out of the existing swamp of data somethings and provide instead a clear list of types, formats and files that are actually quite enough for client's needs. Basically there are only 3 big types, each requiring a bunch of specific files:

  1. Outdoors type (or "sector", "area", "zone", "world", whatever you want to call it, the point is that it has some solid terrain, some sort of "water" in the lower parts and some sort of "sky" that should arguably be in the upper parts only but is in practice all-surrounding). This is the most involved type as it requires three parts, each with its own bunch of specific files2:
    1. Terrain, requiring the following files:
      • heightmap.png
      • materialmap.png3
      • lightmap.png
      • normalmap.png
      • basemap.png
      • tex_1.png4
      • tex_2.png
      • tex_3.png
      • norm_1.png5
      • norm_2.png
      • norm_3.png
    2. Water6, requiring the following files:
      • tex.png
      • tex_reflected.png7
    3. Sky8, requiring the following files:
      • tex.png
  2. Non-moving type, aka CS mesh, requiring the following files:
    • meshfactory.csmesh9
    • tex.png
  3. Moving type, aka Cal3d, requiring the following files:
    • skeleton.csf (or .xsf)
    • any number of .caf (or .xaf) files - the animations. Those may have in principle names matching the "type of animation" they are meant for but note that on one hand CS/Cal3d has a limited and fixed number of such "types" (specifically: idle, travel, cycle, style_cycle and action) and on the other hand it's not all that clear what's the point of them since the more important part is otherwise setting for each some use parameters, of which the most important are the speed interval for which that animation is relevant (hence, when it will be used) and whether to lock in the final pose or not.
    • any number of .cmf (or .xmf) files - the meshes making up this model and including the texture mapping. Note that different models have different number of meshes and there is no specific order in which the meshes are numbered either. As a pattern at the moment I'm simply using mesh_id.xmf as name for the file and loading until no file found.
    • tex.png (or .dds) - the texture to use for ALL meshes; alternatively, any number of tex_id.png so that each mesh has its own texture, supposing that this might be useful at some point.

In addition to the above, there are a few more formats that are simply one file each, used as such: icons (simply a .png or .dds file), sounds (.ogg or .wav) and perhaps particle systems that will need a SMG format since there is no file/format for them at all, only all sorts of code-side settings of this and that. Currently and as per previous discussion, the sounds are not going to be supported but I mention here for completeness the formats known to work with CS.

All image files may in principle be either .png or .dds, with the .dds format the preferable one (takes less space and requires less computations client-side). This being said though, the client should work with either/both and there is only a reasonable requirement that the size be a power of 2. Current textures are all 512x512 pixels and any change to this needs to be matched with a change to the texture mappings provided for each mesh and so on - in other words, I think the correct approach here is simply to bundle together as above the mesh definition with the texture it is meant to use and don't even bother otherwise to explicitly provide whatever number of different sizes - the size of an image is anyway included in the file so whoever is interested to extract it may do so directly from there.

The above description of types and formats marks a fundamental shift in approach and since this cleared up for me only gradually as a result of all the work sunk into the graphics and client side since the beginning of this year, I'd rather set it out explicitly here. The old client's approach focused on loading everything upfront and keeping it all in memory, based on the assumption that there are somehow great gains to this by means of extensive reuse of assets once loaded. In practice I fail to see those gains but there is otherwise ample cost clearly visible and always paid upfront10: fixed and difficult to expand set of assets, long - and moreover, getting longer ie *worse* with any extension of the assets!- initial loading time for the client as a whole, significant overhead required to support the reuse fantasy because otherwise there's precious little reuse when it comes to meshes and characters and even textures. Basically the old idea is of having a central catalogue of all graphics assets and then referencing those from everywhere else. By contrast, my current approach has no such central catalogue and relies instead on each element that requires some graphics assets to know where to find them and possibly have them in its own directory. Essentially, the current approach considers disk space cheap (though NOT network communications - note that assets may end up duplicated locally but in principle they don't *have to* be also sent 1000 times over the wire; it can very well be perhaps the job of the data acquisition module to duplicate files if/when needed and/or set them or link them where expected), discards the reuse pretense and relies instead on minimal overhead as well as minimal, on-demand loading (potentially coupled at implementation time with aggressive clear up of unused resources if memory gets clogged otherwise).

While the above is not yet set in stone, it might very well soon become set, so let me know if you see any trouble with it or if there's some better way to go about it that I just don't see yet.


  1. For the curious, *all* this stands currently at 5581 lines of code+comments+tests+png writer + convenience scripts. No, I did *not* forget any 0 at the end and no, it doesn't require external libs, platforms whatever-else, it's standalone, C, gawk and bash code only. 

  2. The .dds format is in principle better but in practice all image files may end up either .dds or .png so the client side will have to make do with what is provided, perhaps run its own conversions if it has to. 

  3. Also known as alpha map, if that helps you any. 

  4. These are the materials that get used/applied depending on the height and on the basemap - while logically speaking I would just say any number of materials should work, in practice the existing terrain plugin wants exactly and precisely 3, not more nor less. This being said, the format from my point of view will be tex_number files and load as many or as few as your client can use. 

  5. Those are normals for the corresponding texture and in principle they are optional though the terrain will likely look worse without them. 

  6. The current implementation does require a bunch of other settings such as reflection coefficient and whatnot but I think that's strictly a client-side concern so entirely locally-set, nothing to do with getting it from the server. 

  7. This is a texture to be reflected by the water and it's optional. Currently this is the sky's image. 

  8. Note that the current implementation does require all sorts of other "options", from picking the geometry of the sky (!) to a whole bunch of shader variables. Nevertheless, I don't see why would any of that be a concern outside of each client - so they'll be set locally, change your client as you want it if you are fed up with the sphere-sky or something. 

  9. XML file in CS "meshfact" format, which can be loaded directly with CS's loader and then instantiated as and when desired. It contains the following information: position of all vertices, normals of the surface at each vertex, texture coordinates at each vertex, triangles making up the surface. These are effectively listed as such, since this is what CS expects. Note that the format forces the mesh to include a fixed texture mapping, but any texture can be used at load time - how well it will fit or not the mapping is a different matter. 

  10. Come to think of it, this does strike me now as very much the typical problem: paying upfront a significant price for.... not missing an opportunity that never materializes though, huh.