Simple script driving me insane

Talk about creating Grimrock 1 levels and mods here. Warning: forum contains spoilers!
Post Reply
User avatar
Phitt
Posts: 442
Joined: Tue Aug 14, 2012 9:43 am

Simple script driving me insane

Post 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?
BeNNyBiLL
Posts: 40
Joined: Mon Oct 08, 2012 11:00 pm

Re: Simple script driving me insane

Post 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)
User avatar
Phitt
Posts: 442
Joined: Tue Aug 14, 2012 9:43 am

Re: Simple script driving me insane

Post 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!
User avatar
Komag
Posts: 3659
Joined: Sat Jul 28, 2012 4:55 pm
Location: Boston, USA

Re: Simple script driving me insane

Post 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.
Finished Dungeons - complete mods to play
User avatar
Phitt
Posts: 442
Joined: Tue Aug 14, 2012 9:43 am

Re: Simple script driving me insane

Post 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
User avatar
Komag
Posts: 3659
Joined: Sat Jul 28, 2012 4:55 pm
Location: Boston, USA

Re: Simple script driving me insane

Post 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
Finished Dungeons - complete mods to play
Lilltiger
Posts: 95
Joined: Sun Sep 16, 2012 1:12 am

Re: Simple script driving me insane

Post 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()
Post Reply