Oblivion Mod:Cobl/Modding/Techniques

The UESPWiki – Your source for The Elder Scrolls since 1995
Jump to: navigation, search

This page is dedicated to various standards and techniques used in Cobl. Some of this is particular to Cobl design and use, while other techniques are usable in other mods.

Naming Standards[edit]

Variable Names[edit]

  • Common Names:
    • Show: Will cause something to appear if true.
    • Override: As a flag of the overriding script.
    • Bypass: Script is being bypassed. (E.g. cobEatFactorsQ.)
  • Ref Variables
    • Ref type variables should almost always be prefixed with 'r'.
    • E.g. rRealDeath, rBypass, rShowDinner, rNpcRef, rNpcBase.
    • Even when using OBSE to store other types of formids, use 'r'.
  • Ref vs. Base variables (OBSE only)
    • To distinguish between ref vars that hold references and ref vars that hold base objects, use the suffixes "Ref" and "Base" to distinguish between them.
    • E.g. rTargetRef vs. rTargetBase
  • Loop control: iXXX, numXXXs
    • E.g. iSpell, numSpells, rSpell for looping over an npcs spells.
    • iXxx is the loop counter. numXxxs is the number of elements to loop over.
    • Counter should run from 0 to 1 less than numXxx.
    • E.g set iSpell to 0. if iSpell < numSpells...
  • Functional Activators
    • When an activator is constructed to be used as a function:
    • xxxFA: Activator base object.
    • xxxFAS: Script for activator base object.
    • xxxFAR: Placed activator reference.
  • Array Variables (OBSE/Pluggy only)
    • Start array variables with 'a'
    • E.g. aShapes, aTargets, aSpells.
    • Might also use a second prefix to indicate type of variables stored in array.
      • E.g. arTargets (array of references), aaShapes (array of shape arrays).
  • String Variables (OBSE/Pluggy/Tibixe's String Function Collection only)
    • Start string variables with 'so' for OBSE strings, 'sp' for Pluggy strings, 'st' for TSFC strings
  • Number variables
    • Other variables can use prefixes (f for float; b for boolean; ?? for short/long).
    • However, it's usually more natural to not use such prefixes.
      • E.g. hasWater reads more naturally than bHasWater.
      • waterlevel reads more naturally than fWaterLevel.
    • Generally only use prefixes for numbers when there is likely to be confusion over their type.

Package Namespaces[edit]

  • Root names
    • All Cobl content starts with 'cob'.
    • Cobl auxiliarary content (added in a cob esp) starts with 'cab'.
  • Package names
    • All records within Cobl belong to a package, which is indicated by what comes after 'cob'. E.g., cobWater for water wells, barrels, etc.
    • Packages in the main part of Cobl are usually named by function.
    • Pure resource packages are usually named by the author. (cobTexWater for Texian's Water meshes.
    • Obsolete records are renamed to add 'old' before their package name.
      • E.g. cobEatPower becomes cobOldEatPower.
  • Package naming considerations:
    • The namespace root should be fairly short ('cobSal' for Salmo the Baker).
      • Shorter names are easier to type (in most TESCS record lists, you can jump to a group of names by typing the name out).
      • Shorter names work better in TESCS sometimes narrow columns for editor ids.
  • Editor End Codes
    • OS: Object script
    • QS: Quest script
    • MS: Magic effect script.
    • Q: Quest (not always used)

Current Namespaces[edit]

Namespace Usage
Als Alchemical Sorter.
Altar Mage altars.
Amw Ayleid Meteoric Weapons.
Bal Balanced races.
Bev Various drinks: Beer, Morrowind drinks, drinks from Coleen's Farmers Market.
Cat Alchemical catalogs.
Clo Clothes.
Clock Clock.
Col Foods from Colleen's Farmers Market.
Denock Denock arrows.
Eat Dinner plate, buffet plate, etc.
Eye Eyes.
Fact Standard/signal factions.
Fix Fixes. Item swappers for OOO, MMM, etc.
Gen General useful stuff.
Geo Geomancy and dust.
Grinder Grinders.
Hair Hair.
Input Input handling.
InvTracker Inventory tracker.
Lang Language related globals.
Lof Fan written lore books.
Lor Lore books from previous games.
Lug The Luggage!
Menu Menu displaying items and handling.
MgcTracker Magic Tracker
Mort Death handling.
Opt Options menu.
Patch Patch scripts for OOO, MMM, etc.
Pc Player specific globals and variables.
Poison Poison dialog skipper.
Race New races.
RUE Recipe Updater Engine
Sal Salmo foods.
Sig Signal variables and factions.
StaticApp Static Alchemical Apparati.
Store Store supplies/containers for clothes, armor, weapons.
Str String functions, factions, etc.
TexWater Texian's water meshes.
Test Testing objects, etc.
Ti Tamrielic Ingredients.
cobVend Standard vendor containers and lists.
Vi (Vacuity/Item Interchange). Item Interchange base lists.
Water Water wells, barrels, etc.

Registration Refs[edit]

Cobl has a number of features that are designed to be turned on, activated or temporarily owned by Cobl Aware mods. Registration ref variables are used to indicate: 1) that the feature is activated/owned, and 2) which mod or mod function is doing the owning.

