Skip to content
openmw-config
api

Configuration

Every method and field of the configuration object: where it came from, the chain, plugins, directories, settings, saving, and the views and rows it returns.

The object the loaders return: a whole chain, loaded, of type dream.openmw.Config (dream_openmw_Config in the definitions). Call its methods with : and read its fields with .. Each mirrors a Rust method, named in the last column; the Rust API has the full behavior, and the guides the traps.

local cfg = openmwConfig.fromEnvOrUserConfig()

for _, plugin in cfg:contentFiles() do
    print(plugin)
end

if not cfg:hasContentFile("MyPlugin.esp") then
    cfg:addContentFile("MyPlugin.esp")
end
cfg:saveUser()

Where it came from#

MethodReturnsRust
rootConfigFile()The openmw.cfg the chain started atroot_config_file
rootConfigDir()Its directoryroot_config_dir
userConfigPath()The user’s config directory, where saveUser() writesuser_config_path
isUserConfigA field: whether the root is the user’s configis_user_config
userConfig()A new configuration loaded from the user’s configuser_config_ref

Lists and counts#

The methods that return a list return a view over the live configuration, not a table:

local content = cfg:contentFiles()
print(#content, content[1], content[#content + 1]) -- the length, the first name, nil
for i, name in content do
    print(i, name)
end
local names = content:toTable() -- a plain table, for ipairs and table.*

#list, list[i] (1-based, nil past the end), for and toTable() are the whole surface; ipairs, pairs and table.* need the table. A view copies nothing until an element is read and sees every change made after it was taken. The string lists are dream.openmw.Strings; the setting and chain views are named with their rows below.

The counts are fields, read without a call:

FieldCountsRust
contentFileCount, groundcoverFileCount, archiveFileCountThe content=, groundcover= and fallback-archive= entriescontent_file_count, groundcover_file_count, archive_file_count
dataDirectoryCountThe data directories, the injected ones includeddata_directory_count
gameSettingCountDistinct fallback= keysgame_setting_count
genericSettingCountThe preserved unknown entriesgeneric_setting_count
subConfigCountThe config= directories in effectsub_config_count

The chain#

MethodReturnsRust
configChain()Every file the loader tried, a dream.openmw.ConfigChain view of rowsconfig_chain
subConfigs()The config= directories in effect, a view of stringssub_configs

Plugins and archives#

MethodDoesRust
contentFiles()The content= names, in load order, as a viewcontent_files_iter
groundcoverFiles()The groundcover= names, as a viewgroundcover_iter
fallbackArchives()The fallback-archive= names, as a viewfallback_archives_iter
hasContentFile(name), hasGroundcoverFile(name), hasArchiveFile(name)Whether the name is listedhas_*
addContentFile(name), addGroundcoverFile(name), addArchiveFile(name)Appends it; raises if it is already listedadd_*
removeContentFile(name), removeGroundcoverFile(name), removeArchiveFile(name)Removes every entry with the nameremove_*
setContentFiles(list), setFallbackArchives(list)Replaces the whole list with a plain table of names; nil empties itset_content_files, set_fallback_archives

Names compare exactly, case included.

Directories#

MethodDoesRust
dataDirectories()The data directories, resolved, in load order, as a viewdata_directories_iter
hasDataDir(path)Whether a data directory resolves to pathhas_data_dir
addDataDirectory(path)Appends oneadd_data_directory
removeDataDirectory(path)Removes every data= entry resolving to, or written as, pathremove_data_directory
setDataDirectories(list)Replaces the data= entries; nil leaves none. resources/vfs and data-local stayset_data_directories
userData(), resources(), dataLocal()The directory, resolved, or niluserdata, resources, data_local
setUserData(path), setResources(path), setDataLocal(path)Sets it; nil removes the last definitionset_*_path, clear_*

Settings#

MethodDoesRust
gameSettings()Every fallback key once, with its current value, a dream.openmw.GameSettings view of rows; most recently defined firstgame_settings
getGameSetting(key)One key’s current value as a row, or nil. Case-sensitiveget_game_setting
setGameSetting(value, sourcePath, comment)Adds a definition, "Key,Value"; see belowset_game_setting
setGameSettings(list)Replaces every fallback setting; nil leaves noneset_game_settings
genericSettings()Every line with a key the crate does not recognize, a dream.openmw.GenericSettings view of rowsgeneric_settings_iter
addGenericSetting(key, value)Appends key=valueadd_generic_setting
setGenericSettings(key, list)Replaces every entry with key; nil removes themset_generic_settings
encoding()"win1250", "win1251", "win1252" or nilencoding
setEncoding(name)Sets encoding=; see belowset_encoding

setGameSetting#

value is written as it would be after fallback=: "Weather_Clear_Sky_Sunrise_Color,160,170,190". sourcePath is the openmw.cfg to attribute it to, nil for the user’s. comment, or nil, is written above the line, with # added to each line that lacks it:

cfg:setGameSetting("Weather_Clear_Sky_Sunrise_Color,160,170,190", nil, "Brighter dawns")

Raises when value has no comma. The new definition wins because it is last; earlier ones stay in their files.

setEncoding#

Takes "win1250", "win1251" or "win1252", exactly, attributed to the user’s config, and raises on anything else. nil removes the last encoding=.

Saving#

MethodDoesRust
saveUser()Writes the user’s openmw.cfg, preservedsave_user
saveSubconfig(dir)Writes the openmw.cfg of a config= directory in the chainsave_subconfig
saveToPath(path)Writes the whole chain, preserved, to pathsave_to_path
saveResolvedToPath(path)Writes the whole chain, flattened, to pathsave_resolved_to_path
toString()The whole chain, preserved, as a stringDisplay
toResolvedString()The whole chain, flattened, as a stringto_resolved_string

Saving and exporting explains preserved and flattened output. tostring(cfg) does not serialize, it names the object and its root file: call cfg:toString().

Row shapes#

Rows are userdata with read-only fields, read from the configuration when the field is read:

Rows fromTypeFields
configChain()dream.openmw.ChainEntrypath: string · depth: number, 0 for the root · status: "loaded" or "skippedMissing"
gameSettings(), getGameSetting(key)dream.openmw.GameSettingkey · value: the text as written · kind: "Color", "Float", "Int" or "String" · typed: the parsed value · source: the openmw.cfg it came from · comment: the comment lines above it, or ""
genericSettings()dream.openmw.GenericSettingkey · value · source · comment

typed is value parsed by kind: a Luau integer for "Int", a number for "Float", a vector of the red, green and blue components for "Color", and the string itself for "String".

local dawn = cfg:getGameSetting("Weather_Clear_Sky_Sunrise_Color")
if dawn then
    print(dawn.kind, dawn.value, dawn.source)
    -- Color   117,141,164   /etc/openmw/openmw.cfg
    print(dawn.typed.x, dawn.typed.y, dawn.typed.z)
    -- 117   141   164
end

A setting row belongs to the configuration it was read from at the moment it was read. After any change to that configuration, reading a field of the row raises an error that says it is stale, rather than the entry that now sits at its position; fetch the row again. Chain entries never go stale: the chain is fixed at load.