Author Topic: [RELEASE] FS-style table parser v1.0  (Read 5317 times)

0 Members and 1 Guest are viewing this topic.

[RELEASE] FS-style table parser v1.0
Greetings, fellow modders

Earlier this year, I started working on a script capable of parsing text files written in the style of Freespace tables. This idea was to have a generic parser that would allow me to read config files for other scripts.

Source code is available here.

How to use it:

Put parse.lua in data/scripts.

In data/tables/init-sct.tbm, under #Conditional Hooks:
Code: [Select]
$On Game Init: [[parse.lua]]

Call the function parseTableFile(filePath, fileName) on a $On Game Init: hook, and store its results in a variable. The resulting data is basically a big multi-dimensional lua table:
Note: the things in yellow can be change to whatever you want.

  • Categories: Begin with #A name, end with #End.
    #Ship Classes is accessed by tableObject['Ship Classes']
  • Entries: Begin with $Name: some name.
    $Name: GTF Ulysses is access by tableObject['Ship Classes']['GTF Ulysses']
  • Attributes: Single line that begins with $attribute name: some value.
    $Hitpoints: 180 is accessed by tableObject['Ship Classes']['GTF Ulysses']['Hitpoints']['value'], which will have a value of 180.
    Note: you can also have an array of values, such as $Hitpoints: 340, 300, 260, 220, 180, which are then access by their index: tableObject['Ship Classes']['GTF Ulysses']['Hitpoints']['value'][0] will return a value of 340.
  • Sub-attributes: Single line that begins with +sub attribute name: some value.
    +Armor: None will be accessed as tableObject['Ship Classes']['GTF Ulysses']['Hitpoints']['sub']['Armor'], and will have a value of "None".
    Note : Sub-attributes can also have an array of values.

 
Since this structure is a bit difficult to manipulate, I recommend splitting that big blob into sub tables or objects or whatever you feel comfortable with. Note that the script doesn't check the type of the parsed data, or whether a required attribute is present or not.

Examples:
 
I currently have 3 different scripts that use this parser for their config data, so here are a few code samples on how to use it. Note: these are code samples, meaning that they are missing several vital components.


mission-wide ship variant
Here we have a fairly simple table, with multiple categories, each entry has a single attribute, "Variant" with an optional sub-attribute, "Wing". The script function takes a category name, then processes each entry in that category.

Table:
Code: [Select]
#12th Vasudan BG

; Hatshepsut class
$Name: Apep
$Variant: Combat

; Typhon class
$Name: Pharaoh
$Variant: Combat Refit

; Sobek class
$Name: Blade
$Variant: Standard
+Wing: 2

#End

#A01.fs2

; Rakshasa class
$Name: Haagenti
$Variant: Strike Cruiser

#End

Script:
Code: [Select]
shipVariantMissionsTable = parseTableFile("data/config/", "ship_variant_missions.tbl")

function setShipVariants(categoryName)
if not (shipVariantMissionsTable[categoryName] == nil) then
for shipName, attributes in pairs(shipVariantMissionsTable[categoryName]) do
local variantName = attributes['Variant']['value']

-- if this is a single ship
if (attributes['Variant']['sub']['Wing'] == nil) then
setVariant(shipName, variantName)
else -- or if this is a wing
local wingSize = attributes['Variant']['sub']['Wing']
for i = 1, i <= wingSize, i = i + 1 do
setVariant(shipName.." "..i, variantName)
end
end

end
else
ba.warning("[shipVariantMissions.lua] Could not find entry "..categoryName)
end
end

auto ssm strikes
Here we a table with a single category. Each entry has two required attributes, "Type" and "Cooldown", one of which accepts either a single value or a list of values, and an optional attribute, "Default Seeking Algorithm". The script sample splits the parsed data into a bunch of one-dimensional tables to make them easier to use afterwards.

Table:
Code: [Select]
#Automated Strikes

$Name: rr-barrage ; required
$Type: Shivan SSM Barrage ; required, must match ssm.tbl entry
$Cooldown: 22 ; required
$Default Seeking Algorithm: round-robin ; optional, defaults to list

$Name: moloch-std
$Type: Shivan SSM Strike
$Cooldown: 24, 20, 17, 15, 13

$Name: moloch-std-insane
$Type: Shivan SSM Strike
$Cooldown: 13

$Name: moloch-std-hard
$Type: Shivan SSM Strike
$Cooldown: 15

$Name: moloch-std-medium
$Type: Shivan SSM Strike
$Cooldown: 17

$Name: moloch-std-easy
$Type: Shivan SSM Strike
$Cooldown: 20

$Name: moloch-std-very-easy
$Type: Shivan SSM Strike
$Cooldown: 24

#End

Script:
Code: [Select]
auto_ssm_table = parseTableFile(auto_ssm_filePath, auto_ssm_fileName)
dPrint_autoSSM(getTableObjectAsString(auto_ssm_table))

local id = 0
for name, attributes in pairs(auto_ssm_table['Automated Strikes']) do
-- record the strike's id
strike_info_id[id] = name
dPrint_autoSSM("Name="..name.."\n")

-- for each attribute
for attribute, prefix in pairs(attributes) do
value = prefix['value']
if not (type(value) == 'table') then
dPrint_autoSSM("attribute="..attribute.."; value="..value.."\n")
else
local str = ""
for index, val in pairs(value) do
str = str..val.." "
end
dPrint_autoSSM(str.."\n")
end

