-
Notifications
You must be signed in to change notification settings - Fork 113
skinning
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 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
.tganames even though sources (and the packed page) are.png— the lookup normalizes the extension on both sides. Keep writingw_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-goingskips 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, treearbo_*defaults) — the atlas must contain them for those widgets to draw.
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 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=.

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.
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; leave it on and every size silently scales with window height). Title sizes and offsets come from the layer block (title_font_size et al.); only layer0 (root windows) renders a visible title band in production use — sub-layers carry rollout children whose collapsed rows are the "titlebar", so their header_h/title_font_size params are mostly latent.
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).