Jump to content
  • entries
    17
  • comments
    41
  • views
    12,063

Some Modding Standards


darkconsole

930 views

Scripting Standards

Or, How Not To Be A Complete Modding Douchebag.

 

Updated 2015.02.18 at 3pm Texas Time.

  • Added BSA Packing.
  • Added Self Keyword.

So... lets talk about modding standards. Over the past year I've invented my own little system for organising my scripts and CreationKit objects that seems to be working out very nicely. These tips I have designed for the script heavy mod, because as most of us know, without scripting mods basically do nothing of interest. Hell, these rules even are still evolving a little to this day, but I am pretty set in these ways. The main thing is that if you styled your modding patterns after how Bethesda made the core game, you are going to end up with a very messy clusterfuck, very fast. So don't.

 

The bulk of these have to do with properly namespacing your shit. If you are unaware, namespacing is the practice of putting your code down in a way that your files will never have name conflicts with another mod - unless somebody hates you and specifically targets your shit.

 

Also keep in mind that this was written to be partially offensive if you disagree with me. I offer a solution: if you disagree with me you should be offended and change your ways.

 

And one more thing before we begin, let me tell you about myself. I am a programmer by trade, it is what I do. I primary code in C, C#, PHP, Javascript, and of course Papyrus. Not just a programmer, but a back end programmer. My job is to make frameworks and APIs that other people can use and not want to commit suicide. I am taking that experience and dumping into here to, hopefully, prevent you, the modder, from also commiting suicide, and to help you make your mods make more sense to the people who try to mod your mods.

 

I'm not writing this because I am amazing and nailed it first try. I am writing this to help you avoid all the traps I fell into when I tried to do what everyone else is already doing.

 

Naming Your Mod.

 

Name your god damn mod. Do not use your own name as part of the name.

  • Darkconsole's Alchemy Updates
  • Darkconsole's Huge Boobs Body Shape Preset

Be creative, for fucks sake. You are creating a mod, you are engaging in pure creation. Be creative. Christ. Don't be so vain, it is not about YOU, it is about the damn mod! When you make it about you, you just come off as a flaming toolbag.

 

"But your blog is, Darkconsole's Blog, hahah" duh, because the blog is about the things I say, not about the things I am making. :P

 

 

Creating Object Entries.

 

All object entries in CK should be prefixed - and prefixed with something meaningful. For example, all my mods are prefixed with my signature and the mod signature.

  • Windrunner: dcc_wr_
  • Windrunner's Expansion: dcc_wrr_
  • Untamed: dcc_ut_
  • Untamed Tattoo's dcc_uttat_

etc. When I redo Display Model this year, dcc_dm_.

 

Here is the thing. I don't give a fuck if its hard to type or read or find. Don't be stupid. If you prefix your things with aaa or _ or anything else, you are bad and should feel bad. Dear god, if you use that prefix (aaa/zzz/_) on your script files too, you more or less deserve to die in a fire.

 

The main thing is you need to pick a prefix that is descriptive, unique, and reusable in both CK and for filenames. Seriously, as a modder everything you have to deal with has a fucking filter box for you to easily dig up your objects and I suggest you make it your best friend.

 

There is another step to this though, the next step is to now include the TYPE of GAME object it is in the name. Lets say we created a magic effect that heals you. I would then name it, dcc_ut_EffectHeal. This is a nod towards how half the vanilla objects are created.

 

Now lets say I created the SPEL to use the MGEF.

  • dcc_ut_SpellHeal will then use dcc_ut_EffectHeal as its magic effect.

Now lets say I created a spell that needs to have multiple magic effects. Lets namespace this further.

  • SPEL dcc_ut_SpellSuperDuper
  • uses MGEF dcc_ut_EffectSuperDuper_DamageResist
  • uses MGEF dcc_ut_EffectSuperDuper_MagicResist
  • uses MGEF dcc_ut_EffectSuperDuper_AttackDamageMult

And just by looking at those effects you know that all 3 are probably Value Modifiers that modify things like Damage Resist, Magic Resist, and Attack Damage Multiplier. Brilliant.

 

If you are wondering about a max name length... I am sure there is one, but I have not had any problems so far and you are seeing how descriptive these names are getting.

 

 

Property Binding Custom Objects.

 

For a long time I refused to use the auto-fill feature of CK, and I actually still do refuse to use it for stock game objects - we haven't talked about code yet though. However, any items I added to CK I now use the auto-fill ability on.

 

In my script you will see things like:

  • Shout Property dcc_ut_ShoutMateCall Auto
  • Spell Property dcc_ut_SpellShiftCat Auto

