• Welcome to the new COTI server. We've moved the Citizens to a new server. Please let us know in the COTI Website issue forum if you find any problems.
  • We, the systems administration staff, apologize for this unexpected outage of the boards. We have resolved the root cause of the problem and there should be no further disruptions.

Proposed Character File Format

agorski

SOC-13
Admin Award
I've decided to update the chargen apps I've written for CT to add the ability to save completed characters to a file and to add the ability to re-open the saved files for printing. I will also want to use these files in future apps, yet to be developed, so I want the file format to be universally useful. I've incorporated fields from the MT TAS Form 2, which has more stuff than the CT form. Based on the success of the human-readable .sec format, I've decided to do the same thing for character files.

Here's my proposed format, with sample data. I'd appreciate any comments or suggestions.

Code:
CHARACTER FILE v1.0

The data in the character file (padded with spaces if necessary) is defined as:

Line 1:
 1-16: Character Name
17-27: Noble Title
   28: -
   29: Strength
   30: Dexterity
   31: Endurance
   32: Intelligence
   33: Education
   34: Social Standing
   35: -
36-37: Age
   38: -
39-40: Apparent Age
   41: -
42-49: Character Creation Date (mm/dd/yy)
50-57: Character Modification Date (mm/dd/yy)
58-60: Counter ID (for use with Snapshot or Azhanti High Lightning)
   61: -
   62: Terms
   63: -
   64: Officer?
   65: Academy Grad?
   66: College Grad?
   67: Honors Grad?
   68: OTC?
   69: Retired?
   70: TAS Member?
   71: Psionics Trained?
72-77: Retirement Pay

Line 2:
 1-15: Career
16-35: Arm/Branch/Office/Department
36-46: Line (Merchants only)
47-72: Final Rank
   73: -
74-75: Final Rank Number
   76: -
   77: Traveller Rank Number   

Line 3 (Home World) and Line 4 (Discharge World):
 1-20: Sector Name
21-40: Subsector Name
41-60: Name
   61: Starport Code
   62: Size Code
   63: Atmosphere Code
   64: Hydrographics Code
   65: Population Code
   66: Government Code
   67: Law Level Code
   68: -
   69: Tech Level Code

Line 5:
 1- 2: Number of unique Special Assignments (SANum)

If SANum > 0: Next SANum Lines:
 1-30: <Special Assignment Name>-<Number of Occurrences>

Next Line:
 1- 2: Number of unique Awards and Decorations (AwNum)

If AwNum > 0: Next AwNum Lines:
 1-30: <Award Name>-<Number>

Next Line:
 1- 2: Number of unique Skills (SkNum)

If SkNum > 0: Next SkNum Lines:
 1-30: <Skill Name>-<Level>

Next Line:
 1-10: Cash

Next Line:
 1- 2: Number of unique Possessions (PoNum)

If PoNum > 0: Next PoNum Lines:
 1-30: <Possession Name>-<Number>

Next Line:
 1- 3: Number of Lines in Character Generation Log (LogNum)

Next LogNum Lines:
 1-40: Character Generation Log Entry

....+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....

Wolf Blitzer    Knight     -79858B-30-30-5/6/11  5/6/11  G12-3-10000000     0
Army           Infantry                       Second Lieutenant         - 1-1
Spinward Marches    Regina              Efate               A646930-D
Spinward Marches    Regina              Regina              A788899-C
 2
OCS-1
Protected Forces Training-1
 3
Combat Service Ribbon-2
Command Ribbon-5
MCUF-1
11
Administration-1
Advanced Combat Rifle-1
Assault Rifle-1
Automatic Pistol-1
Carbine-1
Gauss Rifle-1
Grav Vehicle-1
Revolver-1
Rifle-1
Vacc Suit-4
Zero-G Combat-1
     10000
 1
Automatic Pistol-1
 96
