Show pageOld revisionsBacklinksBack to top This page is read only. You can view the source, but not change it. Ask your administrator if you think this is wrong. {{indexmenu_n>25}} ====== Composite Codes ====== A **composite code** is a final level code assembled from several parts scattered across codes, bonuses, global bonuses and hints. As soon as the team collects every part, the engine submits the assembled code for the players automatically. > **Important (applies to all three methods):** the final assembled code must exist on the level as a regular code (or as a bonus). Otherwise the engine keeps submitting a non-existent answer and the players' page reloads in a loop. There are three ways to implement a composite code: - **Nested templates** — every part is checked by a template on the server, and the innermost template submits the code with a script. **Recommended method.** - **A script with ''getAllParts'' / ''getAllBonuses''** — the code is assembled in the browser from answers already shown on the page. - **''code_part''** — a legacy option, kept for backward compatibility. ===== Method 1: Nested Templates (recommended) ===== [[en:authors_main:task_editor:advanced:edit_templates|Templates]] are evaluated on the server before the page is sent. Until the team has collected all the parts, the final code is present neither on the screen nor in the page source — there is no way to find it in advance. The idea: nest templates inside each other so that every nesting level checks its own part (a code, a bonus or a global bonus), and the innermost template submits the final code with a script. Example: the code is assembled from the 1st level code, the 2nd bonus and the 5th global bonus. <code HTML> {% match code_1 }:{ {%= crocodile}:{ {% match bonus_2 }:{ {%= hippo}:{ {% match gbonus_5 }:{ {%= boar}:{ <script>enter('ZOO')</script> %} %} %} %} %} %} </code> A branch fires only on an exact answer match, so the nested templates expand down to ''<script>enter('ZOO')</script>'' only when all three parts have been submitted. If a part has not been answered yet, its template returns nothing and the templates nested inside it are not evaluated at all. ==== When only the fact of an answer matters ==== If a part has several synonyms and you only need to know whether it is solved, use the **''!any_answer!''** branch — it matches any submitted answer but, unlike ''?'', does not match when there is no answer yet. The nesting stays exactly the same, only each level now holds ''!any_answer!'' instead of a specific answer: <code HTML> {% match code_1 }:{ {%= !any_answer!}:{ {% match bonus_2 }:{ {%= !any_answer!}:{ {% match gbonus_5 }:{ {%= !any_answer!}:{ <script>enter('ZOO')</script> %} %} %} %} %} %} </code> > **Important:** do not use ''?'' in place of ''!any_answer!'' — it matches any value, **including ''!no_answer!''**, so the code would be submitted too early. Both styles can be mixed inside one nest: use a specific value for a part that has a single answer, and ''!any_answer!'' for a part with synonyms. ==== Different final codes for different combinations ==== Templates compare the actual answer value, so the final code may depend on which synonym closed each part: just add several branches with different ''enter()'' calls. This is how you build "branching" composite codes that cannot be produced by simply concatenating the parts. ==== Where to put it ==== * In the **task text** (Source mode) — as in the examples above. * In the **"Task"** field of the very bonus that this composite code closes — the best option when the composite code is worth a bonus. The bonus task text is only shown until the correct answer is submitted, so once the bonus is solved the template is no longer evaluated. * In the **"Task Script"** field — in that case comment out the template service lines with a double slash so the code editor does not complain about the syntax (see [[en:authors_main:task_editor:advanced:edit_templates#templates_inside_javascript|Templates inside JavaScript]]): <code JavaScript> // {% match code_1}:{ {%= crocodile}:{ // {% match bonus_2}:{ {%= hippo}:{ enter('ZOO'); // %} %} // %} %} </code> What can be checked: ''code_N'', ''bonus_N'', ''gbonus_N'' (and also ''code_first_N'', ''bonus_first_N'', ''gbonus_first_N'' — the very first answer submitted). Global bonuses can be checked even on levels where they are not displayed. See the [[en:authors_main:task_editor:advanced:edit_templates|Templates]] page for the full list of parameters. ===== Method 2: A Script with getAllParts / getAllBonuses ===== These functions assemble the final code from the answers already displayed on the page. <code JavaScript> // Concatenates the answers in the order of the arguments enter(getAllParts('c1', 'b2', 'gb5')); </code> * **''getAllParts(...)''** — accepts the ids of the elements where the engine displays submitted answers: * ''c1'', ''c2'', … — level codes; * ''b1'', ''b2'', … — level bonuses; * ''gb1'', ''gb2'', … — global bonuses. * The parts are concatenated **in the order of the arguments**, not in the order they appear on the screen. * If at least one part has not been submitted yet, the function returns an empty string. There is no need to check the result: the engine neither counts nor logs an empty answer, so ''enter()'' simply does nothing with it. If all the parts sit in a consecutive range of bonuses, there is a shorter form: <code JavaScript> // Concatenates the answers of bonuses 1 to 4: the same as getAllParts('b1','b2','b3','b4') enter(getAllBonuses(1, 4)); </code> Put the script into the **"Task Script"** field; it runs on every level refresh. There is no risk of repeated submissions: ''enter()'' submits a code only once. Keep in mind that what gets concatenated is **the answer the team submitted**. If a part has synonyms, different teams end up with different final strings — either register every possible variant of the final code, or use method 1. ===== Method 3: code_part (legacy) ===== The parts are written into the task text or into the solution text of bonuses and penalty hints (in Source mode): <code HTML> <script>code_part(composite_code_number, 'code_part_string', total_composite_parts)</script> </code> * **''composite_code_number''** — the index of the composite code if the level has several of them (if there is only one, use ''0''). * **'''code_part_string'''** — the code fragment as a string, always quoted (even if it is a number). * **''total_composite_parts''** — how many parts have to be collected in total. As soon as that many parts are present on the page, the engine submits the concatenated code. What is specific about this method: * The parts are concatenated **in the order the ''code_part'' calls run**, that is, in the order the blocks are rendered on the page: the task text first, then hints, then bonuses, then global bonuses. You cannot define your own order — reordering the bonuses changes the final code. * There is no need to list where the parts come from: the engine collects every ''code_part'' with the same number that ends up on the page. Parts can be scattered freely across hints and bonuses without keeping track of their numbers. * The fragment is defined by the author, so it does not depend on which synonym closed the bonus or the hint (unlike method 2). On the other hand, a specific synonym cannot be taken into account either — that requires method 1. * The total number of parts is passed in every call, so changing that number means editing every part at once. * The code fragments are visible in the page source as soon as the bonus/hint is revealed. ===== Which one to choose ===== ^ Method ^ Evaluated ^ Order of parts ^ When to use ^ | Nested templates | On the server | Defined by the author | The most universal method: works with synonyms and never reveals the final code in advance. It also takes the most typing — the nest is convenient to generate with AI | | ''getAllParts'' / ''getAllBonuses'' | In the browser | Defined by the author (argument order) | The least typing, but a poor fit when the parts have answer synonyms | | ''code_part'' | In the browser | Order of appearance on the page | Works with synonyms, but the script has to be written by hand into every part | For method 1, a long nest of templates is convenient to generate with a neural network — see [[en:authors_main:task_editor:ai_authoring|Task Editing and Generation using AI]]. en/authors_main/task_editor/advanced/composite_codes.txt Last modified: 2026/08/06 09:42(external edit)