One of the distinct advantages of registration refs is that they are self-de-registering. I.e. registration refs occupied a refs from some mod will automatically de-register (become equal to zero) if the mod is removed from the load order.

Example: To enable the dinner plate menu, a survival mod needs to set cobMenuQ.rShowDinner to a ref owned by the survival mod. If that survival mod is later removed by the user, rShowDinner becomes == 0, and so Cobl will disable the menu (remove the item from the user's inventory).

Example: Survival mods differ in the sophistication with which they handle water barrels. More sophisticated mods may need to use some of the "extra" variables that Cobl provides for water barrels (state, afloat, ashort). However, interpretation of these variables will depend on the particular mod used. To ensure consistent behavior, a survival mod can/should take ownership of the barrel like so:

if rOverride != myToken
    set rOverride to myToken
    set state to [initial value]
    set ashort to [initial value]
    set afloat to [initial value]
endif

Example: Death handling. The rRealDeath and rFakeDeath refs are used to indicate which mod currently owns that function. Since several death handlers may be simultaneously vying to control death handling, these variables provide a way to determine which of the candidates currently owns death handling. Specifically:

  • If rRealDeath == 0, then a mod is free to take ownership.
  • After taking ownership, rRealDeath should be checked periodically to ensure that ownership is retained. (It may be that some higher priority mod has taken ownership.)

Note: While ref variables will automatically go to zero if the source mod is de-activated, they will not go to zero if the original ref is removed from the mod, but the mod is left in the savegame.

Container Menus[edit]

Container menus are convenient because:

  • Allow multiple mods to contribute to the container.
  • Can be provided with a consistent interface to the user.

For more info, see Cobl/Projects/Menu Containers.

Override Scripts[edit]

Some scripts in Cobl are designed to be overridden. Several of the survival scripts work this way (cobEatEffectsQS, cobWaterWellOS, cobWaterBarrelOS).

When overriding these, Cobl-aware mods should never add or remove variables! Not even temporarily! The reason for this is due to the way that variable values stored in the savegame relate back to variables defined in mod scripts. The major danger here is a conflict between Cobl and Cobl-aware mod, or between two different Cobl-aware mods. Such problems can cause CTDs and other strange behavior.

(If errors are accidentally introduced into a script, there are ways to repair it using Tes4Edit, however, this is a fairly advanced technique, and won't repair damage already done to savegames.)

Tandem Scripts[edit]

In some places, Cobl supports co-ordination through supporting tandem scripts. Tandem scripts are typically quest scripts designed to operate in parallel. While this is a bit more complicated than Override scripts, its also more powerful since it allows several Cobl aware mods to do the same thing simultaneously. It's also somewhat safer since it's much less prone to variable add/remove errors.

For scripts designed to work in tandem, usually one of the scripts is the "leader" and the other scripts are the "followers". Followers sychronize with the leader by monitoring state variables in the leader.

E.g. the dinner plate has a leader quest cobEatQ which manages the general flow, and several followers (cobEatVanillaQ, cobEatSiQ, etc.) which handle specific sets of foods. The followers do the food moving and calculation based on state variables in cobEatQ. While these followers are all started and stopped by the leader (cobEatQ), a Cobl aware mod could add a new follower quest as a permanently running script; and so long as it followed correctly it would have exactly the same effect as the cobl-supplied followers.

E.g. Death handling mods provide scripts that act as followers to the leader cobMortQ script. These typically operate in two modes: 1) Waiting to become owner; 2) As owner. When the death handler is operating as owner, it may manipulate the state of the leader at times (e.g. forcing the cobMortQ.timer to -10 to prevent it from going to the next state).