Age=18
Strength=7
Dexterity=9
Endurance=8
Intelligence=3
Education=8
Social Standing=B
Noble Title=Knight
Term 0 Assignment 0
Marines enlistment attempt failed
Service=Army
Denied admission to Military Academy
Denied admission to College
Enlisted in Army
Term 1 Assignment 1
Arm= Infantry
Assigned to Basic Training
Rifle +1
Carbine +1
Assault Rifle +1
Advanced Combat Rifle +1
Gauss Rifle +1
Promoted to Private
Assigned to Advanced Training
Vacc Suit +1
Age=19
Term 1 Assignment 2
Assigned to active duty unit
Mission: Counter Insurgency
Awarded Combat Service Ribbon
Promoted to Lance Corporal
Age=20
Term 1 Assignment 3
Assigned to Protected Forces Training
Vacc Suit +1
Zero-G Combat +1
Age=21
Term 1 Assignment 4
Assigned to active duty unit
Mission: Garrison
Promoted to Corporal
Age=22
Reenlistment successful
Term 2 Assignment 1
Assigned to active duty unit
Mission: Garrison
Age=23
Term 2 Assignment 2
Assigned to active duty unit
Mission: Training
Promoted to Lance Sergeant
Vacc Suit +1
Age=24
Term 2 Assignment 3
Assigned to OCS
Grav Vehicle +1
Administration +1
Vacc Suit +1
Promoted to Second Lieutenant
Age=25
Term 2 Assignment 4
Assigned to active duty unit Command
Mission: Garrison
Awarded Command Ribbon
Age=26
Reenlistment successful
Term 3 Assignment 1
Assigned to active duty unit Command
Mission: Garrison
Awarded Command Ribbon
Age=27
Term 3 Assignment 2
Assigned to active duty unit Command
Mission: Counter Insurgency
Awarded Combat Service Ribbon
Awarded Command Ribbon
Awarded the MCUF
Age=28
Term 3 Assignment 3
Assigned to active duty unit Command
Mission: Garrison
Awarded Command Ribbon
Age=29
Term 3 Assignment 4
Assigned to active duty unit Command
Mission: Training
Awarded Command Ribbon
Revolver +1
Automatic Pistol +1
Age=30
Forced to muster out
Cash benefit: CR10000
Int +1
Int +1
Weapon: Automatic Pistol
 
I'd suggest instead using an XML structure. While not as compact, it's easier to encode/ extract and has no padding.