Which means yes, I am referencing them as self.dcc_ut_ShoutMateCall in the code. I know that is a lot to to type and programmers are inherently lazy (unelss you are Java developer, in which case you are the master of clusterfucked obfuscation). But don't be retarded. Make your code easy to read and understand. Do not make your code a Perl shorthand pile of Dragur shit.

 

So because of what I said in the previous section, I created my spelled named dcc_ut_ShoutMateCall and now the Auto-fill button on the Script Property dialog will magically fill them all in with one click.

 

 

 

Property Binding Vanilla Objects.

 

As I already mentioned, using the game as it exists as a template will result in very poor structure and organisation. Default things are named like "BearBlackRace" and "EnchFortifyHealth" - lets look at that. That is two completely different namespace systems.

  • BearBlackRace, BearCaveRace, BearSnowRace - they have prefixed these races with the name of what kind animal it is. They stick with this (for the most part) with most of the races. WoodelfRace, WoodelfVampireRace, OrcRace, etc.

  • EnchFortifyHealth, AlchFortifyHealth - here they have prefixed these objects with the actual type of game object it is. Completely different from the races. But this is actually the "right way!"

So here is what I suggest: when you are dealing with VANILLA objects, you completely disregard the rules I set for custom objects and even property binding. Also disregard what Bethesda did. Here, Prefix the shit with the TYPE of GAME object it is.

  • RaceBearBlack, RaceBearBrown, RaceBearSnow
  • which should look suspiciously like EnchFortifyHealth and AlchFortifyHealth.

This means now auto-fill will not work for vanilla objects - but oh well. That is the price we are going to pay to acknolege two things about the object: first that it is vanilla and not an object I made. Second being that we have learned how not to be bad by now.

 

When you read my code now you will see references to self.RaceBearBlack which is pointing at Skyrim's vanilla BearBlackRace, and self.dcc_ut_SpellShiftBear - by nature of the two different namespacing systems you know exactly which properties are default vanilla objects and which are custom objects without even opening CK. Plus, now all my Papyrus has constant structure for the variable names.

 

 

Script Fragment Renaming.

 

By default when you create a script fragment in CK, it ends up with a filename like TIF__G0FKURS3LF.PSC. Go ahead, open your Skyrim directory and look. You probably have a thousand of these TIF__ files laying around because of so many modders being bad.

 

The brilliant thing is that CK lets you rename these files and it takes almost no time. I already wrote a blog that details how and why you would want to do this. The TLDR version is that if you do not rename your fragment, both the Skyrim script directory and the players save is going to be a clusterfuck of hidden files that are near impossible to clean out easily. When you prefix your shit, save game editors and filesystem browsers can easily filter on things like "dcc_ut_" and show you only the things you need to take care of.

 

If you follow that blog post your TIF__D0NG54L1F3.PSC files will become things like "dcc_ut_DiagFrag_HandleAnimal_Follow.psc" - descriptive and very targetable. Now you know exactly which file you need to edit if you want to change how it works or recompile and you never have to even open CreationKit to do it.

 

Lets digest that script fragment name as though we are looking at the file lists in Windows Explorer: dcc_ut_DiagFrag_HandleAnimal_Follow.psc

  • We know it is from the Mod Untamed by Darkconsole.
  • We know it is a Dialogue Fragment.
  • We know it is part of the Handle Animal Dialog Topics where all my animal commands are handled.
  • We know this fragment is the fragment that tells animals to follow you.

Amazing. So much info.

 

 

Scripting File Names.

 

You should follow the exact same rules as detailed under Creating Object Entries for making file names for your scripts. And you better not be forgetting about the Script Fragment Renaming section, either.

 

 

Resource File Names.

 

Resources are any files which are not scripts. Images, Meshes, Textures, whatever. Creation Kit will force you into a few low level conventions like "meshes have to be in meshes" and "textures have to be in textures" else you will get these "invalid directory" warnings.

 

But we need to take this a few steps further. You need to subfolder your shit.

  • interface/untamed/splash.dds
  • meshes/untamed/whatever.nif
  • textures/untamed/whatever.dds

See what I did there? I made a subfolder using the name of my mod. Pure brilliance. Don't be afraid to subfolder even deeper in your own mod folder to do things like separating armor meshes and textures from eachother. This is a lesson in physical organisation.

 

Notice I used the MOD NAME and not MY NAME as the subfolder. If you look at my Pony Pack you will see where I fell into the trap of using MY NAME as the subfolders, and now it is clusterfuck of shared directories and overwrites because I did the same thing in SGO and I regret every moment of it.

 

 

BSA Packing.

 

BSA packing, contrary to any rants you may have seen me engage on IRC, is good. It will actually make your mod load a little faster because of computer science I am not going to get into.

 

