Difference between revisions of "Message"

From AGI Wiki
Jump to navigationJump to search
Line 1: Line 1:
 
A '''message''' is a string of text that is used by commands like [[Print|print]] to give the user information. Each [[Logic|logic resource]] can contain up to 255 messages, with message numbers starting from 1 and going to 255. A message can also be as long as you like; however, there are practical limitations to this. See the [[Message too verbose error|message too verbose error]]. Messages can be defined implicitly or explicitly. An explicit message definition uses the <code>#message</code> command:
 
A '''message''' is a string of text that is used by commands like [[Print|print]] to give the user information. Each [[Logic|logic resource]] can contain up to 255 messages, with message numbers starting from 1 and going to 255. A message can also be as long as you like; however, there are practical limitations to this. See the [[Message too verbose error|message too verbose error]]. Messages can be defined implicitly or explicitly. An explicit message definition uses the <code>#message</code> command:
 +
 
<div class="CodeBlockHeader">Code:</div>
 
<div class="CodeBlockHeader">Code:</div>
<div class="CodeBlockStyle">
 
 
<syntaxhighlight lang="agi">
 
<syntaxhighlight lang="agi">
 
#message 2 "He's not here."
 
#message 2 "He's not here."
</syntaxhighlight></div>
+
</syntaxhighlight>
 +
 
 
This sets the text of message 2, or <code>m2</code>, to "He's not here." Messages are implicitly defined when they do not appear in any <code>#message</code> command but do appear within a print command:
 
This sets the text of message 2, or <code>m2</code>, to "He's not here." Messages are implicitly defined when they do not appear in any <code>#message</code> command but do appear within a print command:
 +
 
<div class="CodeBlockHeader">Code:</div>
 
<div class="CodeBlockHeader">Code:</div>
<div class="CodeBlockStyle">
 
 
<syntaxhighlight lang="agi">
 
<syntaxhighlight lang="agi">
 
print("He's not here.");
 
print("He's not here.");
</syntaxhighlight></div>
+
</syntaxhighlight>
 +
 
 
When a message is implicitly defined in this manner, the compiler will essentially add a <code>#message</code> command to the logic, but it will be invisible. Although possible, it is not generally practical to find out which message number is assigned to the message. Furthermore, additional implicit assignments in the logic file can change which message number is assigned to it. If you need to know the number of a message for sure, use an explicit message definition.
 
When a message is implicitly defined in this manner, the compiler will essentially add a <code>#message</code> command to the logic, but it will be invisible. Although possible, it is not generally practical to find out which message number is assigned to the message. Furthermore, additional implicit assignments in the logic file can change which message number is assigned to it. If you need to know the number of a message for sure, use an explicit message definition.
  
 
If you use an explicit message definition such as the one shown previously, you can print the message by either duplicating the message in full or specifying the message number:
 
If you use an explicit message definition such as the one shown previously, you can print the message by either duplicating the message in full or specifying the message number:
 +
 
<div class="CodeBlockHeader">Code:</div>
 
<div class="CodeBlockHeader">Code:</div>
<div class="CodeBlockStyle">
 
 
<syntaxhighlight lang="agi">
 
<syntaxhighlight lang="agi">
 
print("He's not here.");
 
print("He's not here.");
 
print(m2);
 
print(m2);
</syntaxhighlight></div>
+
</syntaxhighlight>
 +
 
 
As you might expect, there are advantages and disadvantages to both methods of defining messages.
 
As you might expect, there are advantages and disadvantages to both methods of defining messages.
  
 +
&nbsp;
 
== Advantages of implicit message definition ==
 
== Advantages of implicit message definition ==
  
 
The main advantages of implicit message definition are that it is less code to write and that you don't have to worry about manually assigning a message number to each new message you include in your logic. Because some logics may have many, many print statements (particularly if your game is very responsive to player commands), assigning message numbers can quickly become a nuisance.
 
The main advantages of implicit message definition are that it is less code to write and that you don't have to worry about manually assigning a message number to each new message you include in your logic. Because some logics may have many, many print statements (particularly if your game is very responsive to player commands), assigning message numbers can quickly become a nuisance.
  
 +
&nbsp;
 
== Advantages of explicit message definition ==
 
