Coding Concepts
-
Hi, I’m pretty new at modding, managed my first mod today to fix my display to use high resolution, thanks to a tutorial of course
Coming from a HTML/CSS/PHP background there are coding practices to adhere to in general when coding, now I realise ini coding isn’t anywhere near to the complexity of PHP and the like, I wish to know of any coding methodologies or ways to speed up coding.
The XML coding available within FLMM seems pretty good, and as far as I can tell from what I’ve been able to discern so far, the INI files and the way they relate is very dependency driven and relational with the use of id’s or nicknames.
As one file leads to another and then to another from start to end, you could very well include all the relevant sections to be modified in 1 script to insert say a ship with full weaponry, shielding, engines as a “package”.
Maybe I’m wrong on that, I’m just thinking logically I’m unsure how the engine would react to that, which is why I’m here asking for clues
I’m basically looking for any method of templating or re-using code so that I can work as efficiently and as speedy as possible without literally hand coding everything.
Cut and Paste isn’t going to cut it I fear
Thanks!
-
While yes, INI files are very relational (certain files and blocks like AIs support inherit statements, for instance), there’s a certain limit due to how Freelancer first loads the files. You might benefit from looking into EXE\Freelancer.ini, which is the core file which loads everything else. You’ll notice this is where the game knows what files to load and in which order. That also means I doubt you can cross-mix things that much because it may not, for example, pick up a weapon definition in shiparch.ini.
I’m afraid there are not that many ways to avoid hand-coding everything. I don’t want to sound like I’m doing a shameless plug ( ), but FLDev (which you can get on the Forge) allows you to create INI code from spreadsheets by exporting these spreadsheets as CSV files and then using a template INI file to plug the values in. I’m afraid there isn’t much documentation, but if you are interested and need help I could provide a simple example.
-
FriendlyFire wrote:
I’m afraid there are not that many ways to avoid hand-coding everything. I don’t want to sound like I’m doing a shameless plug ( ), but FLDev (which you can get on the Forge) allows you to create INI code from spreadsheets by exporting these spreadsheets as CSV files and then using a template INI file to plug the values in. I’m afraid there isn’t much documentation, but if you are interested and need help I could provide a simple example.
If I understand that correctly, you are saying FLDev can read a CSV exported from say, Microsoft Excel (or Google Docs) to plug values into a template which can be outputted enmasse?
Am I getting that right? lol.
-
Yeppers, precisely.
For instance, it takes a spreadsheet such as this, with this piece of code as a template:
{{weapon_equip.ini::FILE}} [Gun] nickname = {{Faction&&NOSPACE&&UPPER}}_GUN_{{Faction::COUNTERCOL}} ids_name = {{Name::NAME}} ids_info = {{"<rdl><push><tra data="1" mask="1" def="-2"><just loc="center"><text>"%+%Infocard 1%+%"</text><para><para><tra data="0" mask="1" def="-1"><just loc="left"><text>"%+%Infocard 2%+%"</text><para><para></para></para></just></tra></para></para></just></tra></push></rdl>"::INFO}} DA_archetype = {{Archetype}} material_library = {{Material}} HP_child = HPConnect hit_pts = {{Hit Points}} explosion_resistance = 1.000000 debris_type = debris_normal parent_impulse = 20 child_impulse = 80 volume = 0.000000 mass = {{Mass}} hp_gun_type = hp_gun_special_{{Class::TEXT}} damage_per_fire = 0 power_usage = {{Power Usage}} refire_delay = {{Refire Delay}} muzzle_velocity = {{Velocity}} use_animation = Sc_fire toughness = 1.000000 flash_particle_name = ;;;;;;;;;;;;;;; flash_radius = 10 light_anim = l_gun01_flash projectile_archetype = {{Faction&&NOSPACE&&UPPER}}_GUN_{{Faction::COUNTERCOL}}_AMMO separation_explosion = sever_debris auto_turret = true turn_rate = 90 lootable = true LODranges = 0, 20, 60, 100 [Munition] nickname = {{Faction&&NOSPACE&&UPPER}}_GUN_{{Faction::COUNTERCOL}}_AMMO hp_type = hp_gun requires_ammo = false hit_pts = 2 hull_damage = {{Hull Damage}} energy_damage = {{Shield Damage}} weapon_type = {{Type}} one_shot_sound = {{Sound}} munition_hit_effect = ;;;;;;;;;;;;;;; const_effect = {{Faction&&NOSPACE&&UPPER}}_GUN_{{Faction::COUNTERCOL}}__PROJ lifetime = {{Lifetime}} force_gun_ori = false mass = 1 volume = 0.000100 {{weapon_good.ini::FILE}} [Good] nickname = {{Faction&&NOSPACE&&UPPER}}_GUN_{{Faction::COUNTERCOL}} equipment = {{Faction&&NOSPACE&&UPPER}}_GUN_{{Faction::COUNTERCOL}} category = equipment price = {{Price}} item_icon = ..\DATA\equipment\models\commodities\nn_icons\EQUIPICON_gun.3db combinable = false ids_name = {{Name::NAME}} ids_info = {{"<rdl><push><tra data="1" mask="1" def="-2"><just loc="center"><text>"%+%Infocard 1%+%"</text><para><para><tra data="0" mask="1" def="-1"><just loc="left"><text>"%+%Infocard 2%+%"</text><para><para></para></para></just></tra></para></para></just></tra></push></rdl>"::INFO}} shop_archetype = {{Archetype}} material_library = {{Material}} {{WT_effects.ini::FILE}} [Effect] nickname = {{Faction&&NOSPACE&&UPPER}}_GUN_{{Faction::COUNTERCOL}}_PROJ effect_type = EFT_WEAPON_PROJ vis_effect = vis_beam =
And it gives out fully working, albeit invisible (due to lacking proper effects, I just put that in manually), weapons. It also plugs values in the DLLs with type NAME or INFO.
-
Thats awesome, I’m going to download that bad boy right now
The template is intriguing.
In theory I could have a development cycle such as this:
Create a template that encompasses the majority of the dependencies like the weapon, sound, effects (if possible) and then re-use it in the following cycle like this:
Spreadsheet (with all the values) > FLDev (to put the values into the template) > Output (the ready scripts to drop into a FLMM mod folder)
Is that how it would work?
-
You should be able to do what you’re wishing with FLDev, yes.
-
In the template above does it have all the plugs for use with the template? As you said there was no documentation with the download, and I’m sure you have different settings with different plugs.
Like you have {{Faction&&NOSPACE&&UPPER}}
I’m guessing those are different attributes of faction, guessing upper means any text you put there would be outputted in uppercase, not sure about the nospace, I know nicknames tend to take advantage of underscores, another guess at thats what it might be.
I noticed a 1 line per file option as well, which if I’m thinking about it right would do one line of the CSV per outputted file, allowing me to generate many complete weapon scripts if I do the template with the right logic.
Now all I need is the templating that would include all the dependencies within single script, you wouldn’t happen to know if anything like that has been done before?
Not asking anyone to do it for me by any means, but I’m sure someone has coded some form of standardised coding either in INI format or XML script format in the years this game has been modded.
If not no big deal, I’ll do it myself, I just thought why re-invent the wheel if someone has already made it.
Thanks
-
Actually, you’d be surprised by how little the CSV Parser is/has been used. I know of two, perhaps three people who made use of it, myself included.
As for the settings, there are only a handful: UPPER/LOWER (you guessed their function right), NOSPACE (transforms spaces in underline characters, as you guessed) and IF/IFCASE. These last two are rather particular, since they allow you to set conditions to the value being output. I’d call them “advanced templating”
IF and IFCASE behave the same way, except IFCASE will also match case when comparing strings (IE text) while IF will be case insensitive. The syntax is as follows:
&&IF(TARGET, COMPARISON"VALUE")
Target is any column (it only matches the value of the column at the row currently being parsed) in quotes (“”); you can use this to refer to the column currently being parsed WITHOUT quotes. Comparison is any of the standard boolean operators (<, >, !=. ==, <=, >=, respectively lesser than, greater than, not equal to, equal to, lesser or equal to, greater or equal to). Value is the value to compare it to (numbers are automatically parsed).
Example:
&&IF(__this__, !="") ```This will check whether the current column is not empty. If it is, whatever was supposed to be output will not. There is no "else" condition; just put another IF with the reversed condition (IE here it could be if it is empty). There are also a few odd value types. If no type is described, the default is TEXT. NAME is for "ids_name" values, INFO for "ids_info" values, FILE is when you want to specify file names and/or use multiple files from the same template. COUNTER and COUNTERCOL are, again, "advanced templating". COUNTER is what it says, a counter. It'll get incremented by one whenever it's parsed. That means if you have the counter's ID once in your template, it'll get incremented by one for every line in your CSV. COUNTERCOL is slightly different, in that it assigns a different counter to the contents of the text. This can have multiple uses; I have it for loadouts and weapons so that it'll number the weapons for each faction from 1 to X (IE LIBERTY_NAVY_01, LIBERTY_NAVY_02, etc.). For some odd reason, the counter-specific parameter COUNTERLEN (&&COUNTERLEN(VALUE)), which lets you pad numeric values (IE 001 instead of 1), is only defined for COUNTERCOL, so it won't work with just COUNTER. There are also a few more interesting syntax elements. You probably noticed you can combine multiple columns in the same tag, even using text in-between, thanks to %+%, which is effectively the concatenation operator. Remember to always put plain text in between double quotes ("text"). In specific cases (particularly when using IFs that completely determine whether a line gets shown or not), you may also need %%NL%%, which inserts a new line character in the file and can be placed directly in the text ("text%%NL%%"). I'll end this with a nice proof-of-concept illustrating what some thinking can let you do: a full markets file out of a spreadsheet. The XLS file that is the source for the template is included in this post. Use the following template to parse it:
{{“%%NL%%[BaseGood]%%NL%%base = “::TEXT&&IF(“Base”, !=””)}}{{Base::TEXT&&IF(“Base”, !=“”)}}{{“MarketGood = “::TEXT&&IF(“Base”, ==””)}}{{Good Nickname::TEXT&&IF(“Base”, ==“”)}}{{“, “::TEXT&&IF(“Base”, ==””)}}{{Level::TEXT&&IF(“Base”, ==“”)}}{{“, “::TEXT&&IF(“Base”, ==””)}}{{Reputation::TEXT&&IF(“Base”, ==“”)}}{{“, 50, 50, 0, “::TEXT&&IF(“Type”, ==“AMMO”)}}{{”, 10, 10, 0, “::TEXT&&IF(“Type”, ==“EQUIPMENT”)}}{{”, 100, 100, 0, “::TEXT&&IF(“Type”, ==“REGEN”)}}{{”, 150, 500, 0, “::TEXT&&IF(“Type”, ==“COMMODITY”)}}{{”, 0, 0, 1, “::TEXT&&IF(“Type”, ==“COMMODITY_NOTSOLD”)}}{{”, 0, 0, 1, 1, “::TEXT&&IF(“Type”, ==“SHIP_NOTSOLD”)}}{{”, 1, 1, 0, 1, “::TEXT&&IF(“Type”, ==“SHIP”)}}{{Price Multiplier::TEXT&&IF(“Base”, ==””)}}
Hope this helps and… Err, I've just made that reference I was speaking about? :D
-
Awesome, I should be able to pick this up, but I would suggest trying to create a refence or guide to this, even if it is only basic, it might suggest the reason why not many have used it. With the proper documentation I think this program would go quite far.
Not to mention the tools included with it.
But, a lot of the statements for the use I will make out of it perhaps won’t require a lot of conditions, for example it would take longer to type nospace than it would to simply type a _
If you get my meaning …
But I do understand the power of it nonetheless