However.

 

Are you making a Framework that other modders are going to use?

 

No? Ok. BSA that shit.

Yes? DON'T BSA THAT SHIT.

 

If you force a modder to extract your script files to compile, the next time you update all the modders are going to have to extract again. Or they will forget and wonder why their game is so fucked and not getting your bug fixes because the game values flat files over archived files.

 

Make a "SDK" which contains the source files (SkuUI, RaceMenu), or just distribute the mod as loose (SexLab, PapyrusUtil).

 

I'm looking at you, SexLab Aroused.

 

 

 

The Self Keyword.

 

Taking for example this code:

Scriptname dcc_ut_QuestWhatever extends QuestActor Property dcc_ut_ActorSomebody AutoSpell Property dcc_ut_SpellSomething Auto;; ...

You can of course reference dcc_ut_ActorSomebody as is in that script. Now, when you bind this script to another script...

Scriptname dcc_ut_QuestAnother extends Questdcc_ut_QuestWhatever Property Whatever Auto;; ...

Now to access that actor we have to call Whatever.dcc_ut_ActorSomebody. But lets go back to the dcc_ut_QuestWhatever script. Because they are local properties you can just call them out, but I am suggesting you call all the properties with the self keyword included. E.g. self.dcc_ut_ActorSomebody.

 

This serves one purpose: it proves that you know where your shit is coming from. It's coming from right here. It also creates a consistent look across all the scripts for accessing properties. Plus looking at this code here...

Function DoSomeShit()    Int Counter = 0    Int Total = self.dcc_ut_ActorSomebody.GetNumItems()    Int Item    While(Counter < Total)        Item = self.dcc_ut_ActorSomebody.GetNthItem(Counter)        ;; ...        Counter += 1    EndWhileEndFunction

You now very easily can see which variables are actually properties and which variables are actual local variables (the ones without self).

 

 

1 Comment


Recommended Comments

Yep. I've noticed most of this in various mods I've downloaded.

And... if I may rebut (hur hur hur... re-butt... hur hur hur) or just comment:

And since this is the internet, I guess I should point out at the start that this entire thing is mostly tongue-in-cheek, because I absolutely refuse to write JK LOL after every statement to ensure that people don't take me seriously.

 

Naming your mod


But then how will people know it's from me? It's not like they can look under "submitter" and see my name, or look at my profile and see my mods, or anything like that. Without the "coco" in front, the mod will be lost in the maelstrom of other modders submitting batch files and retextures! And that would be a loss to society!

When I made my first "mod" (that yep, doesn't actually do anything much), I thought it was just a convention to use your name as the mod's prefix, or use "sexlab" if the mod had anything to do with sexlab.

I'm nothing if not a follower of standard conventions. It's why I write this:

int main()

{

  cout << "Goodbye, cruel world" << endl;

  return 0;

}

Instead of this:

int main(){cout << "Goodbye, cruel world" << endl; return 0; }

 

I do actually have one argument... your blog is Darkconsole's Blog, yeah, I get that the things you say are different than the things you do (btw, do you really want to advertise that? :) ), but what are words if not creative?


 

Creating Object Entries


Yep. That's just good programming.

I'm pretty slapdash about this... everything is prefixed the same way (I like to prefix my scripts with "TIF" just to piss people off) but none of it's very descriptive. That is, I'm only in the process of making one mod at the moment, and I consider myself justified in just throwing shit in there as I'm learning.

 

But prefixing with "superduper" or equivalents goes against my grain. I would say "table, metal" rather than "metal table" because I read from left to right.


 

Property Binding Custom Objects


What the hell is auto-fill? How does it work?


 

Property Binding Vanilla Objects


Preach it, brother!


 

Script Fragment Renaming


Okay, aside from what I said previously about prefixing my scripts with TIF, I don't actually do that, and never have done. It's irritating in the extreme.

My question is - since the script auto-names to TIF_whatever before you rename it, does a copy of the originally named script still reside in the scripts directory? I've never actually checked.

It technically shouldn't be a problem because the script is never called, but I've used some mods that put scripts in the dir that are still referenced by the base game EVEN AFTER YOU DISABLE THE MOD AND START A BRAND NEW CHARACTER, IT'S EXTREMELY ANNOYING.


 

Scripting File Names


Amen, hallelujah!


 

Resource File Names


Gather round, brothers and sisters, and hear the words of wisdom!


 

BSA Packing


Can you point to a link where it tells you how to BSA pack? I've never done it, and I'm scared to try. It's my first time, be gentle. Hold me.


 

The Self Keyword


M'kay.


Link to comment
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. For more information, see our Privacy Policy & Terms of Use