== Advantages of explicit message definition ==
  
 
Explicit message definition also has some advantages, namely that it allows you to avoid duplicating code and allows you to reference the message from within another message (described shortly). Also, commands like [[print.v|print.v]] use a message number determined by the value of a [[Variable|variable]], so when using these command you sometimes need to know the numbers of certain messages.
 
Explicit message definition also has some advantages, namely that it allows you to avoid duplicating code and allows you to reference the message from within another message (described shortly). Also, commands like [[print.v|print.v]] use a message number determined by the value of a [[Variable|variable]], so when using these command you sometimes need to know the numbers of certain messages.
  
 +
&nbsp;
 
=== Message referencing ===
 
=== Message referencing ===
  
 
You can refer to one message from within another by using message referencing. This is done by including %m and then the message number within the other message. For example:
 
You can refer to one message from within another by using message referencing. This is done by including %m and then the message number within the other message. For example:
 +
 
<div class="CodeBlockHeader">Code:</div>
 
<div class="CodeBlockHeader">Code:</div>
<div class="CodeBlockStyle">
 
 
<syntaxhighlight lang="agi">
 
<syntaxhighlight lang="agi">
 
#message 2 "He's not here."
 
#message 2 "He's not here."
  
 
print("%m2 But he'll be back soon.");
 
print("%m2 But he'll be back soon.");
</syntaxhighlight></div>
+
</syntaxhighlight>
 +
 
 
The message is stored like this in the logic resource, but when the [[AGIWiki7Interpreter|interpreter]] displays it, it will replace <code>%m2</code> with message 2, so the text "He’s not here. But he’ll be back soon." will be displayed. See [[Message#Building messages|Building messages]] for more details.
 
The message is stored like this in the logic resource, but when the [[AGIWiki7Interpreter|interpreter]] displays it, it will replace <code>%m2</code> with message 2, so the text "He’s not here. But he’ll be back soon." will be displayed. See [[Message#Building messages|Building messages]] for more details.
  
=== Avoiding code duplication ===
+
&nbsp;
 +
=== Avoiding Code Duplication ===
  
 
For an example where explicitly defining a message can avoid code duplication, let's take a simple "You're not close enough." message that occurs commonly in [[AGI|AGI]] games.
 
For an example where explicitly defining a message can avoid code duplication, let's take a simple "You're not close enough." message that occurs commonly in [[AGI|AGI]] games.
 +
 
<div class="CodeBlockHeader">Code:</div>
 
<div class="CodeBlockHeader">Code:</div>
<div class="CodeBlockStyle">
 
 
<syntaxhighlight lang="agi">
 
<syntaxhighlight lang="agi">
 
if (said("get", "cat"))
 
if (said("get", "cat"))
Line 63: Line 71:
 
     }
 
     }
 
}
 
}
</syntaxhighlight></div>
+
</syntaxhighlight>
 +
 
 
Obviously here we've got some duplicate code: print("You're not close enough.");. At first glance, using explicit messages can provide a small advantage:
 
Obviously here we've got some duplicate code: print("You're not close enough.");. At first glance, using explicit messages can provide a small advantage:
 +
 
<div class="CodeBlockHeader">Code:</div>
 
<div class="CodeBlockHeader">Code:</div>
<div class="CodeBlockStyle">
 
 
<syntaxhighlight lang="agi">
 
<syntaxhighlight lang="agi">
 
if (said("get", "cat"))
 
if (said("get", "cat"))
Line 85: Line 94:
  
 
#message 1 "You're not close enough."
 
#message 1 "You're not close enough."
</syntaxhighlight></div>
+
</syntaxhighlight>
  
 
Or, using [[Defines|defines]]:
 
Or, using [[Defines|defines]]:
 +
 
<div class="CodeBlockHeader">Code:</div>
 
<div class="CodeBlockHeader">Code:</div>
<div class="CodeBlockStyle">
 
 
<syntaxhighlight lang="agi">
 
<syntaxhighlight lang="agi">
 
#define NotCloseEnough m1
 
#define NotCloseEnough m1
Line 110: Line 119:
  
 
#message 1 "You're not close enough."
 
