Skip to content

skinning

Jan Boon edited this page Jul 24, 2026 · 5 revisions

title: Skinning and Textures description: The interface atlas, container layer skins, loose textures and fonts published: true editor: markdown

Interface graphics come from a texture atlas packed at build time, and widgets find their skin either through direct texture attributes (tx_normal="w_button.tga") or through named options blocks that map skin roles to texture names.

The atlas

The build_interface tool packs a directory of individual images into one atlas page plus a .txt index of sub-rectangles; the view renderer loads both (loadTextures("gui_sample_atlas.png", "gui_sample_atlas.txt", …)). Widgets then reference entries by original filename.

  • Interface XML uses the canonical .tga names even though sources (and the packed page) are .png; the lookup normalizes the extension on both sides. Keep writing w_slot_item.tga.
  • The Ryzom interface sources live in the ryzomcore_graphics repository (interfaces/v3/); the widget sample packs its atlas from there at build time. build_interface --keep-going skips unloadable inputs (e.g. unmaterialized git-lfs pointers) instead of aborting.
  • Several widget families hard-code their texture names (gauge slots/fills w_jauge_*, digit "figur" textures, tree arbo_* defaults); the atlas must contain them for those widgets to draw.

Loose textures

Anything that needs pixel access reads a loose file, not an atlas entry: the color picker samples its palette bitmap directly. Stage such files next to the atlas on the search path; if sources are .png while XML says .tga, register the extension remap (CPath::remapExtension("png", "tga", true)) before indexing search paths (see Embedding).

Container layer skins

Container windows draw themselves entirely from a layer options block. Free windows use layer0; docked children pick layer1/layer2/… by nesting depth (see rollouts), overridable per window with options=.

Nested rollout containers: each docking depth pulls the next layer block's frame set

A layer block names, per role: the 3×3 frame (tx_tl tx_t tx_tr tx_l tx_blank tx_r tx_bl tx_b tx_br), the header band (tx_l_header tx_m_header tx_r_header, header_h), highlight overlays (tx_*_highlight), the open-rollout pieces (tx_bl_open tx_b_open tx_br_open, the left rail tx_m_open, the floating ending strip tx_el_open tx_em_open tx_er_open), the child-list scrollbar (scrollbar_tx_b/m/t, scrollbar_offset_x, scrollbar_size_w), per-piece tiling flags (tile_*), and the corner-button/help-button/open-arrow textures and offsets (right_button_tx_*, help_button_tx*, open_state_tx_*), plus title metrics (title_offset_x/y, title_offset_openable_x/y, title_font_size).

Two skin generations exist in the data:

  • the legacy w_ skin: the original beveled look, which the widget sample runs;
  • the shipped skin_ set, which replaced it name-for-name.

They differ structurally in one place: with a rollout list open, the original layout stops the frame below the header and content and lets the open-section pieces (m_open rail + ending strip) carry the child list, leaving the right edge genuinely open; the shipped skins instead stretch the full frame over the whole list and patch the right edge with a repeated texture. The layer option frame_covers_open_list (default true = shipped behavior) selects between them; the sample's w_ layer blocks set it false.

Two more fixed-name blocks are mandatory for containers: container_move_opt (mover strip and resizer metrics; its absence crashes the first layout pass, see the warning) and container_insertion_opt (drag-reorder arrows). Modal frames read the block named by their options= (skin_modal in the shipped data); menus additionally use menu_checkbox for checkable items.

Fonts and metrics

One font file serves the whole interface (the embedder creates the text context with it). Ryzom shipped ingame.ttf in beta and basic.ttf later.

fontsize means pixels only if the text context's 800×600 ratio scaling is off (setKeep800x600Ratio(false); the client does this, and leaving it on scales every size silently with window height). Title sizes and offsets come from the layer block (title_font_size et al.). Only layer0 (root windows) draws an actual title band. At deeper layers each rollout child's collapsed row plays the role of the titlebar, so header_h/title_font_size there set the collapsed-row metrics rather than a title band.

The global color (global_color attribute, on by default) modulates every element by an interface-wide tint the application controls; skin textures that must stay unmodulated set global_color="false". Per-window content/container alphas ride the UI:SAVE:*ALPHA database entries (declare them or everything renders transparent).

Clone this wiki locally