Table des matières
Language / Langue : FR | EN
Lists, collections and loops
Since 4.17, YAML scenarios can store data in lists and collections, then loop over them. The editor provides forms for the same operations. The TXT syntax is unchanged.
Declare and read
vars: position: 0 amount: 0 vars_text: drawn_item: '' lists: bag: [key, potion, potion] party: - {name: Arthur, health: 70} - {name: Morgane, health: 95} collections: hero: {name: Arthur, health: 90}
Lists are ordered, with indices starting at 0. Collections contain named properties. Both can contain other lists and collections; simple values are strings or integers, without booleans, decimals or null.
text: 't_hero.name_t : v_hero.health_v HP; first item: t_bag[0]_t'
v_…_v reads a number and t_…_t reads text. A variable index looks like party[v_position_v].health. A path must point to an existing simple value: t_hero_t cannot display a whole record. Dots and brackets belong to paths, not property names.
Change a list
In an action or event's do::
do: - hero.health + 10 - {list: bag, append: potion} - {list: bag, remove: potion} - {list: bag, remove: potion, occurrences: all} - {list: party, remove_index: 0} - amount = count(bag)
append also accepts a record, such as {name: Merlin, health: 80}. remove removes the first match, or all matches with occurrences: all. Use an index to remove a record.
count(bag) returns the length; count(bag, “potion”) counts matching values. Counting, removal and search compare text representations: 10 and “10” match, but “010” is different. Use a loop and a condition to find a record by one of its properties.
Pick, draw and shuffle
do: - {list: bag, choose: random, result: drawn_item} - {list: bag, shuffle: random} - list: bag draw: {value: potion} result: drawn_item text_ok: 'You take: t_drawn_item_t.' text_ko: There is no potion. - {list: bag, index_of: key, result: position}
| Operation | Result |
|---|---|
choose: random | Picks without removing. |
draw: random | Picks and removes the item. |
draw: first / last | Removes the first or last item. |
draw: {index: 2} | Removes the third item. Accepts v_position_v. |
draw: {value: potion} | Removes the first matching value. Accepts t_name_t. |
shuffle: random | Changes the order without adding or removing. |
index_of: key | Writes the first matching index, or -1; removes nothing. |
The result needs a declared simple destination of the correct type: vars_text for text, vars for numbers, or a simple property. Picks and draws cannot transfer whole records. An invalid draw leaves both the list and destination unchanged.
text_ok and text_ko are optional on list: blocks. They render after the operation and can read its result. An expected failure handled by text_ko lets do: continue; text_ko: “” handles it silently.
The failure message handles an empty pick/draw, missing removal/search value, or an out-of-range draw/removal index. A failed search still writes -1. Type, destination and budget errors remain errors. Without these fields, the usual rules apply: missing removal does nothing, missing search writes -1, impossible picks/draws and out-of-range index removals raise an error.
Sort and keep
do: - {list: party, sort: desc, by: health} - {list: party, keep: 2}
Use asc for ascending order. Omit by for simple values. Sort keys must all be numbers or all text; text uses Unicode order, sensitive to case and accents. Ties keep their previous order. keep: 0 clears the list; a count greater than its length keeps everything.
Sorting, shuffling or shortening a list being traversed, or any of its parents, is refused. Do this before or after the loop.
Iterate and repeat
do: - for_each: member in: party index: place do: - member.health + 5 - if: v_member.health_v > 100 do: member.health = 100 - text: 't_member.name_t : v_member.health_v HP' - repeat: 3 do: hero.health + 1
The member alias points to the actual item: changing it changes the list. The optional index starts at 0 and is read-only. These names exist only inside the body and must differ from other aliases and scenario variables.
Traversal follows the current list: appended items may be visited, removed items will not. An alias becomes unusable after its item is removed. Automatic events are checked after the outer loop, not between iterations.
break exits the current loop; continue skips to its next iteration. Both can be conditional. A redirect or game ending stops the loops and remaining effects of the context being left.
Bodies accept conditions, data, text and the usual media. Pauses, interactions and player commands are excluded. trigger_event:id can call a compatible manual local or global event; its conditions and state still apply, nested calls are checked and recursion is refused.
Loops also work in global actions, events, timers and triggers. Shared limits per command: 8 nesting levels, 1,000 iterations and 20,000 operations, including automatic processing. An error stops the chain; previous effects stay applied.
Display without changing data
text: - 'The party:' - for_each: member in: party do: - text: 't_member.name_t : v_member.health_v HP'
In text or a HUD, loops are read-only: text, media, conditions, styles, loops, break and continue. No effects run on redraw. Their budget is separate from commands and renewed for each render.
A list of image or sprite references can be displayed with [[grid:3:images]]: three columns, calculated rows. See Tiles and grids.
Saves and scope
| Root | Scope |
|---|---|
bag | Current game, included in its save. |
bag_p | Local storage between games; requires a stable id:. |
ranking_o | Shared online if the scenario source is authorised by the server. |
Outside authorised sources, _o stays local to the game. The root suffix decides: a health_o property inside a local collection stays local. Resuming a game does not replace current persistent values with checkpoint values. In HTML exports, _o stays local to the browser, without sharing between players.
Concurrent online writes to the same root can replace each other: the last save wins, even for different properties. Choose useful moments to write.
Models can bind lists and collections to scenario data, including a path through collections only, without list indices or copying.
See also: Shortcuts ; Data in the editor.
Descriptions and tags
Descriptions are separate from values, in data_info::
collections: hero: {name: Arthur, health: 100} lists: bag: [key, rope] data_info: hero: description: The player's character. tags: [combat] hero.health: description: 'Current health: v_hero.health_v' bag[0]: description: A small iron key. tags: combat: {}
examine hero.health shows its value and description. You can also examine hero, bag or bag[0]. Roots and compound values show their descriptions; simple values also show their values. An index describes the indicated position in the list.
Tags belong to roots, not properties or indices. In a room carrying the tag, the entire list or collection returns to its initial value. With tag-before, room initialisations follow; with tag-after, tag initialisations run last. French syntax: infos_donnees, tag-avant and tag-après.
Editor forms group name, type, value and description; roots also expose tags. Renaming a root or property updates references and descriptions. Removing an element shifts subsequent index descriptions in the scenario's initial values. Large data sets use folding, pagination and search.
