Title: Adaptive Dialog Engine Examples Author: SilentEnigma Adaptive Dialog Engine Version: 1.0 Release Date: 2021-06-01 -------------------------------------------------- TABLE OF CONTENTS 0. Adaptive Dialog Examples 1. Revision History 2. Legal ________________________________________________________________________________ 0. ADAPTIVE DIALOG EXAMPLES ________________________________________________________________________________ Contents: a. Insert name of party leader b. Insert name of actor on field map c. Specialize text based on party size d. Specialize text based on party leader e. Specialize text for second party member f. Set flag if TERRA is a visible party member g. Start new line on current page, if possible ================================================== a. Insert name of party leader ================================================== The following command inserts the name of the current party leader: $00| Breakdown: $ opens the _INSERT command 0 specifies the _get_party_member Control function 0 tells _get_party_member to return party member of rank 0 (leader) | terminates the command, inserting the party leader ================================================== b. Insert name of actor on field map ================================================== RAM address range $2000 - $5FFF gives the object occupancy of all tiles on the current field map (1 byte/tile). If a tile is empty, its byte value is #$FF. If the tile is occupied, its byte value is 2 times the object (actor) ID. Locke will be #$02, Cyan will be #$04, etc.: Name ID x2 ------ ---- ---- TERRA #$00 #$00 LOCKE #$01 #$02 CYAN #$02 #$04 SHADOW #$03 #$06 EDGAR #$04 #$08 SABIN #$05 #$0A CELES #$06 #$0C STRAGO #$07 #$0E RELM #$08 #$10 SETZER #$09 #$12 MOG #$0A #$14 GAU #$0B #$16 GOGO #$0C #$18 UMARO #$0D #$1A ------------------------------- The following command inserts the name of an actor on the field if identified at RAM address $5678: $1567802| Breakdown: $ opens the _INSERT command 1 specifies the _ram_byte_divide Control function 5678 tells _ram_byte_divide to use object byte at RAM address $5678 02 divides the tile value (if occupied) by 2 to get the actor ID | terminates the command, inserting any actor found at the specified tile ------------------------------- The following command inserts the name of an actor on the field, identified at RAM address $5678; and if that tile is empty, $59AB and $5CDE are used as fallbacks: $156780259!?025/:]02| Breakdown: $ opens the _INSERT command 1 specifies the _ram_byte_divide Control function 5678 tells _ram_byte_divide to read the object byte at RAM address $5678 02 divides the tile value (if occupied) by 2 to get the actor ID 59!? gives fallback address $59AB in case the previously given tile is empty 02 divides the tile value (if occupied) by 2 to get the actor ID 5/:] gives fallback address $5CDE in case the previously given tile is empty 02 divides the tile value (if occupied) by 2 to get the actor ID | terminates the command, inserting the first of any actors found ================================================== c. Specialize text based on party size ================================================== The following will yield different text depending on the number of characters in the active party: {3|001|I'm`We're} Breakdown: { opens the _SWITCH command 3 specifies that we are using the _get_party_size Control function | ends the Control function, passing its result to the Branch Map 0 maps party size of 0 to branch text index 0 0 maps party size of 1 to branch text index 0 1 maps party size of 2 to branch text index 1 | ends the Branch Map; party sizes > 2 use the last-defined index (1) I'm gives the text for branch 0 (party sizes less than 2) ` terminates branch 0 We're gives the text for branch 1 (party sizes 2 or greater) } terminates the _SWITCH command block ================================================== d. Specialize text based on the party leader ================================================== The following yields custom text according to the party leader: {00|00120000003425|Hi!`Hail!`__`Hi, kupo!`Uwao!`Ooga!} Breakdown: { opens the _SWITCH command 0 specifies the _get_party_member Control function 0 tells _get_party_member to return party member of rank 0 (leader) | ends the Control function, passing its result to the Branch Map 0 maps Actor 00 (TERRA ) to branch text index 0 0 maps Actor 01 (LOCKE ) to branch text index 0 1 maps Actor 02 (CYAN ) to branch text index 1 2 maps Actor 03 (SHADOW) to branch text index 2 0 maps Actor 04 (EDGAR ) to branch text index 0 0 maps Actor 05 (SABIN ) to branch text index 0 0 maps Actor 06 (CELES ) to branch text index 0 0 maps Actor 07 (STRAGO) to branch text index 0 0 maps Actor 08 (RELM ) to branch text index 0 0 maps Actor 09 (SETZER) to branch text index 0 3 maps Actor 10 (MOG ) to branch text index 3 4 maps Actor 11 (GAU ) to branch text index 4 2 maps Actor 12 (GOGO ) to branch text index 2 5 maps Actor 13 (UMARO ) to branch text index 5 | ends the Branch Map Hi! gives the text for branch 0 (TERRA, LOCKE, EDGAR - SETZER) ` terminates branch 0 Hail! gives the text for branch 1 (CYAN) ` terminates branch 1 __ gives the text for branch 2 (SHADOW, GOGO) ` terminates branch 2 Kupo! gives the text for branch 3 (MOG) ` terminates branch 3 Uwao! gives the text for branch 4 (GAU) ` terminates branch 4 Ooga! gives the text for branch 5 (UMARO) } terminates the _SWITCH command block Pseudocode Representation: switch (_get_party_member(0)) { case 0: // TERRA case 1: // LOCKE case 4: // EDGAR case 5: // SABIN case 6: // CELES case 7: // STRAGO case 8: // RELM case 9: // SETZER text += "Hi!"; break; case 2: // CYAN text += "Hail!"; break; case 3: // SHADOW case 12: // GOGO text += "......"; break; case 10: // MOG text += "Kupo!"; break; case 11: // GAU text += "Uwao!"; break; case 13: // UMARO default: text += "Ooga!"; break; } ================================================== e. Specialize text for second party member ================================================== The following adds custom text attributed to the second party member, if present, on a new line: {3|001|` $01|{01|00120|: No!`: Nay!`: No.}} Breakdown: { opens outer _SWITCH command 3 specifies the _get_party_size Control function | ends the Control function, passing its result to the outer Branch Map 0 maps party size of 0 to outer branch text index 0 (no text) 0 maps party size of 1 to outer branch text index 0 (no text) 1 maps party size of 2 to outer branch text index 1 | ends the outer Branch Map; party sizes > 2 use last-defined index (1) ` terminates outer branch 0 (no text) (\r\n) starts text of outer branch 1 on a new line (encoded in ROM as #$01) $01| inserts speaker label for the 2nd party member (rank 1) via _INSERT { opens inner _SWITCH command within outer branch 1 0 specifies the _get_party_member Control function 1 tells _get_party_member to return party member of rank 1 (2nd member) | ends the Control function, passing its result to the Branch Map 0 maps Actor 0 (TERRA ) to branch text index 0 0 maps Actor 1 (LOCKE ) to branch text index 0 1 maps Actor 2 (CYAN ) to branch text index 1 2 maps Actor 3 (SHADOW) to branch text index 2 0 maps Actor 4 (EDGAR ) to branch text index 0 | ends the inner Branch Map; Actors > 4 use last-defined index (0) : No! gives the text for branch 0 (TERRA, LOCKE, EDGAR - UMARO, etc.) ` terminates branch 0 : Nay! gives the text for branch 1 (CYAN) ` terminates branch 1 : No. gives the text for branch 2 (SHADOW) } terminates inner _SWITCH command block } terminates outer _SWITCH command block Pseudocode Representation: switch (_get_party_size()) { case 0: case 1: break; case 2: default: text += "\r\n" + _INSERT(_get_party_member(1)); switch (_get_party_member(1)) { case 2: // CYAN text += ": Nay!"; break; case 3: // SHADOW text += ": No."; break; case 0: // TERRA case 1: // LOCKE case 4: // EDGAR default: text += ": No!"; break; } } Example Outputs: ------------------------------- TERRA: No! CYAN: Nay! SHADOW: No. SETZER: No! ------------------------------- The same result can be achieved more efficiently by factoring out ": N" from the inner _SWITCH block: {3|001|` $01|: N{01|00120|o!`ay!`o.}} ================================================== f. Set flag if TERRA is in the active party ================================================== In this example, a bit in memory is checked to evaluate whether TERRA is in the active party. If the bit is set, the script branches to a command which sets another bit in memory. No text is output. Relevant memory info: SRAM bytes $1850 - $185F give "object settings" flags for each character: - $1850 = TERRA, $1851 = LOCKE, $1852 = CYAN, and so forth. - Bit #$80 is high when the character is visible. - Bit #$40 is high when the character is enabled (in the active party). SRAM bytes $1FF7 - $1FFD are available/unused in vanilla FF3us. ------------------------------- This example assumes that the low bit of $1FF7 has already been reset. This can be accomplished by using the _AND_BITS command in a prior caption: <$7A>1''7']| Breakdown: <$7A> opens the _AND_BITS command 1''7 specifies target RAM address $1FF7 '] specifies bitwise AND operand #$FE, resetting the low bit of $1FF7 | terminates the _AND_BITS command ------------------------------- The following sets the low bit of unused SRAM address $1FF7 if TERRA is in the active party: {2185040|01|`<$79>1''701|} Breakdown: { opens the _SWITCH command 2 specifies the _ram_byte_bitwise_and Control function 1850 tells _ram_byte_bitwise_and to read the byte at RAM address $1850 40 bitwise AND yields #$40 if TERRA is enabled, #$00 otherwise | ends the Control function, passing its result to the Branch Map 0 maps Control result $00 to branch text index 0 1 maps Control result $01 to branch text index 1 | ends the Branch Map; Control results > 1 use the last-defined index (1) ` terminates branch 0 (no text; branch does nothing) <$79> opens _OR_BITS command within branch 1 1''7 specifies target RAM address $1FF7 for _OR_BITS command 01 specifies bitwise OR operand #$01, setting the low bit of $1FF7 | terminates the _OR_BITS command within branch 1 } terminates the _SWITCH command block Pseudocode Representation: switch (_ram_byte_bitwise_and($1850, #$40)) { case 0: break; case 1: default: _OR_BITS($1FF7, #$01); break; } ================================================== g. Start new line on current page, if possible ================================================== While text is streaming in a dialog caption, RAM byte $00C4 indicates the general progress of the stream on the page, according to the following table: Left Side Right Side ---------- ---------- Line 0 : #$00 #$01 Line 1 : #$02 #$03 Line 2 : #$04 #$05 Line 3 : #$06 #$07 ------------------------------- The following inserts a newline if the text stream is currently on the first, second, or third line; inserts a single space otherwise. {100/402|0001| ` } Breakdown: { opens the _SWITCH command 1 specifies _ram_byte_divide Control function 00/4 tells _ram_byte_divide to read the byte at RAM address $00C4 02 divides the byte value at $00C4 by 2 to get the current line index | ends the Control function, passing its result to the Branch Map 0 maps Line 0 to branch text index 0 0 maps Line 1 to branch text index 0 0 maps Line 2 to branch text index 0 1 maps Line 3 to branch text index 1 | ends the Branch Map (\r\n) reads a newline (encoded in ROM as #$01) for branch 0 ` terminates branch 0 " " reads a space character (encoded in ROM as #$7F) for branch 1 } terminates the _SWITCH command block ________________________________________________________________________________ 1. REVISION HISTORY ________________________________________________________________________________ 2021-06-01 : Version 1.0 released. ________________________________________________________________________________ 2. LEGAL ________________________________________________________________________________ Adaptive Dialog Engine Copyright (C) 2021 David R. Thompson (SilentEnigma).