Further, Each term/assignment should be collapsed to a short string...
Pos L Desc.
000 1 Career
001 1 Assign (0= basic, 1=basic SD, 2+ adv assigns then SD's)
002 1 duration in years
003 1 Survival 0=Fail, 1= PH, 2=made
004 1 E Rank ending
005 1 O Rank ending
006 1 Number of skills earned


Note that this should work for CT and MT, tho Assign needs a breakdown list...
 
I agree, XML is the better way. No "counting off" characters, no "fill with blanks to x chars" no "restricted to y chars length". And XML can be formated to the users delight through XSLT etc.

OTOH XML is a pure "text" format so it can be written even without stuff like (J)DOM
 
Agreed that XML is the way to go. Also, since some versions of Traveller DO allow for changing careers, I'd allow for multiple career elements, and include in each career element the number of terms spent in that career.
 
I'll agree that a structured format is superior to the rather flat .sec style format. I'd choose something lighter than XML, namely JSON or even a subset of YAML, but at least XML if not those.
 
Each term/assignment should be collapsed to a short string...
Pos L Desc.
000 1 Career
001 1 Assign (0= basic, 1=basic SD, 2+ adv assigns then SD's)
002 1 duration in years
003 1 Survival 0=Fail, 1= PH, 2=made
004 1 E Rank ending
005 1 O Rank ending
006 1 Number of skills earned


Note that this should work for CT and MT, tho Assign needs a breakdown list...

Thanks, aramis. I would like to capture the output log of my program as is, in a human readable form. It's not really needed anywhere so I don't think I want to over-process this.

Also, since some versions of Traveller DO allow for changing careers, I'd allow for multiple career elements, and include in each career element the number of terms spent in that career.

Thanks, Jeff. I'm mostly concerned with CT right now and this is pretty rare, methinks, but that's a good idea to keep in mind.

As to everyone's overwhelming vote for XML, what do you think about this (excluding the output log)?:

Code:
<character>
  <name>Wolf Blitzer</name>
  <creation_date>5/6/11</creation_date>
  <modification_date>5/6/11</modification_date>
  <counter_ID>G12</counter_ID>
  <noble_title>Knight</noble_title>
  <UPP>
    <strength>7</strength>
    <dexterity>9</dexterity>
    <endurance>8</endurance>
    <intelligence>5</intelligence>
    <education>8</education>
    <social_standing>11</social_standing>
  </UPP>
  <age>30</age>
  <apparent_age>30</apparent_age>
  <worlds>
    <world type="Home">
      <name>Efate</name>
      <sector>Spinward Marches</sector>
      <subsector>Regina</subsector>
      <hex_number>1705</hex_number>
      <UWP>
        <starport>A</starport>
        <size>6</size>
        <atmosphere>4</atmosphere>
        <hydrographics>6</hydrographics>
        <population>9</population>
        <government>3</government>
        <law_level>0</law_level>
        <tech_level>13</tech_level>
      </UWP>
    </world>
    <world type="Discharge">
      <name>Regina</name>
      <sector>Spinward Marches</sector>
      <subsector>Regina</subsector>
      <hex_number>1910</hex_number>
      <UWP>
        <starport>A</starport>
        <size>7</size>
        <atmosphere>8</atmosphere>
        <hydrographics>8</hydrographics>
        <population>8</population>
        <government>9</government>
        <law_level>9</law_level>
        <tech_level>12</tech_level>
      </UWP>
    </world>
  </worlds>
  <career>
    <service>Army</service>
    <branch>Infantry</branch>
    <terms>3</terms>
    <rank>
      <officer>1</officer>
      <rank_title>Second Lieutenant</rank_title>
      <rank_number>1</rank_number>
      <traveller_rank_number>1</traveller_rank_number>
    </rank>
    <education>
      <academy_grad>0</academy_grad>
      <college_grad>0</college_grad>
      <honors_grad>0</honors_grad>
      <OTC>0</OTC>
    </education>
    <special_assignments>
      <assignment>
        <name>OCS</name>
        <number>1</number>
      </assignment>
      <assignment>
        <name>Protected Forces Training</name>
        <number>1</number>
      </assignment>
    </special_assignments>
    <awards>
      <award>
        <name>Combat Service Ribbon</name>
        <number>2</number>
      </award>
      <award>
        <name>Command Ribbon</name>
        <number>5</number>
      </award>
      <award>
        <name>MCUF</name>
        <number>1</number>
      </award>
    </awards>
    <skills>
      <skill>
        <name>Administration</name>
        <level>1</level>
      </skill>
      <skill>
        <name>Advanced Combat Rifle</name>
        <level>1</level>
      </skill>
      <skill>
        <name>Assault Rifle</name>
        <level>1</level>
      </skill>
      <skill>
        <name>Automatic Pistol</name>
        <level>1</level>
      </skill>
      <skill>
        <name>Carbine</name>
        <level>1</level>
      </skill>
      <skill>
        <name>Gauss Rifle</name>
        <level>1</level>
      </skill>
      <skill>
        <name>Grav Vehicle</name>
        <level>1</level>
      </skill>
      <skill>
        <name>Revolver</name>
        <level>1</level>
      </skill>
      <skill>
        <name>Rifle</name>
        <level>1</level>
      </skill>
      <skill>
        <name>Vacc Suit</name>
        <level>4</level>
      </skill>
      <skill>
        <name>Zero-G Combat</name>
        <level>1</level>
      </skill>
    </skills>
    <benefits>
      <retired>0</retired>
      <pension>0</pension>
      <TAS_member>0</TAS_member>
      <psionics_trained>0</psionics_trained>
    </benefits>
  </career>
  <cash>10000</cash>
  <possessions>
    <possession>
      <name>Automatic Pistol</name>
      <number>1</number>
    </possession>
  </possessions>
</character>
 
As given, you've got something that will work, but which is perhaps unnecessarily verbose. A world, for example, might actually be collapsed into a single non-container XML entity with several attributes:

Instead of

Code:
    <world type="Discharge">
      <name>Regina</name>
      <sector>Spinward Marches</sector>
      <subsector>Regina</subsector>
      <hex_number>1910</hex_number>
      <UWP>
        <starport>A</starport>
        <size>7</size>
        <atmosphere>8</atmosphere>
        <hydrographics>8</hydrographics>
        <population>8</population>
        <government>9</government>
        <law_level>9</law_level>
        <tech_level>12</tech_level>
      </UWP>
    </world>
you might consider

Code:
<world type="Discharge" name="Regina" sector="Spinward Marches" subsector="Regina" hex="1910" uwp="A788899C" />
or even replacing the "uwp" attribute with the eight individual attributes.

In general, if an entity can have zero or one occurrences of an attribute, that attribute should be specified as such within the entity. If it can occur more than once, then you have a sub-entity in which it can only occur zero or one times, and the current entity becomes a container entity. An entity that is not a container entity should be a self-closing entity. From your example, <skill>...</skill> should not be a container entity; it can be collapsed into a self-closing entity with the attributes "name" and "level", e.g., <skill name="Mechanical" level=2 /> - but since a character can have multiple <skill.../>s, <skill.../> is definitely an entity, and <skills>...</skills> is a valid container entity.

If you'd like a full analysis and restructuring of your <character>...</character> entity, PM me or email me; I doubt that such an analysis would be of interest to the others reading/following this thread - either because it's too esoteric, or too obvious!
 
Thanks, Jeff!

I haven't used XML before so I appreciate your insights.

If you'd like a full analysis and restructuring of your <character>...</character> entity, PM me or email me; I doubt that such an analysis would be of interest to the others reading/following this thread - either because it's too esoteric, or too obvious!

I'll take you up on that after I have another stab at it.
 
Does any of the PC software use XML?

I'm a big fan of XML and XSTL, we should be working towards a comprehensive DTD or XML Schema.

Probably needs a meta with Traveller version, creation method.
 
The trick is to have a use for the data. I've found that hobby protocols are de facto: if they're used in enough places they BECOME a standard in this context, rather than decreed by a standards body like an industry can.

And of course, the medium (XML here) is nowhere near as important as the hierarchical structure of the data itself. Serialized formats can be translated. A program can read in XML and spit out YAML. But a poor structure has to be lived with.
 
Last edited:
Many thanks to Jeff (FreeTrav) for tons of insightful off-line comments.

Here's what I'm going to use. Attributes as much as possible, "file_info" for housekeeping, "career" to allow more than one "service".

Code:
<?xml version="1.0" encoding="UTF-8"?>
<character_file xmlns:xml="http://www.w3.org/XML/1998/namespace">
  <file_info schema="1" creation_date="5/6/11" modification_date="5/6/11"/>
  <character name="Wolf Blitzer" noble_title="Knight" str="7" dex="9" end="8" int="5" edu="8" soc="B" age="30" apparent_age="30" counter_ID="G12" college_grad="False" college_honors="False" cash="10000" retired="False" pension="False" TAS_member="False" psionics_trained="False">
    <worlds>
      <world world_name="Efate" world_type="Home" sector="Spinward Marches" subsector="Regina" hex_number="1705" UWP="A646930D"/>
      <world world_name="Regina" world_type="Discharge" sector="Spinward Marches" subsector="Regina" hex_number="1910" UWP="A788899C"/>
    </worlds>
    <career>
      <service service_name="Army" branch="Infantry" terms="3" officer="True" rank_title="Second Lieutenant" rank_number="1" traveller_rank_number="1" academy_grad="False" academy_honors="False">
        <assignments>
          <assignment name="OCS" number="1"/>
          <assignment name="Protected Forces Training" number="1"/>
        </assignments>
        <awards>
          <award name="Combat Service Ribbon" number="2"/>
          <award name="Command Ribbon" number="5"/>
          <award name="MCUF" number="1"/>
        </awards>
      </service>
    </career>
    <skills>
      <skill name="Administration" level="1"/>
      <skill name="Advanced Combat Rifle" level="1"/>
      <skill name="Assault Rifle" level="1"/>
      <skill name="Automatic Pistol" level="1"/>
      <skill name="Carbine" level="1"/>
      <skill name="Gauss Rifle" level="1"/>
      <skill name="Grav Vehicle" level="1"/>
      <skill name="Revolver" level="1"/>
      <skill name="Rifle" level="1"/>
      <skill name="Vacc Suit" level="4"/>
      <skill name="Zero-G Combat" level="1"/>
    </skills>
    <possessions>
      <possession name="Automatic Pistol" number="1"/>
    </possessions>
    <creation_log text="Age=18 etc. etc."/>
  </character>
</character_file>
 
The trick is to have a use for the data. I've found that hobby protocols are de facto: if they're used in enough places they BECOME a standard in this context, rather than decreed by a standards body like an industry can.

Quite true. And one of the 'best' ways that they start getting used in enough places is that the first place that uses them is both good enough on its own, and leaves enough room for additional functionality to be easily created "on the fly" by others, that it becomes attractive to work within the constraints and formats of that program - that is, in essence, what Jim Vassilakos accomplished with GALACTIC, and though there have been worthy attempts, so far there really hasn't come to fruition a viable replacement.

And of course, the medium (XML here) is nowhere near as important as the hierarchical structure of the data itself. Serialized formats can be translated. A program can read in XML and spit out YAML. But a poor structure has to be lived with.

And that's the other key - the structure, rather than its expression, needs to be rational and useful in and of itself; extensibility within the defined structure is a very big plus as well.

FWIW, they give courses in this stuff - data structure theory - at the post-baccalaureate level in computer science schools, and more than one computer scientist has made a name for himself by writing books about it.
 
First - nice job on the programs agorski and thanks for sharing!

Now I've never cared for XML (that's putting it mildly - amateur crap IMO - but that is the way with a great many 'standards')...

But, to speak to your design within its constricts:
  • Why use world_name/world_type instead of just name/type like the other element attributes (ditto for service)?
  • 'number' is a bit ambiguous, words like count and quantity would be clearer (i.e., ala skill 'level').
  • Attributes are a lot less wordy (that's relative with a crap format like XML :) ), but they can also be constraining.
On that last, much more critical point - consider:
  • Do you want to support alien races (which only would add to that long list...)?
  • If you do - how about alternate characteristics (other than str, dex...)?
  • What about the status of characteristics (i.e. <stat name="str" type="injured" ...)?
  • What about alternate languages (for character names and worlds)?
  • What about trade codes (not in worlds element attribute list...)?
  • Multiple branches within a service handling would seem better served by separate branch element...
Most of those could be added as child elements, but some would override the attributes or make for a combination attribute and element addressing the same conceptual aspect. Also, the attributes make some of those elements quite long when it comes to 'human' readings...

There are different schools of thought on the use of attributes - though many see them primarily as meta-data for describing the element when such are singularly atomic and not structured information and some die-hards think they should never be used in any other way - but that really boils down to the fundamental flaws of such outlined, so called 'human readable', formats. ;)

Anyway - that was all meant to be constructive (not critical of anything - well, other than XML ;) ) - most importantly, just have fun programming!
 
