Game Maker Studio, script arguments not responding to variables - arguments

To make my game more dynamic, I have created a script in which arguments are used in order to be substituted by pre defined variables.
Upon clicking the left mouse_button, there is the code:
script_execute(scrShoot, weapon1, ammo1);
Where weapon1 and ammo1 are local variables.
The simple script 'scrShoot' is as follows:
if argument0 = 1
{
argument1 -= 0.05;
instance_create(x,y,objBullet);
}
if argument0 = 2
{
argument1 -= 0.05;
repeat(4)
{
instance_create(x,y,objBullet2);
}
}
argument0 works as expected, being successfully substituted by weapon1, however, the variable ammo1 never decreases.
When I manually write in ammo1 in place of argument1, the script works fine; decreasing by 0.05 with every click.
Other tests using scripts have lead me to believe that the problem lies with using variables to substitute arguments: strings and numbers work as you would expect.
I have encountered this problem in more than one scenario and I'm baffled that nobody else on the internet seems to have come across the same problem.

When you pass a number as an argument to a script, you’re giving that script a copy of the number to work with. That is, the script doesn’t see that you’re passing it ammo1 – it only sees that you passed it, say, 50. The line argument1 -= 0.05 just modifies the copy the script receives, not ammo1 itself.
This is called passing an argument by value (giving the script a copy that it can modify), as opposed to by reference (pointing the script to a variable to modify).
See: What's the difference between passing by reference vs. passing by value?
GML itself doesn’t have syntax for passing arguments by-reference, so you’re out of luck. What you can do, I believe, is pass an instance ID (like self or other, or the result of a call to instance_create) to the script:
/// scrShoot()
var o = argument0;
if (o.weapon == 1) {
o.ammo -= 0.05;
instance_create(x, y, objBullet);
}
/// Your object
script_execute(scrShoot, self);

Related

What is the difference between call-by-reference and call-by-value-return

As the title says I'm curious about the difference between "call-by-reference" and "call-by-value-return". I've read about it in some literature, and tried to find additional information on the internet, but I've only found comparison of "call-by-value" and "call-by-reference".
I do understand the difference at memory level, but not at the "conceptual" level, between the two.
The called subroutine will have it's own copy of the actual parameter value to work with, but will, when it ends executing, copy the new local value (bound to the formal parameter) back to the actual parameter of the caller.
When is call-by-value-return actually to prefer above "call-by-reference"? Any example scenario? All I can see is that it takes extra memory and execution time due to the copying of values in the memory-cells.
As a side question, is "call-by-value-return" implemented in 'modern' languages?
Call-by-value-return, from Wikipedia:
This variant has gained attention in multiprocessing contexts and Remote procedure call: if a parameter to a function call is a reference that might be accessible by another thread of execution, its contents may be copied to a new reference that is not; when the function call returns, the updated contents of this new reference are copied back to the original reference ("restored").
So, in more practical terms, it's entirely possible that a variable is in some undesired state in the middle of the execution of a function. With parallel processing this is a problem, since you can attempt to access the variable while it has this value. Copying it to a temporary value avoids this problem.
As an example:
policeCount = 0
everyTimeSomeoneApproachesOrLeaves()
calculatePoliceCount(policeCount)
calculatePoliceCount(count)
count = 0
for each police official
count++
goAboutMyDay()
if policeCount == 0
doSomethingIllegal()
else
doSomethingElse()
Assume everyTimeSomeoneApproachesOrLeaves and goAboutMyDay are executed in parallel.
So if you pass by reference, you could end up getting policeCount right after it was set to 0 in calculatePoliceCount, even if there are police officials around, then you'd end up doing something illegal and probably going to jail, or at least coughing up some money for a bribe. If you pass by value return, this won't happen.
Supported languages?
In my search, I found that Ada and Fortran support this. I don't know of others.
Suppose you have a call by reference function (in C++):
void foobar(int &x, int &y) {
while (y-->0) {
x++;
}
}
and you call it thusly:
int z = 5;
foobar(z, z);
It will never terminate, because x and y are the same reference, each time you decrement y, that is subsequently undone by the increment of x (since they are both really z under the hood).
By contrast using call-by-value-return (in rusty Fortran):
subroutine foobar(x,y):
integer, intent(inout) :: x,y
do while y > 0:
y = y - 1
x = x + 1
end do
end subroutine foobar
If you call this routine with the same variable:
integer, z = 5
call foobar(z,z)
it will still terminate, and at the end z will be changed have a value of either 10 or 0, depending on which result is applied first (I don't remember if a particular order is required and I can't find any quick answers to the question online).
Kindly go to the following link , the program in there can give u an practical idea regarding these two .
Difference between call-by-reference and call-by-value

