BSL:String comparison
Summary of this page
Even though the topic is a bit convoluted, the general information is that BSL does not reliably support string comparison.
It is strongly advised to not rely on string comparison in BSL scripts.
Topic
As a lot of BSL scripters already know, BSL seemingly allows string comparison, meaning it looks like BSL should be capable of processing syntax similar to the following one:
func void some_ai_died(string ai_name){ if (ai_name eq "A_t48") { dmsg("A_t48 died!"); } else { dmsg("Some other AI died!"); } }
However, string comparison appears to be a bit unreliable - sometimes it looks like it works, sometimes it does not.
But why? The following research is an attempt to find the answer.
Test setup
A test was set in the 1st savepoint of the EnvWarehouse level.
The test comprized of:
- A test subject ("A_t48" ai2 character) and its slightly modified death function t48_dead(string ai_name).
- A global BSL string variable "BOB_string".
- A lot of wasted time while searching for all those damned addresses ^_^.
The test was set as follows:
- There is a global BSL variable "BOB_string".
Init value of the variable is a BSL string literal "A_t48".
The variable can be set via custom BSL functions to represent one of these BSL string literals: "A_t40", "A_t41", "A_t42" - There is a BSL function t48_dead(string ai_name).
The function is called by engine when the ai2 character "A_t48" dies. - Inside the BSL function t48_dead(), there is an immediate comparison of ai_name and BOB_string.
- After cca 5 seconds, BOB_string is set to be the same as ai_name and another comparison attempt is made.
Test results
Please see the enclosed series of figures. Figures show a relevant selection of Oni application runtime memory data.
- Data regarding global BSL variable BOB_string.
- Data regarding local BSL variable ai_name.
(relevant only during the execution of the t48_dead() BSL fnc) - State of runtime memory data at the moment when BSL string 'comparison' got evaluated for the first time (evaluated 'false') and for the second time (evaluated 'true').
Conclusion
- BSL string data seems to be stored as a C-style string. No additional special characters, simply a stream of bytes till the first 0x00 byte (string terminator).
- If there are several various independent strings which by chance represent a same text (e.g. "A_t48"), then engine keeps separate instances of these strings (no string grouping or any similar techniques).
- For BSL strings, the 'string' BSL datatype does not seem to be a string itself, but it more probably represents a pointer to the given C-style string.
- When BSL string 'comparison' is attempted, it in fact most probably means that the values of pointers themselves are compared (meaning the addresses are compared), not strings themselves.
- Engine allocates local BSL variables and parameters of BSL functions "on demand" and utilizes a memory area which is not exclusive for BSL strings, but is generally used for various purposes.
This point effectively means that address of a local BSL string (think ai_name) can differ based on what happened in the game prior to the string allocation request.