Facebook Twitter YouTube Frictional Games | Forum | Privacy Policy | Dev Blog | Dev Wiki | Support | Gametee


Thread Rating:
  • 3 Vote(s) - 5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Script Language Reference and Guide
Adrianis Offline
Senior Member

Posts: 620
Threads: 6
Joined: Feb 2012
Reputation: 27
#11
RE: Script Language Reference and Guide

Ohhh, ok, my mistake! So in fact, returning the string and assigning it in function 'A' is simply a waste, with no advantage... but thankfully not a problem. That's very useful to know, thank you.

I imagine I'll learn some other things that will prompt me to re-write several parts of these functions, thankfully neither of these problems require a change to the functions themselves but I'm sure there are several more ways they could be improved.

I never did encounter any bugs when using GetGlobalVarString itself as the parameter... in your tests, was there any room for the issue to have been in another part of the code? If it does become clear why that problem was happening, please do share. Though, I will test & use your method anyway, if its going to be more... 'secure', thanks for the suggestion.

I now very much look forward to reading the full article on strings as well, they seem to be far more complex beasts than I thought originally Smile

01-15-2013, 06:40 PM
Find
TheGreatCthulhu Offline
Member

Posts: 213
Threads: 10
Joined: Oct 2010
Reputation: 32
#12
RE: Script Language Reference and Guide

(01-15-2013, 06:40 PM)Adrianis Wrote: I never did encounter any bugs when using GetGlobalVarString itself as the parameter... in your tests, was there any room for the issue to have been in another part of the code? If it does become clear why that problem was happening, please do share.

Without first storing it as a string@, I get inconsistent results: sometimes it appears to work, more often it doesn't.

I do have a hunch what's this all about. Using HPL1 as a starting point for the string implementation, internally, strings are std:Confusedtring instances from Standard Template Library (STL) of C++. Basically, as you know from C, char arrays are a pain to manage, so C++ comes with a string class that does it for you. If we are to judge by the source code of HPL1, in order to support reference-type semantics (reference-counted handles) of AngelScript, the internally used string is wrapped, via a pointer, in another class, which is then exposed to the script.
Now, implementation details of STL might vary from runtime to runtime, but, what I suspect is happening is that GetGlobalVarString() is for some reason returning a reference (memory address) of the internal char buffer used by the C++ string class, so that, depending on the actual implementation of std:Confusedtring, when in certain circumstances the internal char array gets replaced by a different one (maybe more space was needed), the script's string& is left pointing to invalid memory (or something along those lines).

This also means that this bug might be hard to reproduce, but, here's the code, try it out several times, as in my tests sometimes it works, sometimes nothing is shown (as if the character codes aren't printable):
PHP Code: (Select All)
void OnEnter()
{
    
SetGlobalVarString("TestString""abcd");
    
    
ChangeString(GetGlobalVarString("TestString"));    
    
AddDebugMessage(GetGlobalVarString("TestString"), false);
}

