textSubStr Confusion

I was just playing around with the textSubStr function, and I noticed some behavior that doesn't seem correct.

I have an actor with a self text attribute called "text" that is initialized to 123456.

The actor has two displayText behaviors:

display text: textSubStr(self.text, 0, 5)

This displays 123456.

display text : textSubStr(self.text, 1, 5)

This displays 12345.

What the heck is going on? How can both of the displays start with 1?

Comments

  • ArmellineArmelline Member, PRO Posts: 5,358

    textSubStr isn't really intended to be used with the 0th character of a string. What it seems to do is just add 1 to both numbers when a 0 is used. So instead of textSubStr(self.text,0,5) you're getting textSubStr(self.text,1,6).

    What you seem to want is to be starting at the 1st character in the first example and the 2nd character in the second example:

    textSubStr(self.text,1,5)
    testSubStr(self.text,2,5)

    The first would result in 12345
    The second would result in 2345

    The first number you provide is the first character that will displayed, the second number the second character.

  • tmanntmann Member Posts: 278

    seems a bit fruity - I thought textSubStr was zero based anyway. But there is basically some kind of bug 0,3 gives the first FOUR characters as I would expect and 1,3 gives the first THREE. So it seems it can be kicked into a zero based way of thinking.

  • ArmellineArmelline Member, PRO Posts: 5,358

    textSubStr does not expect to encounter 0s. It's presumably essentially string.sub from Lua. In Lua you can provide a negative which then refers to the end of the string.

    GameSalad's implementation doesn't support negatives, but it does seem to pad the values you give it until both are positive numbers. 0,1 will give the first two characters (1,2). -1,1 will give the first three characters (1,3) etc.

  • ArmellineArmelline Member, PRO Posts: 5,358
    edited December 2015

    For more fun, you can actually hook into string.sub giving some cool advantages over textSubString:

    self.String:sub(x) will provide the full string. If you don't give a second value, it will assume you mean the string length. So if I have the following string:

    123456

    And I use sub(3), I'll get 3456 as the result. This saves you from having to do textSubStr(3,textLength(string)).

    If you want to count from the end of a string, you can. So sub(3,-1) will count from the final character in the string to the 3rd - so the result would be 3456. -2 will count from the second to last. So sub(3,-2) would give 345.

  • tatiangtatiang Member, Sous Chef, PRO, Senior Sous-Chef Posts: 11,949

    This states that Lua strings are indexed starting at 1, not 0:

    http://lua-users.org/wiki/StringLibraryTutorial

    New to GameSalad? (FAQs)   |   Tutorials   |   Templates   |   Greenleaf Games   |   Educator & Certified GameSalad User

  • tmanntmann Member Posts: 278

    @Armelline oh :) so padding is administered equally ? 0,3 becomes 1,4

  • ArmellineArmelline Member, PRO Posts: 5,358

    @tmann That appears to be the case when using textSubString, yes. You get tons more options with sub though!

  • ArmellineArmelline Member, PRO Posts: 5,358

    Is there any interest in a quick video about the hidden string manipulation capabilities of GameSalad? Things like...

    • Display a substring starting from the end of a string
    • Replace a specific number of instances of a search term
    • Replace all letters, or all numbers, or all capitals etc.
    • Replace all words
    • Replace ranges or sets of characters (i.e. replace all instances of A and B and C from a string)
    • Check if a string starts or ends in a specific character/type of character

    There's nearly the full power of Lua's string manipulation available to us.

  • tmanntmann Member Posts: 278

    @Armelline given the current state of the documentation I would say absolutely yes :)

  • GeorgeGSGeorgeGS Member, PRO Posts: 478

    Keep in mind that textSubString is utf8 aware and the built in lua string functions are not. Depending on the content of your strings, the built in functions can do the completely wrong thing if you aren't careful.

    textSubString isn't too complicated, but it does expect your indices to be 1 based.

    The parameters in the code are treated as a start index and end index inclusive, so textSubStr(1, 2) gives you two characters as expected, but textSubStr(0, 2) gives you three characters.

    The reason is the number of characters to be extracted is endIndex - startIndex + 1, so 0 for the first parameter gives you an extra character because 2 - 1 + 1 = 2 and 2 - 0 + 1 = 3. If the first index is < 1 then the whole range is shifted so that the extraction starts at the first character.

    Hope that helps a little. :)

  • ArmellineArmelline Member, PRO Posts: 5,358

    Interesting!

    @GeorgeGS said:
    Keep in mind that textSubString is utf8 aware and the built in lua string functions are not. Depending on the content of your strings, the built in functions can do the completely wrong thing if you aren't careful.

    If they work in creator, can they reasonably be expected to work on device?

  • GeorgeGSGeorgeGS Member, PRO Posts: 478

    @Armelline said:
    Interesting!

    @GeorgeGS said:
    Keep in mind that textSubString is utf8 aware and the built in lua string functions are not. Depending on the content of your strings, the built in functions can do the completely wrong thing if you aren't careful.

    If they work in creator, can they reasonably be expected to work on device?

    The engine is the same, so I would expect the same results. If you're not using characters that would span multiple bytes when converted to utf8 you shouldn't have any issues.

  • RainbrosRainbros Member Posts: 124
    edited December 2015

    @Armelline Thanks for your answers and yes a video would be great! I'm specifically looking for a way to remove/replace the nth index of a string.

    Another thing that I found odd, why is it that when you put numbers into a text attribute, you can still perform arithmetic operations on them as if they were a number attribute? Shouldn't you be unable to do that if it's a string?

  • tatiangtatiang Member, Sous Chef, PRO, Senior Sous-Chef Posts: 11,949
    edited December 2015

    @Rainbros said:
    I'm specifically looking for a way to remove/replace the nth index of a string.

    Here's a demo that replaces the nth index of a string. To remove the nth index, make game.replacementChar a blank string. Let me know if you have any questions.

    New to GameSalad? (FAQs)   |   Tutorials   |   Templates   |   Greenleaf Games   |   Educator & Certified GameSalad User

  • ArmellineArmelline Member, PRO Posts: 5,358

    @Rainbros said:
    @Armelline Thanks for your answers and yes a video would be great! I'm specifically looking for a way to remove/replace the nth index of a string.

    @tatiang already has you covered there, by the looks of it, so I'll not redo that!

    Another thing that I found odd, why is it that when you put numbers into a text attribute, you can still perform arithmetic operations on them as if they were a number attribute? Shouldn't you be unable to do that if it's a string?

    This is to be expected. Most programming languages allow you to treat a string of numbers as a string. Unfortunately it doesn't work the other way, though - you can't directly manipulate an integer with string functions.

  • RainbrosRainbros Member Posts: 124
    edited December 2015

    @Armelline said:

    This is to be expected. Most programming languages allow you to treat a string of numbers as a string. Unfortunately it doesn't work the other way, though - you can't directly manipulate an integer with string functions.

    I assume you mean " a string of numbers as a number"...?

    Also thanks @tatiang, that's perfect.

  • ArmellineArmelline Member, PRO Posts: 5,358

    @Rainbros said:
    I assume you mean " a string of numbers as a number"...?

    Oops, yes! Well spotted!

  • Rogue AnvilRogue Anvil Member, PRO Posts: 30
    edited April 2018

    Necroing this post as I have a related problem.

    I am using text substring to make sure only some characters (in my example 12) are shown in my input field -but as my app is sending the whole string (not just what is dispayed) to the backend, when I pull the data back in to the app, through a Loop over table, the whole string is there ie. 16 characters or whatever the user put in.

    Is there a way to limit the data entry / submission of characters to 12, not just the display of characters?

  • ArmellineArmelline Member, PRO Posts: 5,358

    @Rogue Anvil You can put your input buttons in a rule that says "If textLength(game.Input) <= 12 then allow button press".

    That way the buttons will stop being active and allowing input when your maximum length is reached.

  • tatiangtatiang Member, Sous Chef, PRO, Senior Sous-Chef Posts: 11,949
    edited April 2018

    @Armelline's suggestion is a good one. Another way would be to truncate the attribute value after it's entered:

    Change attribute game.Input to textSubStr(game.Input,1,12).

    New to GameSalad? (FAQs)   |   Tutorials   |   Templates   |   Greenleaf Games   |   Educator & Certified GameSalad User

  • Rogue AnvilRogue Anvil Member, PRO Posts: 30

    @Armelline - cool fix I like your thinking!
    @tatiang am a bit new to GS - where exactly would you have me implement your solution?

  • tatiangtatiang Member, Sous Chef, PRO, Senior Sous-Chef Posts: 11,949
    edited April 2018

    where exactly would you have me implement your solution?

    Right after the user inputs the value. So something like this:

    [user inputs value e.g. with Keyboard Input or custom keyboard buttons]
    Change attribute game.Input to textSubStr(game.Input,1,12).

    I'd have to see your rules or pseudocode to know how you've set this up but that's the general order of things.

    New to GameSalad? (FAQs)   |   Tutorials   |   Templates   |   Greenleaf Games   |   Educator & Certified GameSalad User

  • tatiangtatiang Member, Sous Chef, PRO, Senior Sous-Chef Posts: 11,949
    edited April 2018

    Here's a quick demo. Click the white square, then enter a phrase (e.g. "The quick brown fox jumps over a lazy dog.") and click Done. The truncated result will be displayed.

    New to GameSalad? (FAQs)   |   Tutorials   |   Templates   |   Greenleaf Games   |   Educator & Certified GameSalad User

  • Rogue AnvilRogue Anvil Member, PRO Posts: 30
    edited April 2018

    So I tried this... I also tried using the substr in the rule that changes the old saved name, but didn't work either.

    Can you see anything from this?

  • Rogue AnvilRogue Anvil Member, PRO Posts: 30
    edited April 2018

    Never mind :) I got it to work by looking into your example and forcing the attribute change when clicking the submit button. Thanks for the help!

Sign In or Register to comment.