First - nice job on the programs agorski and thanks for sharing!
You're welcome, and thanks for your comments.

I'm resigned to the fact that this file format thing will never be settled. :)

That's why I put that "schema" attribute at the front; so a program can determine exactly which of the infinite possible formats it is dealing with.
 
Why use world_name/world_type instead of just name/type like the other element attributes (ditto for service)?
Agreed. I've made those changes.

  • Do you want to support alien races (which only would add to that long list...)?
  • If you do - how about alternate characteristics (other than str, dex...)?
  • What about the status of characteristics (i.e. <stat name="str" type="injured" ...)?
  • What about alternate languages (for character names and worlds)?
  • What about trade codes (not in worlds element attribute list...)?
  • Multiple branches within a service handling would seem better served by separate branch element...
My main concern was to provide a structure for everything on the (expanded) MegaTraveller TAS Form 2, so I'm not going to go more crazy than I have already on adding stuff. ;)
Could I recommend using YES and NO for the Booleans, that way they conform to Apples (this is OS X software) Cocoa types.
In Real Studio, converting a boolean to a string yields "True" or "False", so that's why I used that, but since you're using Apple's dev tools and are the only person I know that might actually want to use something like this, I've made that change as well. :)

One other note. If an element like <awards></awards> has no children, Real Studio puts the single tag <awards/> in as a placeholder. This makes it easier to parse the file, since there's guaranteed to be something there. Since the Real Studio XML parser is based on Expat( http://expat.sourceforge.net), I assume this comes from there, although I haven't taken the time to look.
 
Back
Top