#message 1 "You're not close enough."
</syntaxhighlight></div>
+
</syntaxhighlight>
  
 
Obviously, either example saves a few keystrokes, but it also provides another advantage. Suppose you want to change your "not close enough" message to read "You're too far away." In the original code, where the message is implicitly defined, you will have to search and replace in your code for every place where the text "You're not close enough." appears.
 
Obviously, either example saves a few keystrokes, but it also provides another advantage. Suppose you want to change your "not close enough" message to read "You're too far away." In the original code, where the message is implicitly defined, you will have to search and replace in your code for every place where the text "You're not close enough." appears.
 +
 
<div class="CodeBlockHeader">Code:</div>
 
<div class="CodeBlockHeader">Code:</div>
<div class="CodeBlockStyle">
 
 
<syntaxhighlight lang="agi">
 
<syntaxhighlight lang="agi">
 
if (said("get", "cat"))
 
if (said("get", "cat"))
Line 131: Line 140:
 
     }
 
     }
 
}
 
}
</syntaxhighlight></div>
+
</syntaxhighlight>
 +
 
 +
The danger that is not necessarily obvious here is that if you miss one or make a typo, you will accidentally create a new implicitly-defined message!
  
The danger that is not necessarily obvious here is that if you miss one or make a typo, you will accidently create a new implicitly-defined message!
 
 
<div class="CodeBlockHeader">Code:</div>
 
<div class="CodeBlockHeader">Code:</div>
<div class="CodeBlockStyle">
 
 
<syntaxhighlight lang="agi">
 
<syntaxhighlight lang="agi">
 
if (said("get", "cat"))
 
if (said("get", "cat"))
Line 154: Line 163:
 
     }
 
     }
 
}
 
}
</syntaxhighlight></div>
+
</syntaxhighlight>
 +
 
 
Using explicit message definitions allows the change to be made in just one place: the message definition.
 
Using explicit message definitions allows the change to be made in just one place: the message definition.
 +
 
<div class="CodeBlockHeader">Code:</div>
 
<div class="CodeBlockHeader">Code:</div>
<div class="CodeBlockStyle">
 
 
<syntaxhighlight lang="agi">
 
<syntaxhighlight lang="agi">
 
#define NotCloseEnough m1
 
#define NotCloseEnough m1
Line 178: Line 188:
  
 
#message 1 "You're too far away." // changed
 
#message 1 "You're too far away." // changed
</syntaxhighlight></div>
+
</syntaxhighlight>
  
== Building messages ==
+
&nbsp;
 +
