Jump to content

[Tutorial] What is LABEL, why you should create it and how to do it properly


Recommended Posts

tl;dr:
Add "LabelType = GloballyUnique" line into mod metadata file thus indicating that the "label usage context is for Project Infinity". Then for each mod component add WeiDU LABEL keyword by combining modder prefix or author name, the mod display name (read warring!) and the component name. Then never even change it. You will help other modders, people who create so-called 'mod compilations' and players who do use mod managers.

Introduction:

Project Infinity feature status: Implemented

You might wonder, what is LABEL? Why I should add LABEL's to my mods?

LABEL is a better DESIGNATED. It allows assigning a unique textual identifier for a given mod component. And use this identifier to handle internal dependencies between the components of the same mod and external dependencies of the mods from different authors. By using globally unique LABEL's locally, you are saving yourself the trouble of fixing dependences after DESIGNATED changes. By using external mods LABEL's for defining dependencies, you avoid 'locking' DESIGNATED numbers changes of those mods so the author can freely change them when he needs to. Finally, those are extra advantages that mod ecosystem will get when LABEL's treated as globally unique instead of being bound to tp2 name:

  • label can help you to properly handle mod component dependencies of the other mods, other modders could use labels from your mods the same way
  • so-called mod compilations will not become obsolete after changing the DESIGNATED numbers or even donating components to other mods
  • installation order guides will not become obsolete after changing DESIGNATED numbers or even donating components to other mods
  • mod conflicts list will not become obsolete after changing the DESIGNATED numbers or even donating components to other mods
  • players can safely keep the list of selected mod components and use it without this kind of nightmare

The goal is to create LABEL that is globally unique across ALL existing and future mods. It's easy and straight forward when you keep a simple general rule:

Modder'sPrefixOrAuthorName-ModDisplayName-ComponentName

WARNING:
It seems natural to use the so-called tp2 basename as part of the LABEL. Of course, you can do it, but you should be aware that the whole LABEL is locked and remains the same forever even if the component (its code) is moved to another tp2 file/different mod, no matter if it's your mod or someone else. You should absolutely leave it unchanged. This is a very important distinction that is not obvious at first glance. If a mod MyTweaks.tp2 contains a component with the label 'xx-MyTweaks-RemoveDragons' and later is donated to cdtweaks.tp2 mod/file, the LABEL STAYS THE SAME with modder prefix and tp2 name!

How to enable:

  • Step 1: Add the Add "LabelType = GloballyUnique" line into the mod metadata file, thus indicating that the "label usage context is for Project Infinity".
  • Step 2: For each component of your mods, create labels according to the below requirements and best practices.

Label requirements:

  • no spaces
  • no special characters, except the modder prefix
  • no Unicode characters
  • minimum 4 characters
  • cannot be the digits-only, using digits-only (LABEL '100', '1000' etc) for LABELS in fact removes its advantages
  • cannot be a combination of 'ID:DESIGNATED' as actual LABEL (LABEL 'MyMod:0' etc)
  • cannot be ONLY tp2 basename, the main component of your mod could be easily constructed by adding '-Main' suffix

Label best practices:

  • kebab-case, snake_case, PascalCase
  • it's best to start with the modder prefix: xx-MyMod-Main
  • try to avoid using well-known shortcuts of the mods
  • from the most significant to the least significant:
    "xx-MyMod-Portrait-Brath" / xx-MyMod-Portrait-Wallo" instead of "xx-MyMod-Wallo-Portrait" / "xx-MyMod-Brath-Portrait"
  • avoid using the component category in the label name
    The component category (equivalent to the WeiDU GROUP feature) is a virtual concept and depends on individual preferences. After transferring components to a different mod or category, the label will have a mismatched and confusing name so it may mistakenly prompt people to change this part of the LABEL, but it should never be done.

 Example:

BEGIN "MyMod" LABEL "MyMod-Main"

Wrong label names:

  • "a"  -  not enough characters
  • "Spells" - too general name
  • "Main" - too general name, add mod display name
  • "MyMod" when tp2 is MyMod.tp2/Setup-MyMod.tp2, please add '-Main' suffix

Proper label names:

Labels of the main component of Ascension mod by DavidW:

//////////////////////////////////////////////////////////////////////
// Ascension main component: rewritten Chapter 10                   //
//////////////////////////////////////////////////////////////////////

BEGIN @104001 DESIGNATED 0 GROUP @101000
LABEL Ascension-RewrittenFinalChapterOfToB

Labels of the main component of Transitions by Lauriel:

