This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
applesauce10189's profile picture

Potential Computercraft Bug

Started by applesauce10189, 08 August 2017 - 06:23 AM
applesauce10189 #1
Posted 08 August 2017 - 08:23 AM
So I made another thread which explained I'm playing with a lot of mods, still on that sever and making programs for fun, but I appear to have run into an issue.

I'm playing on minecraft version 1.7.10 with computercraft version 1.75, and because it's relevant to what I was trying to do, Project:Red version 4.7.0 pre 12.95


So I had a wireless modem on the back of the computer, it was originally on the right but I moved it just to see whether or not it was relevant to the problem, and project:red red alloy wiring on the left of the computer, using the computers lua interpreter I enabled and disabled the redstone signal on the left and everything acted just fine, however, when I run my program, the computer just dies. When I back out of the computer, it shows that the computer's on however the screen is entirely blank, it doesn't print anything to the screen. ctrl+t doesn't terminate the program, either. I think very rarely I spot an error, something along the lines of "windows:98" only there for a frame or so. On one occasion the entire computercraft mod on the server broke and I had to restart the server, all computers on the server read something about being unable to resume due to a problem with bios.lua, and then proceeded to be nothing more than a blank screen much like the originating computer. This only happened once and I haven't been able to recreate it.

The only way I was able to end the program was to break the modem, at which point the computer will run the first print then error when rednet.open tries opening a non-existent modem



print("starting program")
rednet.open("back")
print("rednet, opened")
fuel = false
print("fuel declared")
int = 0
print("int declared")
function alert()
print("alert function started")
while true do
print("alert loop has been run: "..int.." times")
int = int + 1
  while fuel == true do
  print("running fuel loop")
   rs.setOutput("left", true)
   sleep(0.8)
   rs.setOutput("left", false)
  end
end
end
function aCheck()
print("running aCheck")
while true do
  print("Waiting for rednet signal")
  id, msg = rednet.receive()
  print("Received rednet signal")
  if id then
   print(id.." said "..msg)
   print("test")
  end
  if id == 7 and msg == "fuelLow" then
   fuel = true
  elseif id == 7 and msg == "fuelGood" then
   fuel = false
  end
  sleep(0.01)
end
end
while true do
print("Starting main loop")
parallel.waitForAny(alert, aCheck)
print("Something returned")
end

Again, when this program is run the computer is just a purely blank screen, even though there's prints all over the place,

EDIT: I've made progress. Right after the print on line 1, I added a new line that's just sleep(5)
after that addition, the program doesn't break computercraft, it just doesn't serve its intended purpose.
Specifically, the rs.setOutputs don't seem to be acting how I'd like, on the left it just receives a constant signal rather than a toggling signal.

EDIT #2: I had a loop that was just turn on signal, sleep, turn off, no wonder it stayed constantly on, it probably wasn't even off for a single tick. Everything works as intended now. I still don't understand why I need a sleep on the second line though, I'm very curious about that.

EDIT #3: Here's my current version of the program though, if anyone could suggest improvements I could make. I'm still bad at coding.

print("starting program")
sleep(1)
print("jk, just slept a second, now starting")
rednet.open("back")
print("rednet, opened")
fuel = false
print("fuel declared")
int = 0
print("int declared")
function alert()
print("alert function started")
while true do
sleep(0.01)
print("alert loop has been run: "..int.." times")
int = int + 1
  while fuel == true do
  print("running fuel loop")
   rs.setOutput("left", true)
   sleep(0.5)
   rs.setOutput("left", false)
   sleep(0.5)
  end
end
end
function aCheck()
print("running aCheck")
while true do
  print("Waiting for rednet signal")
  id, msg = rednet.receive()
  print("Received rednet signal")
  if id then
   print(id.." said "..msg)
   print("test")
  end
  if id == 7 and msg == "fuelLow" then
   fuel = true
  elseif id == 7 and msg == "fuelGood" then
   fuel = false
  end
  sleep(0.01)