How to determine if code is getting executed as a function or using cell mode

I like to use cell mode rather than break points when writing/debugging functions.
How would you determine at run-time if the currently executing code is getting executed as a function or using cell mode?
Bonus Points If you can come up with a function that knows it is was invoked from within another function or from a cell.
An example of when this might be useful is when you want to load data differently during the execution of a function or if you want to create plotters for debugging. It becomes a pain to comment out specific lines when switching between executing as a cell or a function.
function doSomethingAwesome(inputs)
%%
if executingAsCell == true
clear
importData
end
% process stuff
if executingAsCell == true
plot(myAwesomeResults)
end
Note, this is not a duplicate of my previous question: How to determine if code is executing as a script or function?
The simplest approach is using dbstack() as suggested by #Junuxx:
if isempty(dbstack)
%# true if you evaluated the cell while not in debug mode
Similarly, a function can know whether it was invoked from another function or from base/cell by checking the length of the dbstack
function doSomething
if length(dbstack)==1
%# the function has been invoked from a cell or the command line
%# (unless you're in debug mode)
A function can actually distinguish whether it was invoked from command-line or from a cell, since the latter doesn't write into the history:
function doSomething
if length(dbstack)==1
javaHistory=com.mathworks.mlservices.MLCommandHistoryServices.getSessionHistory;
lastCommand = javaHistory(end).toCharArray'; % ' added for SO code highlighting
if strfind(lastCommand,'doSomething')
%# Probably invoked via command line
else
%# Probably invoked via executing a cell
If you want to determine whether you're in debug mode or not, one possibility is to use the line-argument from dbstack, and check whether there is a call to the currently executing function on the line the apparent calling function.

Does defining variables within a loop matter?