////////////////////////////////////////////////////////////////////////////////////
// MAIN COMPONENT FOR ALL GAMES: ALLOW CONTINUED PLAY AFTER DEFEAT OF BOSS ENEMY  //
// OPEN THE PALACE AND MODIFY DUKE BELT TO ALLOW FOR BG1 CONTINUATION             //
// OPEN SULDANESSELLAR AND MODIFY QUEEN ESSEMINE TO ALLOW FOR BG2 CONTINUATION    //
// HANDLES PC'S ROOM IN THE PALACE AND IMOEN'S TRAINING IN MAGIC IN EET           //
////////////////////////////////////////////////////////////////////////////////////
BEGIN @2    // MOD 0
LABEL "#L-TRANSITIONS-MAIN"

 

Edited by AL|EN
Typos
Link to comment

I was going to post and say this is a bit over my head, but I just came up with a real-world instance of what I don't like about this.

I am working on a 5E ruleset conversion thingy. Right now it has one function covering each spellcasting class. There is a single component in the .tp2 file, which looks like this:

BEGIN ~Convert Everyone to 5E Spellcasting Rules?~
DESIGNATED 100

LAF 5E_mages END
LAF 5E_bards END
LAF 5E_clerics END
LAF 5E_druids END
LAF 5E_paladins END
LAF 5E_rangers END

Now, as I iron out the kinks and make it possible for parts of this system to coexists with or without other parts of the system, I would like to add more optional components:

BEGIN ~Convert Mages to 5E Spellcasting Rules~
DESIGNATED 200

LAF 5E_mages END

BEGIN ~Convert Bards to 5E Spellcasting Rules~
DESIGNATED 300

LAF 5E_bards END

BEGIN ~Convert Clerics to 5E Spellcasting Rules~
DESIGNATED 400

LAF 5E_clerics END

BEGIN ~Convert Druids to 5E Spellcasting Rules~
DESIGNATED 500

LAF 5E_druids END

BEGIN ~Convert Paladins to 5E Spellcasting Rules~
DESIGNATED 600

LAF 5E_paladins END

BEGIN ~Convert Rangers to 5E Spellcasting Rules~
DESIGNATED 700

LAF 5E_rangers END

Now, I want to make Faiths & Powers compatible with this. So I want to add a check: are clerics in this game using a 5E spellcasting system? That can be implemented by either component 100, or component 400. If I could add a single LABEL to each class-specific component, and add all six LABELs to component 100, that would be helpful. As it is, that will not work. I have to have a different LABEL for clerics being modified by component 100 vs. clerics being modified by component 400.

Now, I get that LABEL will be reliable and static even if the DESIGNATED numbers change. And that's an advantage. But, it is the only advantage, and LABEL doesn't let me omit DESIGNATED numbers - I still need those to control component install order. So LABEL is extra work, with only the slightest bit of extra utility.

And I keep coming back to this: marker files seem like they accomplish everything LABEL does, and they let me simplify the compatibility check. So... why would I not use marker files again?  Clutter?  My override directory has over 100,000 mod files in it... a few dozen marker files that ensure cross-mod compatibility does not really add meaningful clutter.

Sorry to re-hash that, I know it's been discussed before. I'm just still not sold, I guess.

As for how to name LABELs: seems pretty clear to me: Weidu cannot and should not enforce particular unique naming practices. For any modder who cares about what they are making, using your modding prefix in your LABELs is an obvious way to guarantee it won't conflict with any others. Some modders may not do that - some jerk may add "unnerfed_spell_tables" to his thrice-redundant tweak mod - but if you use your modding prefix in your tweak mod, you will protect yourself from such jerks. (And needless to say, if any asshole uses someone else's modder prefix in their LABELs, then their shitty mod will be banished to the hinterlands of Baldur's Extended Butt.

Link to comment

@subtledoctor

I don't mind mentioning 'marker files' or any other thing which sparks discussion. Having hundreds of extra files inside override is not something that I would rise against using marker files. If you are focusing on this use-case, it seems valid.

That being said, you emphasize over marker files because you limit the usage context only to the simplest possible feature, that is, a detection if some component was installed into the game and the code should account for that.

Marker files have no semantic meaning unless you explicitly define them via code and arbitrary textual description. It's like checking if the game is BG2EE by detecting the existence of hexxat.cre. Sure, weidu allows you for doing that and you won't be the first modder who is doing it. Weidu also has a standard function which you can use for the same purpose. And when you take look at recently updated mods, for eg: at BG1NPC changelog, you will quickly notice that there was a shift from FILE_EXIT into GAME_IS in order to standardize code.