-- store this attribute in the relevant array
if (attribute == "Type") then
strike_info_type[name] = value
elseif (attribute == "Cooldown") then
strike_info_cooldown[name] = value
elseif (attribute == "Default Seeking Algorithm") then
strike_info_seeker_algo[name] = value
else
ba.warning("[autoSSM.lua] Unrecognised attribute "..attribute.."\n");
end
end

-- increment id count
id = id + 1
end


I am open to suggestions, remarks, questions regarding both this script and the way it is presented in this thread (in other words: I'm not sure if I'm explaining things properly here).
« Last Edit: November 10, 2015, 02:42:48 pm by X3N0-Life-Form »

 

Offline mjn.mixael

  • Cutscene Master
  • 212
  • Chopped liver
    • Steam
    • Twitter
Re: [WiP - Beta] FS-style table parser
I'm curious what you're using this for.
Cutscene Upgrade Project - Mainhall Remakes - Between the Ashes
Youtube Channel - P3D Model Box
Between the Ashes is looking for committed testers, PM me for details.
Freespace Upgrade Project See what's happening.

 
Re: [WiP - Beta] FS-style table parser
I'm planning on using it for two things right now: an automated SSM strike framework that's still in the works, and for the ship variant script I released earlier this year.

I figured that since I would have at least two data files I need to parse, and that the existing parsing logic and format of the ship variant thing was crap, I might as well rewrite a generic parser, standardize my script data a bit and make it easier to read and use for FSO modders. That way, I could re-use the parsing logic for whatever I want in the future.

 

Offline mjn.mixael

  • Cutscene Master
  • 212
  • Chopped liver
    • Steam
    • Twitter
Re: [WiP - Beta] FS-style table parser
Neat. Axem should take note of this for his scripts like System Viewer and Journal... (Yeah, Axem, I said it again. I hate your JSON tables. :p )
Cutscene Upgrade Project - Mainhall Remakes - Between the Ashes
Youtube Channel - P3D Model Box
Between the Ashes is looking for committed testers, PM me for details.
Freespace Upgrade Project See what's happening.

 

Offline Axem

  • 211
Re: [WiP - Beta] FS-style table parser
Yeah, it would be simpler for people to edit but if I did make a switch over, I'd have to ask for a way to put data into numerical arrays real easy.

For instance defining the color of something would be easier to go

$Color: 128,128,128,192

rather than

$Color:
+R: 128
+G: 128
+B: 128
+A: 192

So if there where comma delimiting allows entries to go into a numerical based table, that would be so neat.

 
Re: [WiP - Beta] FS-style table parser
I'll add that to the TODO list then.

 
Re: [WiP - Beta] FS-style table parser
:bump:
Updated the script so that it stuffs comma delimited values into tables.

 

Offline Axem

  • 211
Re: [WiP - Beta] FS-style table parser
Okay, I have a few questions now on how it works with regards to sub-attributes.

So you have this...
Code: [Select]
$Attribute2: attribute 2 value
+sub attribute: sub value

which is supposed to generate this...

Code: [Select]
tab['entry name']['Attribute2'] = attribute 2 value
tab['entry name']['Attribute2']['sub']['sub attribute'] = sub value

Where does that 'sub' come from? Is that something the script generates?

And I'd like to be able to do this...
Code: [Select]
$AI:
  +MinCloak: 50
  +ActionTimeout: 10

Where it would generate...

Code: [Select]
tab['entry name']['AI'] = table (object only)
tab['entry name']['AI']['MinCloak'] = 50
tab['entry name']['AI']['ActionTimeout'] = 10

Possible maybe?

 
Re: [WiP - Beta] FS-style table parser
Ugh, looks like I need to rethink my attribute/sub attribute handling a tiny bit. I don't have time to do that this week (or probably even next week), but the idea I have right now would be to have something like this:

Code: [Select]
$Attribute name: some value     ==>    table['entry name']['Attribute name']['value']       = some value
  +sub1: other value            ==>    table['entry name']['Attribute name']['sub']['sub1'] = other value
  +sub2: yet another value      ==>    table['entry name']['Attribute name']['sub']['sub2'] = yet another value

 
Re: [WiP - Beta] FS-style table parser
Alright, since I'm obviously not going to have much spare time to work on FSO modding stuff, I've decided to take 10-15 minutes of my time to try and cook up something.
The modified script basically work as described in the post above: $Attribute: value results in ['Attribute']['value'] = value.

Note that it's received rather extensive testing (read: "launching the game to see if something chokes up on parsing"), so I'm still flagging this as beta for now.

EDIT - yup, it seems to be pretty broken right now

EDIT 2 - Should have been fixorized now. I'm probably going to review the category system before pushing out a 1.0.
« Last Edit: April 02, 2015, 05:01:55 am by X3N0-Life-Form »

 
Re: [RELEASE] FS-style table parser v1.0
Bumping for 1.0 release, see first post.

  
Re: [RELEASE] FS-style table parser v1.0
If this had been available 4 years ago I probably would have used it for my ship save/load script instead of that mess I ended up coding myself.
When I think about it adding reversed read functions as write functions would be enough. The script already creates one large table for each ship anyway.
Here goes scripting and copy paste coding
Freespace RTS Mod
Checkpoint/Shipsaveload script