This is a piece of code I am writing.
var cList:XMLList = xml.defines.c;
var className:String;
var properties:XMLList;
var property:XML;
var i:int,l:int;
var c:XML;
for each(c in cList)
{
className = String(c.#name);
if(cDict[className])
{
throw new Error('class name has been defined' + className);
}
if(className)
{
cDict[className] = c;
}
properties = c.property;
i = 0,
l = properties.length();
if(l)
{
propertyDict[className] = new Dictionary();
for(;i<l;i++)
{
// ...
}
}
}
As you can see, I defined all variables outside of loops. I am always worried, that if I defined them inside the loop, it might slow down the process speed, though I don't have proof - it's just a feeling.
I also don't like that the as3 grammar allows using a variable name before the defintion. So I always define vars at the very beginning of my functions.
Now I am worried these habits might backfire on me someday. Or is it just a matter of personal taste?
No it doesn't matters because the compiler use variable hoisting, so it means that that the compiler moves all variable declarations to the top of the function :
More explanation on variables:
http://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7f9d.html
AS3 IDEs allow you to use variable names before the declaration, because they know that the compiler uses a mechanism called "hoisting" to move all variable definitions to the top of a function, anyway. This happens without you noticing it, so that you can conveniently keep your code more readable. Therefore, it does not really make a difference if you manually move all the definitions to the top - unless you like your code to be structured in that way.
For the same reason, variable declaration within loops does not affect performance, unless you keep those loops in separate functions - only then will it result in actual allocation of a variable.
A lot of AS3 programmers, me including, would consider the way you have it now to be "the right" way, while putting variables inside any block to be the "wrong way". The speed does not matter in this situation, I'll try to present both side's arguments in as little biased way as I can.
Put variables definition as close to the code it is used in. The motivation is simple: if the variable is used somewhere, you might want to know where was it declared. This is useful if you aren't sure of type of the variable, or its modifiers. Normally, the declaration is also the place to put commentary.
Put variables at the place where they are actually declared. Even a seasoned ActionScript programmer may eventually confuse him- or herself by declaring variables inside blocks, where a seemingly uninitialized variable would suddenly contain some random value. The common case looks like this:
for (var i:int; i < x; i++) {
// this loop is entered exactly once, instead of `i' times
for (var j:int; j < y: j++) { ... }
}
There is also a long tradition, originating in the C89 standard (aka ANSI C), which didn't have block-scoped variables and would not allow variable definition inside a loop. This has been later altered so that variables were scoped to the block of code where they are declared. Many modern C-like languages, for example C# treat variables like that. So, in the example above, C# would re-initialize j every time the inner loop was entered.
Programmers with longer tradition of writing code in other C-like languages would be led to believe thus, once they see variables declared inside a block, that the variable is scoped to the block. The "hoisting" is thus thought of as counter-intuitive. Therefore error-prone.

Lua Debugging - Detect when the value of a variable changes

Is it possible to detect when the value of a variable has changed using the lua debug library.
Something like A callback function which would give details like the function in which the value was changed, previous value, etc.
Is such a thing possible?
I read about hooks, but I'm not sure hooks can be set to variables.
If you don't mind using a debugger, then some debuggers allow you to set Watch expressions, which will be triggered when the condition in the expression is true. I'll show how this can be done in MobDebug (it is using lua debug library, but there is no direct way to detect a variable change as far as I know).
Let say we have a script start.lua like the one below and want to detect where foo gets value 2:
print("Start")
local foo = 0
for i = 1, 3 do
local function bar()
print("In bar")
end
foo = i
print("Loop")
bar()
end
print("End")
Download mobdebug.lua and make it available to your scripts (the simplest way is to put it into the folder with your scripts).
Start the server using lua -e "require('mobdebug').listen()" command.
Start the client using lua -e "require('mobdebug').loop()" command.
You will see the prompt in the server window: '>'. Type load start.lua to load the script.
Type step and then step again. You will see "Paused at file start.lua line 3".
Let's see what the value of foo is. Type eval foo and you should see 0.
Now we can set up our watch. Type setw foo == 2. You can specify any Lua expression after setw command; the execution of your script will be stopped when the condition is evaluated as true.
Continue execution of the script using "run" command.
The watch now fires, which will show you the message like: "Paused at file start.lua line 8 (watch expression 1: [foo == 2])". This means that the previous expression changed the value of foo to 2 and the execution is stopped at line 8. You can then inspect your script and the current values (you can use "eval" and "exec" commands to run any Lua code to be evaluated in your script environment) to find what triggered the change.
The benefit of this approach is that you are not limited to monitoring table values and can specify any expression. The main disadvantage is that your script runs under a debugger and the expression is evaluated after each step, which may get really slow.
You can do this to a certain extent in Lua by using metatables and keeping a "proxy" table, and using the __newindex function call to detect attempts to add a variable.
This is covered here in the Programming in Lua book under the section "Tracking Table Accesses":
http://www.lua.org/pil/13.4.4.html
See Also
http://www.gammon.com.au/forum/?id=10887

Using function arguments as local variables

Something like this (yes, this doesn't deal with some edge cases - that's not the point):
int CountDigits(int num) {
int count = 1;
while (num >= 10) {
count++;
num /= 10;
}
return count;
}
What's your opinion about this? That is, using function arguments as local variables.
Both are placed on the stack, and pretty much identical performance wise, I'm wondering about the best-practices aspects of this.
I feel like an idiot when I add an additional and quite redundant line to that function consisting of int numCopy = num, however it does bug me.
What do you think? Should this be avoided?
As a general rule, I wouldn't use a function parameter as a local processing variable, i.e. I treat function parameters as read-only.
In my mind, intuitively understandabie code is paramount for maintainability, and modifying a function parameter to use as a local processing variable tends to run counter to that goal. I have come to expect that a parameter will have the same value in the middle and bottom of a method as it does at the top. Plus, an aptly-named local processing variable may improve understandability.
Still, as #Stewart says, this rule is more or less important depending on the length and complexity of the function. For short simple functions like the one you show, simply using the parameter itself may be easier to understand than introducing a new local variable (very subjective).
Nevertheless, if I were to write something as simple as countDigits(), I'd tend to use a remainingBalance local processing variable in lieu of modifying the num parameter as part of local processing - just seems clearer to me.
Sometimes, I will modify a local parameter at the beginning of a method to normalize the parameter:
void saveName(String name) {
name = (name != null ? name.trim() : "");
...
}
I rationalize that this is okay because:
a. it is easy to see at the top of the method,
b. the parameter maintains its the original conceptual intent, and
c. the parameter is stable for the rest of the method
Then again, half the time, I'm just as apt to use a local variable anyway, just to get a couple of extra finals in there (okay, that's a bad reason, but I like final):
void saveName(final String name) {
final String normalizedName = (name != null ? name.trim() : "");
...
}
If, 99% of the time, the code leaves function parameters unmodified (i.e. mutating parameters are unintuitive or unexpected for this code base) , then, during that other 1% of the time, dropping a quick comment about a mutating parameter at the top of a long/complex function could be a big boon to understandability:
int CountDigits(int num) {
// num is consumed
int count = 1;
while (num >= 10) {
count++;
num /= 10;
}
return count;
}
P.S. :-)
parameters vs arguments
http://en.wikipedia.org/wiki/Parameter_(computer_science)#Parameters_and_arguments
These two terms are sometimes loosely used interchangeably; in particular, "argument" is sometimes used in place of "parameter". Nevertheless, there is a difference. Properly, parameters appear in procedure definitions; arguments appear in procedure calls.
So,
int foo(int bar)
bar is a parameter.
int x = 5
int y = foo(x)
The value of x is the argument for the bar parameter.
It always feels a little funny to me when I do this, but that's not really a good reason to avoid it.
One reason you might potentially want to avoid it is for debugging purposes. Being able to tell the difference between "scratchpad" variables and the input to the function can be very useful when you're halfway through debugging.
I can't say it's something that comes up very often in my experience - and often you can find that it's worth introducing another variable just for the sake of having a different name, but if the code which is otherwise cleanest ends up changing the value of the variable, then so be it.
One situation where this can come up and be entirely reasonable is where you've got some value meaning "use the default" (typically a null reference in a language like Java or C#). In that case I think it's entirely reasonable to modify the value of the parameter to the "real" default value. This is particularly useful in C# 4 where you can have optional parameters, but the default value has to be a constant:
For example:
public static void WriteText(string file, string text, Encoding encoding = null)
{
// Null means "use the default" which we would document to be UTF-8
encoding = encoding ?? Encoding.UTF8;
// Rest of code here
}
About C and C++:
My opinion is that using the parameter as a local variable of the function is fine because it is a local variable already. Why then not use it as such?
I feel silly too when copying the parameter into a new local variable just to have a modifiable variable to work with.
But I think this is pretty much a personal opinion. Do it as you like. If you feel sill copying the parameter just because of this, it indicates your personality doesn't like it and then you shouldn't do it.
If I don't need a copy of the original value, I don't declare a new variable.
IMO I don't think mutating the parameter values is a bad practice in general,
it depends on how you're going to use it in your code.
My team coding standard recommends against this because it can get out of hand. To my mind for a function like the one you show, it doesn't hurt because everyone can see what is going on. The problem is that with time functions get longer, and they get bug fixes in them. As soon as a function is more than one screen full of code, this starts to get confusing which is why our coding standard bans it.
The compiler ought to be able to get rid of the redundant variable quite easily, so it has no efficiency impact. It is probably just between you and your code reviewer whether this is OK or not.
I would generally not change the parameter value within the function. If at some point later in the function you need to refer to the original value, you still have it. in your simple case, there is no problem, but if you add more code later, you may refer to 'num' without realizing it has been changed.
The code needs to be as self sufficient as possible. What I mean by that is you now have a dependency on what is being passed in as part of your algorithm. If another member of your team decides to change this to a pass by reference then you might have big problems.
The best practice is definitely to copy the inbound parameters if you expect them to be immutable.
I typically don't modify function parameters, unless they're pointers, in which case I might alter the value that's pointed to.
I think the best-practices of this varies by language. For example, in Perl you can localize any variable or even part of a variable to a local scope, so that changing it in that scope will not have any affect outside of it:
sub my_function
{
my ($arg1, $arg2) = #_; # get the local variables off the stack
local $arg1; # changing $arg1 here will not be visible outside this scope
$arg1++;
local $arg2->{key1}; # only the key1 portion of the hashref referenced by $arg2 is localized
$arg2->{key1}->{key2} = 'foo'; # this change is not visible outside the function
}
Occasionally I have been bitten by forgetting to localize a data structure that was passed by reference to a function, that I changed inside the function. Conversely, I have also returned a data structure as a function result that was shared among multiple systems and the caller then proceeded to change the data by mistake, affecting these other systems in a difficult-to-trace problem usually called action at a distance. The best thing to do here would be to make a clone of the data before returning it*, or make it read-only**.
* In Perl, see the function dclone() in the built-in Storable module.
** In Perl, see lock_hash() or lock_hash_ref() in the built-in Hash::Util module).

Resources