end
end
while true do
print("Starting main loop")
parallel.waitForAny(alert, aCheck)
print("Something returned")
end
Edited on 08 August 2017 - 06:49 AM
The Crazy Phoenix #2
Posted 08 August 2017 - 10:39 AM
Check your code for illegal characters, it seems that there is an 0xA0 character before every single indented line.

Instead of using a shared variable and repeatedly checking, use os.queueEvent and os.pullEvent to signal to the alert function what it should do.
applesauce10189 #3
Posted 08 August 2017 - 12:03 PM
The illegal character is probably the tabs, I edit my programs with notepad++ because a youtube video showed me that you can do that and I find it just easier that way in my opinion.
It seems a "tab" in CC is just 2 spaces, whereas a tab in notepad++ is an actual indent.

Here's an updated version of the code:

print("starting program")
sleep(1)
rednet.open("back")
fuel = false
function alert()
while true do
  sleep(0.01)
  event, p1 = os.pullEvent("trigger")
  if p1 then
   rs.setOutput("left", true)
   sleep(0.3)
   rs.setOutput("left", false)
   sleep(0.3)
  end
end
end
function aCheck()
while true do
  id, msg = rednet.receive()
  if id then
   print(id.." said "..msg)
  end
  if id == 7 and msg == "fuelLow" then
   os.queueEvent("trigger", true)
  elseif id == 7 and msg == "fuelGood" then
   os.queueEvent("trigger", false)
  end
  sleep(0.01)
end
end
while true do
parallel.waitForAny(alert, aCheck)
print("Something went wrong.")
end

Now the only potential problem is it only runs the redstone blink once per event, however the computer telling it what to do should be essentially spamming the trigger as long as its needed so it's not really that big a problem.

That, and I can't think of an effective worth-while solution to it.
KingofGamesYami #4
Posted 08 August 2017 - 12:10 PM
You dont need either of the sleep(0.01)s.
The Crazy Phoenix #5
Posted 08 August 2017 - 12:23 PM
Instead of using sleep(0.3), use a timer. That will allow you to have it continuously blink without spamming the network.
In fact, you don't even need multithreading if you listen to the rednet_message or modem_message event.


local timer = os.startTimer(0.3)
local fuel = false
local state = false
while true do
	local event, data, msg = os.pullEvent()
	if event == "rednet_message" and data == 7 then
		fuel = msg == "fuelLow" and true or (msg == "fuelGood" and false or fuel)
	elseif event == "timer" and data == timer then
		if fuel then
			state = not state
			rs.setOutput("left", state)
		else
			-- No delay next time fuel is low.
			state = false
		end
		timer = os.startTimer(0.3)
	end
end
Edited on 08 August 2017 - 10:46 AM
Exerro #6
Posted 09 August 2017 - 11:29 PM
Instead of using sleep(0.3), use a timer. That will allow you to have it continuously blink without spamming the network.
In fact, you don't even need multithreading if you listen to the rednet_message or modem_message event.


local timer = os.startTimer(0.3)
local fuel = false
local state = false
while true do
	local event, data, msg = os.pullEvent()
	if event == "rednet_message" and data == 7 then
		fuel = msg == "fuelLow" and true or (msg == "fuelGood" and false or fuel)
	elseif event == "timer" and data == timer then
		if fuel then
			state = not state
			rs.setOutput("left", state)
		else
			-- No delay next time fuel is low.
			state = false
		end
		timer = os.startTimer(0.3)
	end
end

There's an issue with that code. On the following line:

fuel = msg == "fuelLow" and true or (msg == "fuelGood" and false or fuel)
The `and true` isn't required, as `msg == "fuelLow"` will already be `true` for the `and true` to evaluate. Not exactly an issue but it's more readable imo.
Also, in the brackets, fuel will always default to `fuel` as `A and false or B == B` always. This should instead be `msg ~= "fuelGood" and fuel or false`, and like before with the `and true`, the `or false` isn't required.
So in the end, this line should read

fuel = msg == "fuelLow" or msg ~= "fuelGood" and fuel
Note that `and` has a higher precedence than `or` so the brackets aren't required.