Page 1 of 1

Simple script driving me insane

Posted: Mon Oct 29, 2012 12:09 am
by Phitt
I have a problem with a very simple script and I don't know what is wrong with it. Here is the script:

Code: Select all

local random = math.random(2)

	if random == 1 then
	local xpos = party.x + 1 + math.random(3)
	else
	local xpos = party.x - 1 - math.random(3)
	end
	
	print(xpos)
The problem is that xpos always returns 'nil'. I found out what the problem is already, but I don't know why. The if condition apparently doesn't work, if I remove it the variable returns the correct value. I tried to simply set random to 1 (instead of local random = math.random(2) I used local random = 1), but it still doesn't work. print(random) shows that the random variable has the correct values (1 or 2). But no matter what I try, the random variable doesn't exist in the if condition. Is it not possible to use local variables in if conditions or what is the problem here?

Re: Simple script driving me insane

Posted: Mon Oct 29, 2012 12:14 am
by BeNNyBiLL
your local variable xpos loses scope outside of the if/else loop. Outside of this loop, xpos is disposed of. This is the very definition of a local variable. It is not a problem, its just how you use it. The correct implementation would be

Code: Select all

local random = math.random(2)
local xpos = 0
if random == 1 then
   xpos = party.x + 1 + math.random(3)
else
   xpos = party.x - 1 - math.random(3)
end
   
print(xpos)

Re: Simple script driving me insane

Posted: Mon Oct 29, 2012 12:28 am
by Phitt
BeNNyBiLL wrote:your local variable xpos loses scope outside of the if/else loop. Outside of this loop, xpos is disposed of. This is the very definition of a local variable. It is not a problem, its just how you use it. The correct implementation would be

Code: Select all

local random = math.random(2)
local xpos = 0
if random == 1 then
   xpos = party.x + 1 + math.random(3)
else
   xpos = party.x - 1 - math.random(3)
end
   
print(xpos)
Ah, ok. Guess using a local variable is pointless then as it will be 0 outside the if condition. Thought the only difference was that it's not written to the save game. Thanks!

Re: Simple script driving me insane

Posted: Mon Oct 29, 2012 2:24 am
by Komag
local things will be local to inside of whatever they're inside of. So if it's inside an "if" they will disappear after the "end" associated with that "if". If it's inside a "function" it will remain alive until the function is done with its "end"

They're useful because then you don't have to use a unique name compared to other scripts and functions you have going on.

Re: Simple script driving me insane

Posted: Mon Oct 29, 2012 9:10 am
by Phitt
Komag wrote:local things will be local to inside of whatever they're inside of. So if it's inside an "if" they will disappear after the "end" associated with that "if". If it's inside a "function" it will remain alive until the function is done with its "end"

They're useful because then you don't have to use a unique name compared to other scripts and functions you have going on.
Ack...so non-local variables are not unique to scripts? If I declare a variable named 'counter' in script A and declare another one named 'counter' in script B, then I have effectively one variable named 'counter' only? So if script A sets the counter var to, say, 2 then it will automatically be 2 in script B as well? If that is the case then I guess I'll have to do a lot of renaming. But I guess the declaration block of a script runs only once when the script is triggered for the first time, right? Eg

Code: Select all

counter = 0

function blabla()
blabla
end
will only set the counter to zero when the script runs for the first time (including if the player reloads a save game and triggers the script again)?

Oh, and I have another question. If I have a teleporter and 'change facing' enabled, then an item passing through it should adjust its facing normally. If I set the facing by using this script nothing happens though, the items always face north:

Code: Select all

function teletarget()

local xpos = math.random(4) + 26
local ypos = math.random(3) + 28
local face = math.random(4) - 1

catchtele1:setTeleportTarget(xpos,ypos,face,2)
catchtele2:setTeleportTarget(xpos,ypos,face,2)
catchtele3:setTeleportTarget(xpos,ypos,face,2)

end

Re: Simple script driving me insane

Posted: Mon Oct 29, 2012 12:01 pm
by Komag
hmm, I USED to think they must be unique names for stuff like "counter", but now I see that I've been mistaken about that. I just tested setting up two scripts with the same "doorCounter = 1", two buttons to open two doors when the counters reach 3. They work completely independently (I cannot press one button twice and then another button once, for example, to open the second button's door). So apparently it's just fine to have the same "counter" names in different script entities.

I seem to recall reading something like that from the dev's now, that all script things like that are really in fact local, that nothing is truly global. Maybe it's just that if you put it up top, outside the function, it will work for ALL the functions you place in that script entity, which makes sense I suppose. In that regard, it still makes sense to think of them being inside whatever they're inside of, in this case, they're inside the script entity, broader than the level of being inside a function.

But I also think I remember something about the difference of not saying "local" to something even inside a function. I think you can create a variable inside a function that will be accessible outside the function later, such as a function setting "counter = 0" for the first time, and a different function within the same script entity checking the counter later

Re: Simple script driving me insane

Posted: Mon Oct 29, 2012 6:05 pm
by Lilltiger
You can see each script as it's own namespace, it's own local unit, so let's say you have a script named:
rabbit_script
And inside this script you define the var:
jump = 1
now this variable is globally readable as:
rabbit_script.jump
But this way to access it is not recommended instead do it like this:

rabbit_script:

Code: Select all

jump = 1

function getJump()
   return jump
end

function setJump(value)
   jump = value
end
now you access it globally as:
rabbit_script:getJump()
or
rabbit_script.getJump()