void ChangeString(strings)
{
    
"ABCDEFGHIJKLMN";



Expanding a bit on that reveals that the script is aborted if such conditions are met:
PHP Code: (Select All)
void OnEnter()
{
    
SetGlobalVarString("TestString""abcd");
    
AddDebugMessage("start -->"false);
    
    
ChangeString(GetGlobalVarString("TestString"));    
    
AddDebugMessage(GetGlobalVarString("TestString"), false);
   
    
stringtemp GetGlobalVarString("TestString");
    
int i temp[0];
    
AddDebugMessage("char[0]: " ifalse);
    
    
AddDebugMessage("<--- end"false);
}

void ChangeString(strings)
{
    
"ABCDEFGHIJKLMN";


In case of a problem, the output ends with:
start -->

However, in my case, it's enough to just move the line

string@ temp = GetGlobalVarString("TestString");

to the top, and the string apparently gets pinned in memory, so OnEnter() always finishes successfully:
PHP Code: (Select All)
void OnEnter()
{
    
stringtemp GetGlobalVarString("TestString");
    
    
SetGlobalVarString("TestString""abcd");
    
AddDebugMessage("start -->"false);
    
    
ChangeString(GetGlobalVarString("TestString"));    
    
AddDebugMessage(GetGlobalVarString("TestString"), false);
       
    
int i temp[0];
    
AddDebugMessage("char[0]: " ifalse);
    
    
AddDebugMessage("<--- end"false);
}

void ChangeString(strings)
{
    
"ABCDEFGHIJKLMN";


The script function should have probably been implemented to return a string@, not a string&, like this:
PHP Code: (Select All)
stringGetGlobalVarString(stringvarID); 
(This post was last modified: 01-18-2013, 10:57 PM by TheGreatCthulhu.)
01-18-2013, 10:54 PM
Find
Adrianis Offline
Senior Member

Posts: 620
Threads: 6
Joined: Feb 2012
Reputation: 27
#13
RE: Script Language Reference and Guide

I tried out your tests, I think I understand from your explanation why this is happening. I changed the test around so it was using my functions to do the same thing, and sure enough, the problem you highlighted was indeed happening - so I went back to the maps I was using to test when I was writing it initially, and sure enough, the problem was there. I don't know why I didn't see it before, cause it only took a few tries before it broke in exactly the way you stated.

So I started changing various things, including updating the functions I was using to make sure they were the latest versions, but starting with replacing the way I was using the function to the way you suggested,
PHP Code: (Select All)
stringpstrArrayInput GetGlobalVarString("glostrName");
        
int inNextPos GetSetNextSpawnRandom(pstrArrayInput); 
Now, I should point out that this implementation is more complicated than the previous tests - it involves the player transporting across 2 maps, each with their own string in global.hps for positions, and the function calls are within other functions, generally timer loops, it can't just be in OnStart. After I tried the above, it all seemed to work, I tested it probably about 20/30 times, and it never failed (wheras the previous method would fail 3/4 times).

So I started writing this reply, then thought about another feature of this mechanic (getting the last position used) that I needed to test out as well, to make sure it didn't get broken - when I loaded it up again, it started failing exactly as it had before.... I checked the script files, the map, everything was exactly how I'd left it, and yet it was breaking again and very often. I'm not sure if the 'working' tests I did before were simply successful due to 'chance', it seems very unlikely given how often it was breaking beforehand. But regardless, it was still sometimes failing to print the string, I went over the scripts for both maps, made the same changes I had before using your method, still wouldn't work

I decided at that point I clearly don't know enough about how strings work in HPL2 & AS to be able to do this effectively, and was all ready to rewrite all the functions to use an altogether different method, but then I though of this far simpler - if less elegant - solution
PHP Code: (Select All)
string strArrayInput GetGlobalVarString("glostrName");
        
int inNextPos GetSetNextSpawnRandom(strArrayInput); 
        
SetGlobalVarString("glostrName"strArrayInput); 
That seems to work (I hesitate to say just 'it works' due to previous experience).

I'm very grateful to you for pointing out this quite serious flaw, hopefully in a couple of months I'll come back to this and be able to figure out WTF I was doing beforehand, and how to make your more elegant solution work for this situation.

(This post was last modified: 01-20-2013, 10:04 PM by Adrianis.)
01-20-2013, 07:39 PM
Find
TheGreatCthulhu Offline
Member

Posts: 213
Threads: 10
Joined: Oct 2010
Reputation: 32
#14
RE: Script Language Reference and Guide

Maybe that's a better way to do it after all; yeah, there's an extra string in between, but it doesn't really have any significant performance impact, so who cares.

Anyway, interesting... Another thing I noticed while doing those tests: at first, it would fail only occasionally (so that you have to go through 10-20 tries to observe it), but at some point it would start failing almost on every try, until I exit the game and then start it again. Now, while I think I have some clue as to why the effect is there in the first place, I also think there's more to it than the explanation from the previous post, since this new observation makes me suspect that, at some point, some internal data storing structure/mechanism gets broken...
01-20-2013, 10:02 PM
Find
Adrianis Offline
Senior Member

Posts: 620
Threads: 6
Joined: Feb 2012
Reputation: 27
#15
RE: Script Language Reference and Guide

(01-20-2013, 10:02 PM)TheGreatCthulhu Wrote: ...Another thing I noticed while doing those tests: at first, it would fail only occasionally (so that you have to go through 10-20 tries to observe it)...

That sounds about right, glad it wasn't just me being a moron

(01-20-2013, 10:02 PM)TheGreatCthulhu Wrote: ...suspect that, at some point, some internal data storing structure/mechanism gets broken...

If that is the case, it'll be at best very difficult, if not impossible to be sure. However, you do seem particularly determined at working out problems, so good luck if you plan on trying. I'm happy to help test, but sadly I doubt there's much more I can do to help

01-20-2013, 10:18 PM
Find
Thomas Offline
Frictional Games

Posts: 2,634
Threads: 184
Joined: Apr 2006
Reputation: 68
#16
RE: Script Language Reference and Guide

I think the problem is simply that the return value could be
const string&, otherwise it is possible to change the value and you get all kinds of strange stuff.

the easiest way to go around is to have the variable be
string sMyVariable = ...
then the value gets copied, instead of the reference (memory address) being used as the return variable.
01-29-2013, 11:18 AM
Find
TheGreatCthulhu Offline
Member

Posts: 213
Threads: 10
Joined: Oct 2010
Reputation: 32
#17
RE: Script Language Reference and Guide

Thanks. Yeah, we know - I just wanted you to be aware of this behavior and also of the ways people might be using the exposed script functions (like Adrianis did, a few posts back), so that you
guys might pottentially take this into account when designing the script classes in the future (either by designin for such usage scenarios, or by preventing them).
01-29-2013, 12:09 PM
Find
TheGreatCthulhu Offline
Member

Posts: 213
Threads: 10
Joined: Oct 2010
Reputation: 32
#18
RE: Script Language Reference and Guide

Oh, BTW, it just occured to me that you misunderstood what the problem is about.
It can't be const because it is possible to change the string via a reference. That's not the problem.
(01-29-2013, 11:18 AM)Thomas Wrote: I think the problem is simply that the return value could be
const string&, otherwise it is possible to change the value and you get all kinds of strange stuff.
Exactly - 'all kinds of stuff' happening is exactly how things are now, in the shipped game - it works a few times (value gets changed through a ref), but then the memory gets corrupt or something. That's what I'm trying to warn you about.

I know that this is not how the function was meant to be used, but as long as it is possible, there's a chance someone will do it - and by providing custom story/mod support, you are releasing an API of sorts to the public, so considering this sort of things becomes important.
01-29-2013, 01:18 PM
Find
Thomas Offline
Frictional Games

Posts: 2,634
Threads: 184
Joined: Apr 2006
Reputation: 68
#19
RE: Script Language Reference and Guide

Yeah affirmative!

All string return values are const refrereces for our next game. Will see if we will issues a fix for Amnesia, do not want to mess up any mods or so.
01-29-2013, 10:25 PM
Find
Acies Offline
Posting Freak

Posts: 1,643
Threads: 60
Joined: Feb 2011
Reputation: 73
#20
RE: Script Language Reference and Guide

(01-29-2013, 10:25 PM)Thomas Wrote: Yeah affirmative!



All string return values are const refrereces for our next game. Will see if we will issues a fix for Amnesia, do not want to mess up any mods or so.
Is this a hint at the possibility of porting mods to AMFP or HPL3?

[Image: mZiYnxe.png]


(This post was last modified: 01-29-2013, 10:57 PM by Acies.)
01-29-2013, 10:56 PM
Find




Users browsing this thread: 1 Guest(s)