feature_flags - ryzom/ryzomcore GitHub Wiki
title: NeL GUI Feature Flags description: Conditional load-time sections in interface XML, so one data tree can serve multiple client builds published: true editor: markdown
Feature flags allow developers to include alternative UI descriptions in a single XML file. This is useful for having different branding between releases, as well as for hiding optional game features. The goal is multiple client builds sharing one interface tree without breaking each other. The shipped interface XMLs do not use them yet; the machinery is in place for when flavors diverge.
The CMake cache variable RYZOM_CLIENT_UI_FEATURE_FLAG sets the main feature flag baked into the client (default ryzomcore; the WITH_RYZOM_LIVE preset switches it to ryzomforge; ryzomclassic is the other conventional value). It is not yet exposed through the quick-start configurator; set it as a CMake option on manual builds.
At runtime the flag becomes the default content of the UiFeatureFlags string array in the client config, which can be overridden in client.cfg for development and testing. In general, for production, using the compile-time variable is advised to avoid unnecessary repository branches. This variable must not go in client_default.cfg, only in client.cfg. Before each interface parse the client clears the parser's flag set and adds every entry of UiFeatureFlags.
In login_config.xml, outgame_config.xml, or config.xml, add subfeature flags as needed in the following format. Flags are sticky across parsing (a <flag> set in an early file is visible in every later file until changed), so reset them explicitly if a section must not leak:
<if flags="ryzomforge" />
<flag name="contexticons" value="true" />
<elseif flags="ryzomclassic" />
<flag name="contexticons" value="false" />
<endif /><flag name="X"/> with the value attribute omitted sets the flag; value="false" clears it.
The <if />, <elseif />, <else />, and <endif /> XML tags are defined for use with feature flags. They are flat, self-closing markers between siblings, not nesting containers: the conditional region runs from one marker to the next. Expressions support !, &, |, parentheses and the literals true/false; an unset flag name evaluates false. It is recommended to use subfeature flags where possible, and the main feature flag only for branding adjustments.
contexticons | (!ryzomcore & ryzomclassic)All sibling XML nodes, and their child nodes, that fall within disabled blocks are dropped entirely by the interface parser.
Flag resolution is the first transform the parser runs on each node, before %define expansion and style merging, and it recurses to every depth, so conditional sections work inside groups and templates, not only at file level. The markers and <flag> elements are consumed during preprocessing (they never reach element parsing); nodes in false branches are unlinked and freed. Blocks nest up to 16 levels; flag names are capped at 64 characters; an unbalanced <endif/> logs a warning.
Standalone embedders seed the set through the parser API before parsing: clearFeatureFlags() / addFeatureFlag(name) (CInterfaceParser, see Embedding NeL GUI).
<if flags="ryzomclassic" />
<ctrl type="button" button_type="push_button" id="but_quit" posref="TR TR" x="-30" y="-30"
tx_normal="quit_over.tga" tx_over="quit_over.tga" tx_pushed="quit_over.tga"
color="255 255 255 0" col_over="255 255 255 255" col_pushed="255 255 255 0"
onclick_l="login_quit" />
<else />
<ctrl style="log_button" id="but_exit" posparent="windows" posref="BR BR" y="6"
onclick_l="login_quit" hardtext="uiExitLogin" />
<endif />