Oblivion Mod:Cobl/Modding/Techniques
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.
Contents
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.
- The namespace root should be fairly short ('cobSal' for Salmo the Baker).
- 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:
- Overrideable: Designed to be overwritten by a user mod.
- Private: Do not reference or use.
- Public: Can be referenced/used as a resource.
- 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.
- 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.
;--OVERRIDEABLE ------------------- ; Script Description ; How to override, what not to do
;--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
;--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.)
; 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