Obsolete Records[edit]

When records become obsoleted, the original record should be left in the mod. Also, the record eid should be changed to insert an 'Old' just before the package name. E.g. cobEatPower becomes cobOldEatPower.

Scripting Standards[edit]

;--DO NOT MODIFY THIS SCRIPT!!!
;  DOING SO WILL CAUSE CTDS AND STRANGE BEHAVIOR FOR USERS.
;  If you need this script to do more, have a suggestion, or an alteration:
;  contact the Cobl team at: http://www.uesp.net/wiki/Tes4Mod:Cobl/Modding/Board

;--TRANSLATE ME! (Only if applicable.)
;  Translators: Be sure to use Tes4View/Tes4Edit to make sure that script
;  variables are consistent between original and translated version! (Otherwise
;  CTDs may result.) Please make sure that you only translate what is in 
;  between quotes, and leave all parameters (i.e., %c, %%, |) as they are.

;--SCRIPT TYPE --------------------------- (Choose the applicable script type. See below for more information.)
;...

;--VERSION HISTORY
;  v1.62  Yadda, yadda.
;  v1.60  First version.

;--COMPILE REQUIREMENTS (If applicable.)
;  REQUIRES OBSE   v15
;  REQUIRES PLUGGY v73
;  REQUIRES TSFC   v5

scn cobFooBarOS

Script Types:

  1. Overrideable: Designed to be overwritten by a user mod.
  2. ;--OVERRIDEABLE -------------------
    ;  Script Description
    ;  How to override, what not to do
  3. Private: Do not reference or use.
  4. ;--PRIVATE -------------------
    ;  DO NOT USE OR REFERENCE.
    ;  SEE SCRIPT(S): cobClockFAR, cobClockOS (List related, public scripts, if applicable.)
    ;  More information: http://www.uesp.net/wiki/Tes4Mod:Cobl/Modding/Clock (If applicable.)
    ;  Script Description
  5. Public: Can be referenced/used as a resource.
  6. ;--PUBLIC -------------------
    ;  Script description
    ;  OBJECT/QUEST/EFFECT/FUNCTIONAL ACTIVATOR/SERVICE/MONITOR SCRIPT
    ;  Usage information
    ;  More information: http://www.uesp.net/wiki/Tes4Mod:Cobl/Modding/Clock (If applicable.)
    • Object/Quest/Effect - General, catch-all script types. Use these if no other script type seems applicable and script seems unique. Alternatively, you can create a new script type.
    • Functional Activator is an object script designed specifically to be used as a function.
    ;  FUNCTIONAL ACTIVATOR SCRIPT
    ;  Usage: Set the Input/Optional variables: "set cob---FAR.InputOpt to 1"
    ;  Activate: "cob---FAR.Activate cobGenActRef, 1"
    ;  If available, check output variables: "if (cob---FAR.Output == x)"
    ;  PLAYER REQUIREMENTS: NONE (Note the minimum player OBSE/Pluggy/etc. requirements here)
    ;    Check for any Player Requirements with
    ;        SetStage cobSigSE 0
    ;        if (cobSigSE.Version >= 15) && (cobSigSE.VersionPluggy >= 73) ;Version = OBSE Version
    ;  Activator Depth: +0
    ;  Labels Used: 0
    • Service is a "just in time" quest script that is started to provide some short lived functionality and then shuts down. E.g cobEatVanillaQ.
    • Monitor is a quest script that isn't really for a quest, but rather runs persistently, monitoring and making changes as needed. E.g. cobMortQ.
      • Monitor scripts can act much like service scripts -- i.e. they can be mostly passive until something else triggers them to provide an additional service. E.g. Wrye Morph's main script runs continuously in monitor mod (where it does periodic checks), but it also runs in service mode after being triggered to provide a morph, new form or teleport.