Legacy GM are arguments read-only?

I

itameio

Guest
i'm trying to shorten functions in GML by including them in scripts and then calling that script instead of the function itself, example :

script "d" {
instance_deactivate_object(argument0)
}

this is called in an object like{ d(self) } for example, to make it deactivate itself.

but when I tried writing a script called "limit" which goes like this :

script "limit" {
if argument0>argument1{argument0=argument1}
}

to use it to limit variables and constants such as speed for example { limit(speed,20) }, it doesn't work.

after testing the code in different ways I realized the only part that does not work is argument0=argument1 which if changed to speed=argument1 works fine. so my impression was that arguments are read-only, but the help documents doesn't say anything like that, so if they are not read-only then am I doing something wrong?
 
Last edited by a moderator:

TsukaYuriko

☄️
Forum Staff
Moderator
They are not read-only. However, you seem to be assuming that variables passed into arguments are passed by reference (or that variables can be passed by reference at all). This is not the case. They are passed by value.

Treat argument variables like any other variable. By calling a script, you set them to a value. If you set them to a different value inside of the script, the corresponding variable will hold the new value... but that variable has zero to do with the variable you used to pass a value to the argument in the first place.

Edit: Ninja mod Tsuk strikes back! :p YOU HEAR THIS, BIKKIE?!
 

geky

Member
If you need variable to stay within a certain limit, an easy way is to clamp it:
Code:
speed = clamp( speed, minimum, maximum );
Arguments are not read only, but you need to return it to the calling instance:
Code:
instance calling script:
speed = limit( speed, 20 )

script:
if argument0>argument1{argument0=argument1}
return argument0;
 

Yal

🐧 *penguin noises*
GMC Elder
From my experiences, arguments are read-and-write, but they're call-by-value instead of call-by-reference. Changing argument0 just changes argument0 and nothing else. If you used speed, direction, or 162.5 for that argument when calling the script doesn't matter; argument0 is just a value when the script gets access to it.
 

Hyomoto

Member
A couple of the answers here make sense, but are written in a confusing way, so in case you feel the same way, here's a bit of clarification:
When you type:
Code:
limit( speed, 20 )
The variables are passed, by value, into the script you defined as 'argument':
Code:
if argument0 > argument1 { argument0 = argument1 }
However, this has no bearing on the initial values. argument0 is not 'speed', it is only equal to the value of speed. So what you've done is basically made a statement, 'limit( speed, 20 )'. What you need to do is an evaluation, and much like geky's example using clamp, you need to make speed equal to this function, and that function must return a value:
Code:
speed = limit( speed, 20 );
In order to return that value, limit needs to look something like:
Code:
if argument0 > argument1 { return argument1 }
else { return argument0 }
As you can see, we are setting 'speed' to the result of 'limit( speed, 20 )'. And to get that result, 'limit' returns a value. If we were to expand out this script into a ternary operation, it would look something like this:
Code:
speed = ( speed < 20 ) ? speed : 20;
But the initial code you are typing looks like this:
Code:
Nothing happens, because you haven't told the program to actually do anything. Read up more about arguments and functions in the manual for more information.
 
Top