Posted 03 November 2012 - 06:08 AM
I have written a simple program to automatically refill my IC2 reactor. In case of the server going offline the program saves state so it can be resumed with an autorun script when the server is restarted.
The program loops in the following manner:
For the countdown
Wait one second
Decrement the countdown
Write the new value for the countdown to disk
Repeat
The program almost works flawlessly, the refill routine works perfectly, having been tested several times, and for the majority of the time so does the main loop. The problem is that every few hundred seconds the computer will crash with the following error: “reactor:13: attempt to index ? (a nil value)”. This error is indicated to come from the fs API file.write() function.
I have tried all I can think of to fix the problem:
I thought that I ought to check that it is not something simple I am missing before I try the above solution.
The program loops in the following manner:
For the countdown
Wait one second
Decrement the countdown
Write the new value for the countdown to disk
Repeat
The program almost works flawlessly, the refill routine works perfectly, having been tested several times, and for the majority of the time so does the main loop. The problem is that every few hundred seconds the computer will crash with the following error: “reactor:13: attempt to index ? (a nil value)”. This error is indicated to come from the fs API file.write() function.
I have tried all I can think of to fix the problem:
- Originally the program was written with the io API, swapping between the two has made no difference.
- I have tried saving state every 5 seconds instead in order to give the computer more time to write, but the problem persists.
- I have put the sleep before and after write in the loop, but this has not helped.
- I looked around in the lua io documentation and tried to change the buffering mode, but the function did not seem to be available in computercraft.
I thought that I ought to check that it is not something simple I am missing before I try the above solution.
--FUNCTIONS
function readCache() --Read the time stored on disk
local cache = fs.open("disk/cache", "r")
local time = cache.readAll()
cache.close()
return tonumber(time)
end
function writeCache(Str) --Write the value of the countdown to disk
local cache = fs.open("disk/cache", "w")
cache.write(Str)
cache.close()
end
function clearTerm() --Clear terminal and reset cursor
term.clear()
term.setCursorPos(1, 1)
end
function refill() --Refill reactor
clearTerm()
write("Disengaging reactor and cooling: ")
rs.setOutput("back", true)
sleep(0.1) --No reason for this other than to make it look the part
print("Done\n")
sleep(0.75)
for i = 1, 47 do --47 fuel cells in the reactor
clearTerm()
write("Emptying reactor: ")
write(math.ceil((i/47)*100))
write("%")
rs.setOutput("right", true) --Could make these sleeps smaller, but the server connection is not rock solid, better safe than sorry
sleep(0.5)
rs.setOutput("right", false)
sleep(0.5)
end
clearTerm()
write("Emptying reactor: Done")
sleep(0.75)
for i = 1, 47 do
clearTerm()
write("Filling reactor: ")
write(math.ceil((i/47)*100))
write("%")
rs.setOutput("left", true)
sleep(0.5)
rs.setOutput("left", false)
sleep(0.5)
end
clearTerm()
print("Filling reactor: Done")
sleep(0.75)
clearTerm()
write("Reinitialising reactor and cooling: ")
rs.setOutput("back", false)
sleep(0.1)
print("Done\n")
sleep(0.75)
end
--IN POINT
while true do
local loop = readCache() --Set 'loop' to the stored remaining time
clearTerm()
write("Resuming reactor from ")
write(loop)
for i = 1, loop do
sleep(1)
writeCache(loop - i)
clearTerm()
write("Next refill in ")
print(loop - i)
end
refill()
writeCache(10000) --Set cache to 10000 seconds, time for reactor to cycle, may need adjusting but approximately this value
end