User openmw.cfg
The last file loaded: the one the launcher edits, and the one save_user() writes.
Library active
Read, compose and write OpenMW's openmw.cfg chains from Rust, or from Lua embedded in a Rust host.
cargo add openmw-configOpenMW does not read one openmw.cfg. It reads a chain of them: a root config beside the
executable or in the system’s config directory, which points with config= at the user’s, which
may point further. Each file adds data directories, content files and fallback settings, and any
of them can replace= what the files before it said. Tools that open the user’s openmw.cfg
directly see only the last link, and get the load order wrong on every packaged install.
openmw-config reads the chain the way OpenMW does, and gives you the result as one configuration you can inspect, change and save. Every setting remembers the file it came from and the comments above it, so saving writes each change back to the file that owns it and leaves the rest of the chain alone.
The crate walks the same chain OpenMW does, keeps track of which file said what, and writes changes back to the file that owns them.
Beside the executable, or the platform's global config. A package's root usually ends with config="?userconfig?".
config= entries load depth first, as OpenMW's loader walks them. replace= discards what came before, tokens resolve, relative paths anchor to their own file.
Content files, data directories, archives, fallback settings and unknown keys, each tagged with its source file and comment.
The last file loaded: the one the launcher edits, and the one save_user() writes.
A Rust host registers openmwConfig, and scripts get the same model through a camelCase API.
OPENMW_CONFIG, OPENMW_CONFIG_DIR, the
executable’s directory and the global config; config= depth first, as OpenMW’s loader walks
it; every replace= form; the ?local?, ?global?, ?userdata? and ?userconfig? tokens,
Flatpak included.luau feature, a Rust host composes an l3i extension into its
runtime plan and scripts get the same configuration through a camelCase API, typed.config_chain() lists
every file it loaded and every config= target it skipped.use openmw_config::{ConfigError, OpenMWConfiguration};
fn main() -> Result<(), ConfigError> {
let mut config = OpenMWConfiguration::from_env()?;
for plugin in config.content_files_iter() {
println!("{}", plugin.value());
}
config.add_content_file("Better Balmora.esp")?;
config.save_user()
}This site is the crate’s documentation, its API reference included.
openmw-config models openmw.cfg only; settings.cfg is not handled yet. It is not affiliated
with the OpenMW project.
Rust crate · 3.0.2
From your project's directory:
cargo add openmw-config
Or by hand, in Cargo.toml:
[dependencies]
openmw-config = "3.0.2"
Cargo reads a bare version as "this or any compatible newer release" and records the exact one in Cargo.lock.
[dependencies]
openmw-config = { git = "https://github.com/DreamWeave-MP/Openmw_Config" }
Cargo pins the commit it fetched in Cargo.lock; cargo update -p openmw-config moves it forward.
Anything not listed here is untested.
Builds OpenMW's virtual file system from the data directories this crate resolves.
Built on l3i 1.1.0.
@dream/openmw-config module is unchanged.The same digest as the crates.io index's checksum, which Cargo checks on every download.
The Luau bindings are an l3i extension with live views and typed rows, the loader reads config= chains exactly as OpenMW’s engine does, and the site is built with the DreamWeave Mod Template.
luau feature makes the crate an l3i extension, openmw_config::luau::extension(), providing the module @dream/openmw-config, with live views over the loaded configuration and typed rows. create_lua_module, the mlua types and the standalone-lua feature are gone.luau feature needs l3i’s toolchain: clang, lld and cross-language thin LTO. Rust 1.92.config= entries load depth first, each config= directory is read once, a config= directory without an openmw.cfg stays in the chain, the user config directory is created on load, replace= applies per config over the configs loaded before it, replace=config keeps the root and the config= entries still to load, replace=replace discards the replace= lines of earlier configs, replace= values match option names exactly, and resources=, user-data=, data-local= and encoding= are left alone by replace=.SettingValue exported so predicates can name what they are given, and the meta() and typed accessors every setting type has.save_user, save_subconfig and Display keep replace= lines; list replacements and removals persist through replace= lines in the user config, and a parent’s entries stay in the parent’s file when the user config replaces a list.resources/vfs data directory is no longer written back as a data= line on every save; the directories resources= and data-local= add stay in step with them.io::Error behind ConfigError::Io is reachable through source().add_archive_file returns CannotAddArchiveFile on a duplicate; replace=fallback-archive is read and written under the option name OpenMW uses.set_game_setting writes its comments as comment lines, and the comments and blank lines that end a config file survive the settings added after them.resources=, user-data=, data-local= or encoding= stays in place when the user sets one.The same digest as the crates.io index's checksum, which Cargo checks on every download.
save_user, save_subconfig and Display drop replace= lines, so a saved user config merges its parents’ entries back in on the next load. Fixed on the default branch.resources= writes the injected resources/vfs directory back as a data= line, and each save and reload adds another copy. Fixed on the default branch.The same digest as the crates.io index's checksum, which Cargo checks on every download.