== Building Messages ==
  
 
As mentioned in the [[Message#Message_referencing|Message referencing]] section, you can include messages in other messages. You can also include other things in messages:
 
As mentioned in the [[Message#Message_referencing|Message referencing]] section, you can include messages in other messages. You can also include other things in messages:
Line 208: Line 219:
 
When using <code>%v</code>, you can place a <code><nowiki>|</nowiki></code> after the number and then another number which determines the minimum number of digits for the var. For example, if you use <code>%v40|2</code> and the value of <code>v40</code> is 8, then the <code>%v40|2</code> will be replaced with 08. If the value of <code>v40</code> was 100 or more, all three digits would be displayed.
 
When using <code>%v</code>, you can place a <code><nowiki>|</nowiki></code> after the number and then another number which determines the minimum number of digits for the var. For example, if you use <code>%v40|2</code> and the value of <code>v40</code> is 8, then the <code>%v40|2</code> will be replaced with 08. If the value of <code>v40</code> was 100 or more, all three digits would be displayed.
  
 +
&nbsp;
 
=== Example ===
 
=== Example ===
 +
 
<div class="CodeBlockHeader">Code:</div>
 
<div class="CodeBlockHeader">Code:</div>
<div class="CodeBlockStyle">
 
 
<syntaxhighlight lang="agi">
 
<syntaxhighlight lang="agi">
 
v255 = 20;
 
v255 = 20;
 
print("The value of v255 is %v255.");
 
print("The value of v255 is %v255.");
</syntaxhighlight></div>
+
</syntaxhighlight>
 +
 
 
This code will print the message "The value of v255 is 20."
 
This code will print the message "The value of v255 is 20."
  
 +
&nbsp;
 
=== Advantages ===
 
=== Advantages ===
  
Line 222: Line 236:
  
 
Take the following code from logic 0 of the [[AGI Studio Template Game|AGI Studio Template Game]], which informs the player that he or she used a word that the game doesn't understand:
 
Take the following code from logic 0 of the [[AGI Studio Template Game|AGI Studio Template Game]], which informs the player that he or she used a word that the game doesn't understand:
 +
 
<div class="CodeBlockHeader">Code:</div>
 
<div class="CodeBlockHeader">Code:</div>
<div class="CodeBlockStyle">
 
 
<syntaxhighlight lang="agi">
 
<syntaxhighlight lang="agi">
if (input_recieved &&
+
if (input_received &&
 
     unknown_word_no > 0) {
 
     unknown_word_no > 0) {
   reset(input_recieved);
+
   reset(input_received);
 
   if (unknown_word_no == 1) {
 
   if (unknown_word_no == 1) {
 
     print("I don't understand \"%w1\"");
 
     print("I don't understand \"%w1\"");
Line 247: Line 261:
 
   }
 
   }
 
}
 
}
</syntaxhighlight></div>
+
</syntaxhighlight>
  
 
This code is in fact wasting a few dozen bytes of memory. Although this does not seem like much, in a programming environment like AGI where memory is a precious resource, these bytes can make a difference. When the compiler sees this code, it will generate invisible message definitions similar to the following:
 
This code is in fact wasting a few dozen bytes of memory. Although this does not seem like much, in a programming environment like AGI where memory is a precious resource, these bytes can make a difference. When the compiler sees this code, it will generate invisible message definitions similar to the following:
 +
 
<div class="CodeBlockHeader">Code:</div>
 
<div class="CodeBlockHeader">Code:</div>
<div class="CodeBlockStyle">
 
 
<syntaxhighlight lang="agi">
 
<syntaxhighlight lang="agi">
 
#message 10 "I don't understand \"%w1\""
 
#message 10 "I don't understand \"%w1\""
Line 259: Line 273:
 
#message 14 "\"%w5\" is not in my vocabulary."
 
#message 14 "\"%w5\" is not in my vocabulary."
 
#message 15 "What is \"%w6\""
 
#message 15 "What is \"%w6\""
</syntaxhighlight></div>
+
</syntaxhighlight>
 +
 
 
'''Note:''' the message numbers were chosen arbitrarily and are not necessarily the message numbers that will be generated by the compiler.
 
'''Note:''' the message numbers were chosen arbitrarily and are not necessarily the message numbers that will be generated by the compiler.
  
Line 269: Line 284:
  
 
Each of these phrases appears in two of the messages above. Using explicit message definitions we can reduce the amount of memory used, as shown below:
 
Each of these phrases appears in two of the messages above. Using explicit message definitions we can reduce the amount of memory used, as shown below:
 +
 
<div class="CodeBlockHeader">Code:</div>
 
<div class="CodeBlockHeader">Code:</div>
<div class="CodeBlockStyle">
 
 
<syntaxhighlight lang="agi">
 
<syntaxhighlight lang="agi">
if (input_recieved &&
+
if (input_received &&
 
     unknown_word_no > 0) {
 
     unknown_word_no > 0) {
   reset(input_recieved);
+
   reset(input_received);
 
   if (unknown_word_no == 1) {
 
   if (unknown_word_no == 1) {
 
     print("%g10%w1\"");
 
     print("%g10%w1\"");
Line 298: Line 313:
 
#message 11 "\" is not in my vocabulary."
 
#message 11 "\" is not in my vocabulary."
 
#message 12 "What is \""
 
#message 12 "What is \""
</syntaxhighlight></div>
+
</syntaxhighlight>
  
 
'''Note:''' this code uses <code>%g</code><var>N</var> because the messages are defined in logic 0.
 
'''Note:''' this code uses <code>%g</code><var>N</var> because the messages are defined in logic 0.
  
This code does the exact same thing as the earlier code, but it uses less memory. The obvious disadvantage here is that the code is a little less readable. Unfortunately, this trade-off is somtimes necessary. You can use [[Defines|defines]] to overcome it if you like. The advantage is that the compiler will now use something similar to the following message definitions:
+
This code does the exact same thing as the earlier code, but it uses less memory. The obvious disadvantage here is that the code is a little less readable. Unfortunately, this trade-off is sometimes necessary. You can use [[Defines|defines]] to overcome it if you like. The advantage is that the compiler will now use something similar to the following message definitions:
 +
 
 
<div class="CodeBlockHeader">Code:</div>
 
<div class="CodeBlockHeader">Code:</div>
<div class="CodeBlockStyle">
 
 
<syntaxhighlight lang="agi">
 
<syntaxhighlight lang="agi">
 
#message 10 "I don't understand \""
 
#message 10 "I don't understand \""
Line 315: Line 330:
 
#message 17 "\"%w5%g11"
 
#message 17 "\"%w5%g11"
 
#message 18 "%g12%w6\""
 
#message 18 "%g12%w6\""
</syntaxhighlight></div>
+
</syntaxhighlight>
 +
 
 
The next obvious question is how much memory this actually saves. Because the message numbers are chosen at random and do not necessarily reflect what the real message numbers would be, this figure is not necessarily exact (you will have to give or take 6 bytes):
 
The next obvious question is how much memory this actually saves. Because the message numbers are chosen at random and do not necessarily reflect what the real message numbers would be, this figure is not necessarily exact (you will have to give or take 6 bytes):
  
Line 322: Line 338:
 
* So, the total savings with this code are 31 bytes.
 
* So, the total savings with this code are 31 bytes.
  
Again, 31 bytes may not seem like much, but 31 bytes saved here and another 31 bytes saved there can add up to avoiding an [[Out of memory error|out of memory error]]. In this particular code, further memory could be saved by printing the same message any time an unknown word is encountered instead of using three different variations. Obviously, this reduces the variety of responses to unknown words, but if you are running low on memory then this might be an acceptable trade-off.
+
Again, 31 bytes may not seem like much, but 31 bytes saved here and another 31 bytes saved there can add up to avoiding an [[Out of Memory Error|out of memory error]]. In this particular code, further memory could be saved by printing the same message any time an unknown word is encountered instead of using three different variations. Obviously, this reduces the variety of responses to unknown words, but if you are running low on memory then this might be an acceptable trade-off.
  
 
'''Note:''' again, 31 bytes is not an exact figure. For technical reasons, each message adds about 3 additional bytes to the logic resource beyond the number of bytes required for the message itself (which is the same as the number of different characters in the message). So, the actual savings here are probably more along the lines of 22 bytes, give or take 6.
 
'''Note:''' again, 31 bytes is not an exact figure. For technical reasons, each message adds about 3 additional bytes to the logic resource beyond the number of bytes required for the message itself (which is the same as the number of different characters in the message). So, the actual savings here are probably more along the lines of 22 bytes, give or take 6.
  
 +
&nbsp;
 
== Sources ==
 
== Sources ==
  
 
* [[AGI Studio|AGI Studio]] help file
 
* [[AGI Studio|AGI Studio]] help file
  
 +
&nbsp;
 
== Data types ==
 
== Data types ==
  
 
{{Data Types}}
 
{{Data Types}}
 +
 +
&nbsp;
 +
 +
[[Category:Logic]]

Revision as of 22:56, 25 December 2013

A message is a string of text that is used by commands like print to give the user information. Each logic resource can contain up to 255 messages, with message numbers starting from 1 and going to 255. A message can also be as long as you like; however, there are practical limitations to this. See the message too verbose error. Messages can be defined implicitly or explicitly. An explicit message definition uses the #message command:

Code:
#message 2 "He's not here."

This sets the text of message 2, or m2, to "He's not here." Messages are implicitly defined when they do not appear in any #message command but do appear within a print command:

Code:
print("He's not here.");

When a message is implicitly defined in this manner, the compiler will essentially add a #message command to the logic, but it will be invisible. Although possible, it is not generally practical to find out which message number is assigned to the message. Furthermore, additional implicit assignments in the logic file can change which message number is assigned to it. If you need to know the number of a message for sure, use an explicit message definition.

If you use an explicit message definition such as the one shown previously, you can print the message by either duplicating the message in full or specifying the message number:

Code:
print("He's not here.");
print(m2);

As you might expect, there are advantages and disadvantages to both methods of defining messages.

 

Advantages of implicit message definition

The main advantages of implicit message definition are that it is less code to write and that you don't have to worry about manually assigning a message number to each new message you include in your logic. Because some logics may have many, many print statements (particularly if your game is very responsive to player commands), assigning message numbers can quickly become a nuisance.

 

Advantages of explicit message definition

Explicit message definition also has some advantages, namely that it allows you to avoid duplicating code and allows you to reference the message from within another message (described shortly). Also, commands like print.v use a message number determined by the value of a variable, so when using these command you sometimes need to know the numbers of certain messages.

 

Message referencing

You can refer to one message from within another by using message referencing. This is done by including %m and then the message number within the other message. For example:

Code:
#message 2 "He's not here."

print("%m2 But he'll be back soon.");

The message is stored like this in the logic resource, but when the interpreter displays it, it will replace %m2 with message 2, so the text "He’s not here. But he’ll be back soon." will be displayed. See Building messages for more details.

 

Avoiding Code Duplication

For an example where explicitly defining a message can avoid code duplication, let's take a simple "You're not close enough." message that occurs commonly in AGI games.

Code:
if (said("get", "cat"))
{
    if (!posn(ego, 20, 30, 40, 50))
    {
        print("You're not close enough.");
    }
}

if (said("get", "cup"))
{
    if (!posn(ego, 60, 60, 80, 90))
    {
        print("You're not close enough.");
    }
}

Obviously here we've got some duplicate code: print("You're not close enough.");. At first glance, using explicit messages can provide a small advantage:

Code:
if (said("get", "cat"))
{
    if (!posn(ego, 20, 30, 40, 50))
    {
        print(m1);
    }
}

if (said("get", "cup"))
{
    if (!posn(ego, 60, 60, 80, 90))
    {
        print(m1);
    }
}

#message 1 "You're not close enough."

Or, using defines:

Code:
#define NotCloseEnough m1

if (said("get", "cat"))
{
    if (!posn(ego, 20, 30, 40, 50))
    {
        print(NotCloseEnough);
    }
}

if (said("get", "cup"))
{
    if (!posn(ego, 60, 60, 80, 90))
    {
        print(NotCloseEnough);
    }
}

#message 1 "You're not close enough."

Obviously, either example saves a few keystrokes, but it also provides another advantage. Suppose you want to change your "not close enough" message to read "You're too far away." In the original code, where the message is implicitly defined, you will have to search and replace in your code for every place where the text "You're not close enough." appears.

Code:
if (said("get", "cat"))
{
    if (!posn(ego, 20, 30, 40, 50))
    {
        print("You're too far away."); // changed
    }
}

if (said("get", "cup"))
{
    if (!posn(ego, 60, 60, 80, 90))
    {
        print("You're too far away."); // changed
    }
}

The danger that is not necessarily obvious here is that if you miss one or make a typo, you will accidentally create a new implicitly-defined message!

Code:
if (said("get", "cat"))
{
    if (!posn(ego, 20, 30, 40, 50))
    {
        print("You're too far away."); // changed
    }
}

if (said("get", "cup"))
{
    if (!posn(ego, 60, 60, 80, 90))
    {
        /* OOPS!! No period at the end, so this is a new message! */

        print("You're too far away"); // changed
    }
}

Using explicit message definitions allows the change to be made in just one place: the message definition.

Code:
#define NotCloseEnough m1

if (said("get", "cat"))
{
    if (!posn(ego, 20, 30, 40, 50))
    {
        print(NotCloseEnough);
    }
}

if (said("get", "cup"))
{
    if (!posn(ego, 60, 60, 80, 90))
    {
        print(NotCloseEnough);
    }
}

#message 1 "You're too far away." // changed

 

Building Messages

As mentioned in the Message referencing section, you can include messages in other messages. You can also include other things in messages:

%vN

value of variable N

%wN

Nth word that the player typed in

%sN

String N

%mN

Message N from current logic (except logic 0)

%gN

Message N from logic 0

When using %v, you can place a | after the number and then another number which determines the minimum number of digits for the var. For example, if you use %v40|2 and the value of v40 is 8, then the %v40|2 will be replaced with 08. If the value of v40 was 100 or more, all three digits would be displayed.

 

Example

Code:
v255 = 20;
print("The value of v255 is %v255.");

This code will print the message "The value of v255 is 20."

 

Advantages

Message inclusion allows you to do things that are not otherwise possible, such as printing a number that is not known when you are creating the game. It also allows you to save considerable amounts of memory.

Take the following code from logic 0 of the AGI Studio Template Game, which informs the player that he or she used a word that the game doesn't understand:

Code:
if (input_received &&
    unknown_word_no > 0) {
  reset(input_received);
  if (unknown_word_no == 1) {
    print("I don't understand \"%w1\"");
  }
  if (unknown_word_no == 2) {
    print("\"%w2\" is not in my vocabulary.");
  }
  if (unknown_word_no == 3) {
    print("What is \"%w3\"");
  }
  if (unknown_word_no == 4) {
    print("I don't understand \"%w4\"");
  }
  if (unknown_word_no == 5) {
    print("\"%w5\" is not in my vocabulary.");
  }
  if (unknown_word_no == 6) {
    print("What is \"%w6\"");
  }
}

This code is in fact wasting a few dozen bytes of memory. Although this does not seem like much, in a programming environment like AGI where memory is a precious resource, these bytes can make a difference. When the compiler sees this code, it will generate invisible message definitions similar to the following:

Code:
#message 10 "I don't understand \"%w1\""
#message 11 "\"%w2\" is not in my vocabulary."
#message 12 "What is \"%w3\""
#message 13 "I don't understand \"%w4\""
#message 14 "\"%w5\" is not in my vocabulary."
#message 15 "What is \"%w6\""

Note: the message numbers were chosen arbitrarily and are not necessarily the message numbers that will be generated by the compiler.

Clearly, there are some parts of these messages that simply cannot be changed (the %w1, %w2, %w3, and so on, which are needed to put the unknown word that the player typed into the message), but there are also some obvious duplications here, namely:

  • "I don't understand"
  • "is not in my vocabulary"
  • "What is"

Each of these phrases appears in two of the messages above. Using explicit message definitions we can reduce the amount of memory used, as shown below:

Code:
if (input_received &&
    unknown_word_no > 0) {
  reset(input_received);
  if (unknown_word_no == 1) {
    print("%g10%w1\"");
  }
  if (unknown_word_no == 2) {
    print("\"%w2%g11");
  }
  if (unknown_word_no == 3) {
    print("%g12%w3\"");
  }
  if (unknown_word_no == 4) {
    print("%g10%w4\"");
  }
  if (unknown_word_no == 5) {
    print("\"%w5%g11");
  }
  if (unknown_word_no == 6) {
    print("%g12%w6\"");
  }
}

#message 10 "I don't understand \""
#message 11 "\" is not in my vocabulary."
#message 12 "What is \""

Note: this code uses %gN because the messages are defined in logic 0.

This code does the exact same thing as the earlier code, but it uses less memory. The obvious disadvantage here is that the code is a little less readable. Unfortunately, this trade-off is sometimes necessary. You can use defines to overcome it if you like. The advantage is that the compiler will now use something similar to the following message definitions:

Code:
#message 10 "I don't understand \""
#message 11 "\" is not in my vocabulary."
#message 12 "What is \""
#message 13 "%g10%w1\""
#message 14 "\"%w2%g11"
#message 15 "%g12%w3\""
#message 16 "%g10%w4\""
#message 17 "\"%w5%g11"
#message 18 "%g12%w6\""

The next obvious question is how much memory this actually saves. Because the message numbers are chosen at random and do not necessarily reflect what the real message numbers would be, this figure is not necessarily exact (you will have to give or take 6 bytes):

  • Avoiding the duplication of the repeated parts of the messages saves 55 bytes.
  • The %gN portion of each of the six messages uses 24 bytes.
  • So, the total savings with this code are 31 bytes.

Again, 31 bytes may not seem like much, but 31 bytes saved here and another 31 bytes saved there can add up to avoiding an out of memory error. In this particular code, further memory could be saved by printing the same message any time an unknown word is encountered instead of using three different variations. Obviously, this reduces the variety of responses to unknown words, but if you are running low on memory then this might be an acceptable trade-off.

Note: again, 31 bytes is not an exact figure. For technical reasons, each message adds about 3 additional bytes to the logic resource beyond the number of bytes required for the message itself (which is the same as the number of different characters in the message). So, the actual savings here are probably more along the lines of 22 bytes, give or take 6.

 

Sources

 

Data types