20 posts
Posted 09 October 2013 - 12:47 PM
Title: Error in openning modem channels
What I'm attempting to do is on startup my computer will open all channels it can and it will be recieving messages from turtles (each having their own channel which is linked to thier computer ID)
I'm getting an error on line 26 saying I'm trying to index a nil value.
My code is here on pastebin
http://pastebin.com/Z5jC3sV3Two for one, can you reset computer ids in the game?
130 posts
Posted 09 October 2013 - 01:24 PM
`modem` is defined as local in the if statements so it only exists in them. You need to define modem before the ifs and just set it inside the if
local modem
if peripheral.getType('left') == 'modem' then
modem = peripheral.wrap('left')
end
20 posts
Posted 09 October 2013 - 01:27 PM
Sweet!! Thanks Coder Puppy. That was honestly the first time I've ever used local so I didn't think to look for that. Now to fix the same issue in the three other porgrams I hadn't tested yet…
8543 posts
Posted 09 October 2013 - 01:27 PM
You're declaring the modem variable as local inside the if block. When the if block ends, the variable goes out of scope, so when you try to use modem.open later, it can't find it. You should declare it as local before the if block, then simply change the value inside it. Alternatively, since you're missing "front", you could iterate the list of sides:
local modem
for _, side in pairs(rs.getSides()) do
if peripheral.getType(side) == "modem" then
modem = peripheral.wrap(side)
break
end
end
20 posts
Posted 09 October 2013 - 01:30 PM
Does anyone have an answer to my second question? can you reset ID's in game like labels?
What is the break line for?
8543 posts
Posted 09 October 2013 - 01:30 PM
If you clear the label and break the turtle/computer, it will get a new ID next time it is placed.
130 posts
Posted 09 October 2013 - 01:36 PM
You can't change a computer's id. But you can reset computer ids deleting <save>/computer/lastid.txt. This could mess stuff up… You could get computers with the same id.
break stops the loop, see
http://www.lua.org/manual/5.1/manual.html#2.4.4.
20 posts
Posted 09 October 2013 - 01:40 PM
Crap.. I was hoping to set up a system where the turtles were on channels 1-100 (and each channel was thier ID for easy rememberence) and the computers were 100+'s. Oh well
Edit: Secondary question, the _ after the for is just a variable correct?
Tertiary question, why is in pairs used?
Quadrary, why break the loop instead of waiting for it to end?
20 posts
Posted 09 October 2013 - 08:42 PM
code
4 modem=peripheral.wrap("right")
5 print("Connected to Modem")
…
…
…
11 local channelMax=128
12for i=1, channelMax, 1 do
13 if not i==os.getComputerID() then
14 modem.open(i)
15 end
16 end
i'm getting an attempt to index a nil value at 4 when I run the code. Any idea what the issue is guys?
375 posts
Location
USA
Posted 09 October 2013 - 08:49 PM
Could you have overwritten the peripheral variable? Post the whole code, and put it in code tags.
Edit: Also, why are you opening 127 channels?
20 posts
Posted 09 October 2013 - 09:07 PM
--This is a computer start-up program that will hopefully be able to control a veritable army of turtles.
print("Name: "..os.getComputerLabel())
print("ID: "..os.getComputerID())
modem=0
x="modem"
if peripheral.getType("left")==x then
modem = peripheral.wrap("left")
print("Modem is on the left")
elseif peripheral.getType("right")==x then
modem = peripheral.wrap("right")
print("Modem is on the right")
elseif peripheral.getType("top")==x then
modem = peripheral.wrap("top")
print("Modem is on the top")
elseif peripheral.getType("bottom")==x then
modem = peripheral.wrap("bottom")
print("Modem is on the bottom")
elseif peripheral.getType("back")==x then
modem = peripheral.wrap("back")
print("Modem is on the back")
else
print("I don't have any modems")
end
local channelMax=128
for i=1, channelMax, 1 do
modem.open(i)
end
print("")
print("I have the following programs available: ")
print("!tunnel, !refuel")
print("")
print("I will now wait for messages from Minions, hold Ctrl+T to terminate")
print("")
while true do
local event, modemSide, senderChannel,
replyChannel, message, senderDistance = os.pullEvent("modem_message")
print("Message from Minion "..senderChannel.." : "..message)
end
This is the raw code before i tried to make it less universal and just work. I got it to work on the first computer (ID 0) but it won't work on this one (ID 2) and I don't understand why. I also want to pair it with another code that simply recieves messages and puts them on a large monitor as sort of a mission control. to that extent for this computer the last while loop has been deleted. and replaced with a shell.run("monitor code") and that while loop is in the monitor code.
7083 posts
Location
Tasmania (AU)
Posted 10 October 2013 - 01:38 AM
Saying "it won't work" isn't helpful. What does it do instead? What code are the turtles running? Does it give the same error as the code in your first post, or something different? If it's the same sort of thing on the same sort of line, reboot the computer and try it again.
Note that modems do not need to send to the same port they send from (nor should they), and connections to/from multiple devices can be managed through one port. That is to say, you need only open a port if you want to receive communications addressed to that port, and which port the communications are being sent from is irrelevant.
20 posts
Posted 10 October 2013 - 12:39 PM
I've since tested the code on a single player server and it works beautifully. The error is still line 4, attempt to call nil. I think that with the issue setting up the server, the code somehow got corrupted. I will redownload it and try again. The turtles are using a very simple.
modem.transmit(channel, channel, "Minion "..os.getComputerLabel().." has finished refueling, Sir!")
to send messages with the last set of quotes being changed as neccessary to report completing/starting of a tunnel/building/ditch/waterway etc.
Thank you for your input on channels. I just wanted to be able to track turtle by computer ID number so that way I know that when I send 1-5 to start mining, I can easily differentiate between 1 and say 3 finishing. I will open channel 128 on the turtles so that would be the channel they receive commands from.
8543 posts
Posted 10 October 2013 - 01:15 PM
Threads merged. Please stick to one topic for all of your questions on a given piece of code.
20 posts
Posted 10 October 2013 - 04:56 PM
Maybe this will be more clear.
When I run the following code
--This is a computer start-up program that will hopefully be able to control a veritable army of turtles.
print("Name: "..os.getComputerLabel())
print("ID: "..os.getComputerID())
modem=0
for _, side in pairs(rs.getSides()) do
if peripheral.getType(side) == "modem" then
modem = peripheral.wrap(side)
print("Connected to Modem")
break
end
end
monitor=0
for _, side in pairs(rs.getSides()) do
if peripheral.getType(side) == "monitor" then
monitor = peripheral.wrap(side)
print("Connected to Monitor")
break
end
end
drive=0
for _, side in pairs(rs.getSides()) do
if peripheral.getType(side) == "drive" then
drive = peripheral.wrap(side)
print("Connected to Drive")
break
end
end
modem.open(100)
modem.open(128)
modem.open(os.getComputerID())
print("")
print("I have the following programs available: ")
print("!tunnel, !refuel, !message, turtlestartup, !MissionControl, !chat")
in single player it works fine on multiple computers. However, when I upload it to a second computer in a server it says,
error in startup:4: attempt to index ? (a nil value)
all I'm doing in line 4 is defining a variable, so what is the issue? and why does it work in single player but not in multiplayer. is there a code issue there or what?
20 posts
Posted 10 October 2013 - 05:17 PM
Resolved:
Apparently computers don't like rebooting with a disk drive that has a floppy in it connected
7083 posts
Location
Tasmania (AU)
Posted 10 October 2013 - 07:25 PM
Beats me how it'd give that error on that line, let alone what a monitor would have to do with it.
A couple of points, well done on your code improvements, but you can still trim things down a little bit. Eg, rather then having multiple loops checking for peripherals, one will do:
for _, side in pairs(rs.getSides()) do
if peripheral.getType(side) == "monitor" then
monitor = peripheral.wrap(side)
print("Connected to Monitor")
elseif peripheral.getType(side) == "drive" then
drive = peripheral.wrap(side)
print("Connected to Drive")
elseif etc...
You may consider having each turtle open a port equal to its ID number (meaning that whenever a given turtle receives a message, odds are that message is specifically for that turtle). When booting up, they can send a message to the server stating their label, which the server can then store for later reference - or they can send a message
requesting a label, which the server can make up based on what labels it's given out already. The point is to rig things so that you never need to manually code in new port numbers as you add turtles to the system.