Scene Configuration Reference
Scene::default_config() / Scene.default_config() provides the values for a
simulation scene. Scene::config_schema() / Scene.config_schema() is the
machine-readable contract for every registered key: defaults, storage and JSON
types, units, hard constraints, lifecycle, implementation status, descriptions,
and source-level consumers. The tables below present the same contract for
humans. A single typed declaration creates both the runtime defaults and schema
metadata, preventing the two views from drifting as keys evolve. It lives in
scene_default_config.cpp,
while effective-value rules and selector values were checked against the CUDA
backend that consumes them.
Important
Scene configuration is strict: unknown keys, wrong storage types, non-finite
values, unsupported selectors, and values outside the documented hard
constraints are rejected. Validation runs when constructing a Scene and
again in World::init(scene), after any mutable scene.config() edits.
Querying the contract
The schema is available without reading backend source and can be consumed by tools, agents, editors, and configuration generators.
The installed command-line interface can dump either the complete schema or a single slash-separated key:
Creating and editing a configuration
The usual path is to copy the defaults, change only what the scene needs, and then construct the scene.
A scene also exposes its registered configuration as attributes. This is
useful when a scene has already been created or loaded. Make these changes
before world.init(scene): several backend systems cache configuration
values during initialization, so scene.config() is not a general hot-reload
interface. Call scene.validate_config() for an earlier explicit check;
world.init(scene) calls it automatically.
In Python, Scene.default_config() returns a dictionary, but scene.config()
returns a ConfigAttributes facade, not a dictionary. Use find("dt") and
uipc.view(slot) for attribute access; retain the owning scene while using the
facade. Post-initialization attribute writes are not automatically revalidated by
every world.advance() call and are not a general backend reconfiguration API.
Do not use scene.config().create(...) as an application metadata store.
Unregistered values have no backend consumer; attach custom attributes to the
appropriate geometry instead.
Types and units
flagis stored as an integer (0or1); PythonFalse/Trueis accepted.- Length, time, velocity, acceleration, pressure, and density use SI units: m, s, m/s, m/s², Pa, and kg/m³.
- A vector is a three-component column vector. Python JSON therefore displays
gravity as
[[x], [y], [z]]. - A selector must match one of the documented strings exactly. An unsupported selector is rejected by scene configuration validation. Optional collision selectors additionally depend on the build options described below.
- Numeric hard constraints apply even when a subsystem is disabled or a relative
override is active. For example, the stored absolute
contact/d_hatmust still be positive whencontact/d_hat_relative > 0. All numeric values must be finite.
Time integration
| Key | Type | Default | Valid domain / choices | Meaning |
|---|---|---|---|---|
dt |
float, s | 0.01 |
finite, > 0 |
Time represented by one call to world.advance(). |
gravity |
Vector3, m/s² | [0, -9.8, 0] |
finite components | Global acceleration applied to dynamic bodies and FEM vertices. |
integrator/type |
string | "bdf1" |
"bdf1", "bdf2" |
Backward differentiation formula used for time integration. Start with BDF1; BDF2 changes numerical damping and transient response. |
cfl/enable |
flag | 0 |
0, 1 |
Enables the contact-system CFL step filter. This is an advanced/experimental high-speed-contact control; leave it off unless a scene has been diagnosed to need it. |
BDF2 startup and variable-step limitation
The 2026-09-11 audit of 4757859c found that BDF2 history initialization does
not preserve a prescribed nonzero constant velocity at startup. A contact-free
particle with velocity 1 m/s and dt=0.01 s advanced 0.0066667 m on its first
BDF2 step rather than 0.01 m. The implemented BDF2 coefficients also assume a
constant step size; live dt reads do not establish variable-step BDF2 support.
Use default BDF1 when relying on these cases until the integration contract is
corrected and tested. This is an identified algorithm/history limitation,
not a requirement for bitwise repeatability or a change to the solver here.
Newton solve
| Key | Type | Default | Valid domain / choices | Meaning |
|---|---|---|---|---|
newton/max_iter |
integer | 1024 |
>= 1 |
Maximum nonlinear iterations in one frame. Reaching it warns, or throws in strict mode. |
newton/min_iter |
integer | 0 |
0 <= value <= max_iter |
Hard floor before ordinary Newton convergence may terminate. 0 disables the floor. |
newton/use_adaptive_tol |
reserved integer | 0 |
exactly 0 |
Reserved for compatibility. Because no adaptive-tolerance consumer exists, setting it to 1 is rejected rather than silently doing nothing. |
newton/velocity_tol |
float, m/s | 0.05 |
> 0 |
Absolute velocity tolerance. The displacement test is max_axis_displacement <= velocity_tol * dt. |
newton/velocity_tol_relative |
float | 0.0 |
> 0 enables; <= 0 disables |
Scene-relative override. Effective velocity tolerance becomes value * rest_scene_bbox_diagonal. |
newton/ccd_tol |
float | 1.0 |
(0, 1] |
Newton convergence additionally requires the latest CCD step fraction to be at least this value. |
newton/transrate_tol |
float, 1/s | 0.1 |
>= 0 |
ABD transform-rate tolerance. The per-step threshold is transrate_tol * dt; irrelevant when no affine bodies exist. |
newton/semi_implicit/enable |
flag | 1 |
0, 1 |
Enables cumulative-step termination in IPC and the configured K_min delay in AL-IPC. |
newton/semi_implicit/beta_tol |
float | 1e-3 |
[0, 1] |
Standard IPC early-exit threshold for accumulated beta. AL-IPC uses contact/al-ipc/toi_threshold instead. |
newton/semi_implicit/K_min |
integer | 6 |
>= 0 |
Delays cumulative-progress attenuation until the configured step count. It is not a hard ordinary-Newton floor in IPC; in AL-IPC it prevents safe-path termination before that many completed outer steps. Values below 1 are treated as 1 by AL-IPC. |
See Newton and Linear Solvers for the exact termination logic and tuning guidance.
Linear system
| Key | Type | Default | Valid domain / choices | Meaning |
|---|---|---|---|---|
linear_system/tol_rate |
float | 1e-3 |
(0, 1) |
Relative PCG residual tolerance. Smaller is more accurate and usually more expensive. |
linear_system/solver |
string | "fused_pcg" |
"fused_pcg", "linear_pcg" |
Global iterative solver. fused_pcg is the optimized default; linear_pcg supports detailed PCG vector dumps. |
linear_system/fem_preconditioner |
string | "diag" |
"diag", "mas" |
FEM local preconditioner. MAS auto-partitions every non-empty FEM geometry into fixed-size clusters and is intended for stiff/ill-conditioned FEM scenes. |
linear_system/use_cuda_graph |
integer mode | 1 |
0, 1, 2 |
Fused-PCG launch mode: 0 plain launches; 1 host-checked block replay; 2 full-GPU while-loop graph. Mode 2 requires CUDA 12.4+ and falls back when unsupported. Non-IPC pipelines currently force graphs off. |
linear_system/check_interval |
integer | 5 |
>= 1 |
Number of fused-PCG iterations between host convergence checks in modes 0/1. Larger values reduce checks but make exit granularity coarser. |
Line search
| Key | Type | Default | Valid domain / choices | Meaning |
|---|---|---|---|---|
line_search/max_iter |
integer | 8 |
>= 1 |
Maximum backtracking iterations per Newton step. |
line_search/report_energy |
flag | 0 |
0, 1 |
Logs the energy contribution of every line-search reporter. Useful for diagnosis, noisy for normal runs. |
Contact and friction
| Key | Type | Default | Valid domain / choices | Meaning |
|---|---|---|---|---|
contact/enable |
flag | 1 |
0, 1 |
Builds contact detection and response systems. Disable for a deliberately contact-free scene. |
contact/d_hat |
float, m | 0.01 |
> 0 |
Absolute IPC activation distance. |
contact/d_hat_relative |
float | 0.0 |
> 0 enables; <= 0 disables |
Overrides d_hat with value * rest_scene_bbox_diagonal. |
contact/friction/enable |
flag | 1 |
0, 1 |
Enables frictional contact terms. Normal non-penetration remains active when disabled. |
contact/eps_velocity |
float, m/s | 0.01 |
> 0 |
Absolute friction transition velocity. |
contact/eps_velocity_relative |
float | 0.0 |
> 0 enables; <= 0 disables |
Overrides eps_velocity with value * rest_scene_bbox_diagonal. |
contact/constitution |
string | "ipc" |
"ipc", "al-ipc" |
Selects the standard IPC or augmented-Lagrangian IPC pipeline. |
These global keys do not define pairwise material behavior. Friction and
contact resistance for geometry pairs are set through ContactTabular; see
Contact and Collision.
AL-IPC parameters
The following keys are read only by the "al-ipc" pipeline. They are
algorithm parameters rather than material contact resistance.
| Key | Type | Default | Valid domain | Meaning |
|---|---|---|---|---|
contact/al-ipc/mu_scale_mode |
string | "per_vertex" |
"per_vertex", "diag_norm" |
Selects the stable mass-based per-vertex estimate or experimental uniform Hessian-diagonal scaling. |
contact/al-ipc/mu_scale_diag_norm |
float | 0.1 |
> 0 |
In diag_norm mode, sets mu = value * max_i(abs(H_E(i,i))), with AL contact excluded from H_E. |
contact/al-ipc/mu_scale_fem |
float | 5e7 |
> 0 |
FEM scale used only in per_vertex mode: mu_i = mass_i * value * dt². |
contact/al-ipc/mu_scale_abd |
float | 1e5 |
> 0 |
ABD scale used only in per_vertex mode: mu_i = body_mass * value * dt². |
contact/al-ipc/toi_threshold |
float | 0.1 |
(0, 1] |
Remaining cumulative safe-path weight tolerated by AL termination. Smaller values require more outer progress. |
contact/al-ipc/alpha_lower_bound |
float | 1e-6 |
(0, 1] |
CCD steps at or below this value do not advance the collision-free state or termination progress. |
contact/al-ipc/decay_factor |
float | 0.3 |
(0, 1) |
Multiplies an inactive constraint's weight after each outer AL update. The pair is removed once the accumulated weight is below 0.01. |
per_vertex is the default because it remains stable when one scene mixes
cloth, volumetric FEM, affine bodies, and very different vertex masses.
diag_norm follows the conditioning-aware initialization in the AL-IPC paper,
but applies one uniform value to every vertex and is retained as an explicit
experimental comparison mode. Validate its trajectory and line-search status
before using it for production scenes. If its assembled diagonal norm is empty
or non-finite, the backend logs a warning and falls back to per_vertex for
that frame.
Adaptive contact resistance
| Key | Type | Default | Valid domain | Meaning |
|---|---|---|---|---|
contact/adaptive/min_kappa |
float, Pa | 1e8 (100 MPa) |
> 0 |
Lower fallback bound and the effective default resistance when the user never calls default_model(...). |
contact/adaptive/init_kappa |
float, Pa | 1e9 (1 GPa) |
> 0 |
Initial resistance used by the adaptive-kappa strategy. |
contact/adaptive/max_kappa |
float, Pa | 1e11 (100 GPa) |
> 0 |
Upper fallback bound. Keep min <= init <= max. |
contact/adaptive/kappa_eval_scale |
float | 1e-16 |
> 0 |
Evaluation scale for the scene-adaptive kappa corridor. This is an expert parameter; keep the default unless reproducing a calibrated method. |
If a user explicitly sets a non-negative default contact resistance, the
backend clamps it into [min_kappa, max_kappa] and reports the range. A
negative resistance is the explicit opt-in marker for adaptive kappa and is
not clamped. When a scene-derived corridor is computable, it takes precedence
over the configured fallback bounds.
Collision detection, validation, differentiation, and diagnostics
| Key | Type | Default | Valid domain / choices | Meaning |
|---|---|---|---|---|
collision_detection/method |
string | "info_stackless_bvh" |
"info_stackless_bvh"; optionally "info_stackless_bvh_v0", "stackless_bvh", "linear_bvh" |
Broad-phase trajectory filter. Keep the default unless benchmarking or diagnosing the broad phase. |
sanity_check/enable |
flag | 1 |
0, 1 |
Runs pre-initialization intersection and distance checks. A failed check makes the world invalid. |
sanity_check/mode |
string | "normal" |
"normal", "quiet" |
normal also writes diagnostic geometry when a check fails; quiet reports the failure without exporting that geometry. |
diff_sim/enable |
flag | 0 |
0, 1 |
Initializes differentiable-simulation state. Calling non-const scene.diff_sim() sets this flag automatically; do so before world initialization. |
extras/debug/dump_surface |
flag | 0 |
0, 1 |
Dumps intermediate surface state during the nonlinear solve. Produces substantial output. |
extras/debug/dump_linear_system |
flag | 0 |
0, 1 |
Dumps assembled global linear systems for diagnosis. |
extras/debug/dump_linear_pcg |
flag | 0 |
0, 1 |
Dumps PCG vectors for linear_pcg. fused_pcg warns and ignores this option. |
extras/debug/dump_mas_matrices |
flag | 0 |
0, 1 |
Dumps MAS matrices when the MAS FEM preconditioner is active. |
extras/strict_mode/enable |
flag | 0 |
0, 1 |
Converts nonlinear/line-search limit warnings into engine errors. Recommended for automated validation, not exploratory tuning. |
The three alternate collision selectors are compiled only when
UIPC_WITH_CUDA_LEGACY_COLLISION=ON (CMake, the default) or
cuda_legacy_collision=true (XMake). Builds with the option disabled omit the
filter implementations and remove their names from the schema enum, so scene
construction rejects a serialized or manually edited unavailable selector.
The machine-readable entry exposes this state in conditionalValues.
Effective-value precedence
Three pairs of absolute/relative controls follow the same pattern. Let L be
the diagonal of the rest-scene bounding box:
| Effective quantity | Rule |
|---|---|
| Newton velocity tolerance | velocity_tol_relative > 0 ? velocity_tol_relative * L : velocity_tol |
| Contact activation distance | d_hat_relative > 0 ? d_hat_relative * L : d_hat |
| Friction transition velocity | eps_velocity_relative > 0 ? eps_velocity_relative * L : eps_velocity |
Relative controls are useful when the same scene recipe is run at different scales. Absolute controls are easier to reason about when mesh units are known and stable. Do not enable both with the expectation that they are added: a positive relative value overrides the absolute value.
Source map
For audits and future documentation updates, the main implementation points are:
- schema, defaults, and unknown-key rejection:
src/core/core/scene_default_config.cpp - scene construction and mutable config attributes:
src/core/core/scene.cpp - backend initialization and cached values:
src/backends/cuda/engine/sim_engine_do_init.cu - relative tolerances:
max_translation_checker.cuandglobal_contact_manager.cu - solver modes:
linear_fused_pcg.cu