A few questions in 1 thread!

As you may or may not know I am working on a game called Mazecraft that is a randomly generated labyrinth or maze.
However, I'm having some issues:
1. How do I create locked exits?
Like a randomly generated locked door that requires a key to be unlocked.
2. How do I read each character of a string?
Like read: 123 as 1, 2, 3


1. A general strategy here is to start a new game and create a locked exit and key, and then look at the attributes for each/, and see what you need for your random ones. For example, you will need islocked to be true to lock the door.

2. I do not think foreach works on a list (though I could be wrong). Try this:
for (i, 1, LengthOf(s)) {
msg("The next character is " + Mid(s, i, 1))
}

Check it does read each character and no more!

What's wrong with this code? (Ignore the fact it's 100%, just trying to test it out but nothing is happening even though an exit from that room exists)
north_exit = GetExitByName (room, "north")
if (not north_exit = null) {
if (RandomChance(100)) {
CloneObjectAndMove (north_door, room)
north_exit.lockmessage = "You need a key to unlock this door!"
LockExit (north_exit)
}
}
east_exit = GetExitByName (room, "east")
if (not east_exit = null) {
if (RandomChance(100)) {
CloneObjectAndMove (east_door, room)
east_exit.lockmessage = "You need a key to unlock this door!"
LockExit (east_exit)
}
}
south_exit = GetExitByName (room, "south")
if (not south_exit = null) {
if (RandomChance(100)) {
CloneObjectAndMove (south_door, room)
south_exit.lockmessage = "You need a key to unlock this door!"
LockExit (south_exit)
}
}
west_exit = GetExitByName (room, "west")
if (not west_exit = null) {
if (RandomChance(100)) {
CloneObjectAndMove (west_door, room)
west_exit.lockmessage = "You need a key to unlock this door!"
LockExit (west_exit)
}
}

I am not clear how this is supposed to work. In particular:
    CloneObjectAndMove (north_door, room)

Do you mean north_exit, not north_door? If so, why clone it if it already exists? If not, what is north_door?

Also, I think CloneObjectAndMove returns an object, and perhaps what you actually want to do is change the attributes on the new exit, not the old one.

It is also possible you cannot clone exits; they are different to normal objects.

north_door is the locked door as best as I can put it, it's the object the player will interact with to unlock the door.

Ah, then that answers all my points. Okay, try this code, and tell me what gets displayed for the north exit.
north_exit = GetExitByName (room, "north")
msg(north_exit)
if (not north_exit = null) {
if (RandomChance(100)) {
new_door = CloneObjectAndMove (north_door, room)
msg(new_door)
north_exit.lockmessage = "You need a key to unlock this door!"
LockExit (north_exit)
}
}

I get this error:
Error running script: Object reference not set to an instance of an object.

I think the problem is that GetExitByName returns the name of the exit, not the exit itself. Try this:
north_exit_name = GetExitByName (room, "north")
if (not north_exit_name = null) {
if (RandomChance(100)) {
north_exit = GetObject(north_exit_name)
CloneObjectAndMove (north_door, room)
north_exit.lockmessage = "You need a key to unlock this door!"
LockExit (north_exit)
}
}

That didn't work either :(
UPDATE: I think I found a work around for this. Instead of trying to lock an exit, I'm going to make the exit not exist at first but instead clone a locked door and use a script that will unlock the door (and create a new exit) and act as if the way is being unlocked.