I don't understand how you can claim that the only advantage of LABEL is being more reliable and that marker files can accomplish everything LABEL does. I have literally written the advantages in the first post. LABEL is so much more, you need to think outside of the weidu box to see it:

  • Can marker files be used to create a curated mod list aka mod compilations? - No.
  • Can marker files be used to create curated install order lists? - No.
  • Can marker files be used to provide a reliable way to save user component selections for mod managers? - No.
  • Does the logic behind marker files could be somehow 'extracted', logically interpret, and present to the user as 'mod dependencies or conflicts' before installation begins? - No.
    (it can definitely be done with upcoming tp3, it won't be possible with marker files logic)

So let me give you an example of what globally unique LABEL can do.

 The mod compilations are transformed from this:

Ascension:0:Rewritten Final Chapter of Throne of Bhaal`
transitions:0:Main component: Allow continued play after Sarevok and/or Irenicus is defeated
...

to this: (there are no more tp2 filenames and designated numbers!)

Ascension-RewrittenFinalChapterOfToB ; Ascension - Rewritten Final Chapter of Throne of Bhaal
#L-TRANSITIONS-MAIN ; Transitions - Allow continued play after Sarevok and/or Irenicus is defeated
...

The users can finally reliably save mod choices like this:

Ascension-RewrittenFinalChapterOfToB
#L-TRANSITIONS-MAIN
...

There is indeed some extra work and brainpower associated with adding LABEL and using it for internal and external mod dependencies.

But let's assume for the moment that someone has to take look at your mod to see "how things are done" and coded several logic conditions by using marker files. Then he needs to create dependencies for mods which doesn't have marker files. So he learns how to use REQUIRE_COMPONENT, FORBBIT_COMPONENT with DESIGNATED numbers. The DESIGNATED numbers were changed, things break.

Then he discovers usage of LABEL so he re-code external dependencies. Later, he wants to provide the above extra features for his mod. He needs to create and add LABEL to every component. But he could be done this in the first place and use LABELS for internal dependences. It would also teach him how to create dependencies for all external mods since they either use DESIGNATED or already have LABEL. This appears to me as more extra work than starting with LABEL's in the first place.

Did I do my homework and invented something which doesn't use LABEL?
Yep. It requires using external website/command-line tool to generate semi-random numbers like 01EY951MQSCCJB4RXSBE6MDE7D for every mod component. The only advantage of this version of global ID is that it's a no-brainier solution: you generate ID's, paste into tp2 and you are done. One problem, as you mentioned was the 'require to use extra website/tool'. The second problem was: it could only be used for the mod manager, without any kind of benefits for WeiDU. Having to choose between PI-only solution and LABEL, I chose something which can be used by both worlds. So I DO account for 'extra work'.

I agree that the syntax of REQUIRE_PREDICATE MOD_IS_INSTALLED ID_OF_LABEL is awful. I wish that REQUIRE_COMPONENT, FORBBIT_COMPONENT could use LABEL or at least a variable. If you want to have simplified syntax, requests for WeiDU were created, add your vote to them.
 

Edited by AL|EN
Link to comment

All I can do for this topic is wave pompoms and cheer on Al|en and his impressive project.  Labels rule! Team unique label will crush the marker file opposition!  <waves pompoms>  Personally I hate marker files, to be honest.  It's messy.  I hate mod executable and debug files in my game main directory.  So messy!  But there's probably nothing that I can do about that.  And that's a rabbit hole that doesn't need to be followed for this topic (although PI could help make that go away ... hint hint).  Anyway, I'll continue to be on the sidelines waving pompoms and cheering on this wonderful idea.

Link to comment

@subtledoctor

After reviewing your use-case again and comparing it to some former cases (where the main mod component was spitted into several) and other examples of the 'component reorganization', I conclude that there is a little bit more to the story. Later, I will cover this in a separate topic with more examples but for now, I hope that we can continue this discussion in good faith.

I understand that the mod is in the early stage of development so the work and focus is putted elsewhere than component system. The weidu installation routine itself encounters modders to start with one big component at the beginning. Later, comes the 'let's offer more choices" thought. But it is really a meaningfull choice?

The point I would like to make is that if you are spiting the main component into several smaller ones, so all content of the big one main component is covered by them, there is no point in keeping the main component anymore. It offers nothing new for the player, no new content etc. When the player will use your mod, he will be presented with 6 choices, choose what he wants, mod manager will save his choices (hopefully!) and he could then even use the same selection for other games. Why keeping it only to introduce more complexity into the mod itself, which then you have to deal with later? The less complex the component system would be the less work you will spend on it.

Anyway, this is something which I thought.

Link to comment
31 minutes ago, AL|EN said:

The point I would like to make is that if you are spiting the main component into several smaller ones, so all content of the big one main component is covered by them, there is no point in keeping the main component anymore. It offers nothing new for the player, no new content etc.

Agree to disagree. This is how Refinements v4 is structured right now.  The biggest, uh, refinement I made to Refinements was to allow HLAs to be installed on a class-by class basis.  The install procedure looks like this:

Install all HLAs? [y] or [n]

If [n]:

Install Fighter HLAs? [y] or [n]
Install Paladin HLAs? [y] or [n]
Install Ranger HLAs? [y] or [n]
Install Cleric HLAs? [y] or [n]
Install Druid HLAs? [y] or [n]
Install Wizard HLAs? [y] or [n]
Install Bard HLAs? [y] or [n]
Install Thief HLAs? [y] or [n]

The players who just want all the Refinements HLAs have a procedure that is just as easy as it was under v3.31: press 'y' once and they are done. But the players who want more control can press 'n' and then they get several options.

This is one of the benefits of immutability and encapsulation: the changes made in a mod need not be tied to this or that mod component, but can be installed by several components in combination with other changes or settings. The Refinements thing is repeated in various instances across my mods: e.g. the SoB total proficiency overhaul auto-installs proficiency category changes, but those can also be installed independently; the MnG revised archery system auto-installs the Marksman kit (a fighter-class Archer) and the Slinger kit (a halfling F/T Archer), but those can also be installed independently.

Another application is Tome & Blood's "Innate Spell Sequencers:" there are four options presented as subcomponents; each subcomponent sets a single variable to a different value and then runs the same function. There are minor differences in application, like do you learn Sequencer abilities automatically or do you learn them from scrolls. But in all four options the result is the same, Sequencer spells live in the innate abilities bar and behave a certain way. If I want to check in another whether TnB has moved Sequencer spells to the innate abilities bar, I can either code a clunky check for four different-but-similar LABELS, or I can check for a single marker file. Me, I'll choose the latter option any day of the week. I don't want to check which component was installed; I want to check whether that function was run.

Another thing: I have replicated TnB's "Ability-Based Bonus Spells" in SoB, a completely different mod. The components are completely identical to each other, not a single different character in the code; it is only in two different places for the sake of players' install order convenience. I cannot use LABEL for compatibility checks to see whether that code is installed, but I can use a marker file.

I could go on and on. This is not to say that LABEL isn't valuable - you've convinced me of that. But the value seems to be focused on mod managers like BWS/PI, not on compatibility checks for other mods.  One is not a substitute for the other... if anything, with LABELs and marker files and proper immutability/encapsulation, we could do away with DESIGNATED. But, I'll keep using that anyway for the sake of full component-order control.  (Not to mention, it is already in all my mods, so removing it would be more work than keeping it. But anyone starting to mod now, using LABEL and marker files and encapsulation, could omit DESIGNATED.)

Edited by subtledoctor
Link to comment

@subtledoctor 

I think you misunderstood me. All examples except the "Refinements" are not falling into above: every component or combination of them has different outcome.

For "Refinements", the HLA components can have only two outcomes: install all HLA's or only some HLA's:

  1. The 'all HLA's outcome" is achievable by selecting 8 HLA's components
  2. The 'some HLA's outcome" is achievable by the same HLA's components but not all of them
  3. Yet, there is a third choice to have 'all HLA's outcome" by selecting an extra component <- this will give the player the same outcome as 1 so it's redundant

But ye, while mod manager will present those choices at once, weidu is offering components selection as one-by-one so I guess it's yet another area for it's improvement. I'm nitpicking, let's leave it for now. I'm grateful that you find LABEL's being useful.

This one is interesting, please explain:

2 hours ago, subtledoctor said:

If I want to check in another whether TnB has moved Sequencer spells to the innate abilities bar, I can either code a clunky check for four different-but-similar LABELS, or I can check for a single marker file. Me, I'll choose the latter option any day of the week. I don't want to check which component was installed; I want to check whether that function was run.

Do you use the "file is detected" as "REQUIRE/FORBID" component or rather to "skip some part of the code" during the actual installation when all 'requirement/forbid conditions' were previously evaluated? So the hypothetically selected component will still be present inside weidu.log but because of 'FILE_IS' condition, the actual code was skipped entirely and it's like dummy component?

To put it another way, if there will be ever a situation when the player chooses a particular component combination, then one or more components will be completely skipped because of 'file check" and it won't be added to weidu.log?

Edited by AL|EN
typos
Link to comment

As of today, modders can implement steps from first post to allow players to save their mod selections. The ongoing discussion about labels being globally unique as default has no effect on this feature, as long as both steps from first post are implemented.

Demonstration for the upcoming Ascension 2.0.18:

 


hdl26ry4vpyj.gif
 

Edited by AL|EN
Link to comment

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...