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

Computer freezes then shuts down

Started by LeviM, 29 October 2015 - 04:05 PM
LeviM #1
Posted 29 October 2015 - 05:05 PM
Hi, I'm making a bank on my multiplayer server and I have written a small text formatting based API for controlling a monitor. However when I run one of the functions the computer freezes for a little bit and then shutsdown. During this time you can terminate the program.

The API is here and it's the last function, I've placed a comment above it.
KingofGamesYami #2
Posted 29 October 2015 - 05:17 PM
You have an infinite non-yielding loop there. CC automatically shuts down computers that don't yield.
Creator #3
Posted 29 October 2015 - 05:24 PM
When your PC does not yield for 10 sec, CC stops it because during that time, no other PC can run.
LeviM #4
Posted 29 October 2015 - 07:38 PM
But, I don't know why.
Lupus590 #5
Posted 29 October 2015 - 07:41 PM
But, I don't know why.

read the second post again
Bomb Bloke #6
Posted 29 October 2015 - 09:45 PM
When a computer/turtle starts running code, ComputerCraft starts a ten second timer. If that code doesn't yield before that timer ends then ComputerCraft will either crash the script or the whole computer (depending on the nature of the functions your script is calling). After each yield, any other systems waiting to run code may do so, then after they've all yielded, processing continues with a new time limit.

The reason why is that running your code chews up valuable server processing power, and so it shouldn't be able to monopolise it. In fact, only ONE CC device can run code at a time: While one is doing something, none of the others can do anything until it yields.

Whether or not it takes more than ten seconds for your code to execute has a little to do with the power of the Minecraft server it's running on, and a lot to do with how often you allow your code to yield. Pulling events (eg getting typed characters or checking timers) triggers a yield, and many commands (eg turtle movements, sleeping, or getting text input from the user) have to pull events to work anyway. Basically, anything that triggers a pause is pulling an event in order to do it, and in order to pull an event the code yields.

In your code, these loops here are your problem:

  while true do
    local tWidth = width
    while true do
      local temp = string.sub(text, done, tWidth)
      if string.sub(temp, #temp) == " " then
        temp = string.sub(text, done, tWidth - 1)
        table.insert(lines, temp)
        done = tWidth + 1
      else
        tWidth = tWidth - 1
      end
    end
  end

They never yield, and they also never stop - there's no way the code underneath them will ever run.

It looks like you were perhaps trying to take every word in "text", and place them sequentially into a table? If so, you could replace the whole thing with:

for word in string.gmatch(text, "%w+") do lines[#lines + 1] = word end
Creator #7
Posted 29 October 2015 - 10:04 PM
Exactly. Perfect explanation. Lind of whatvwe were all trying to say.
LeviM #8
Posted 29 October 2015 - 10:14 PM
When a computer/turtle starts running code, ComputerCraft starts a ten second timer. If that code doesn't yield before that timer ends then ComputerCraft will either crash the script or the whole computer (depending on the nature of the functions your script is calling). After each yield, any other systems waiting to run code may do so, then after they've all yielded, processing continues with a new time limit.

The reason why is that running your code chews up valuable server processing power, and so it shouldn't be able to monopolise it. In fact, only ONE CC device can run code at a time: While one is doing something, none of the others can do anything until it yields.

Whether or not it takes more than ten seconds for your code to execute has a little to do with the power of the Minecraft server it's running on, and a lot to do with how often you allow your code to yield. Pulling events (eg getting typed characters or checking timers) triggers a yield, and many commands (eg turtle movements, sleeping, or getting text input from the user) have to pull events to work anyway. Basically, anything that triggers a pause is pulling an event in order to do it, and in order to pull an event the code yields.

In your code, these loops here are your problem:

  while true do
	local tWidth = width
	while true do
	  local temp = string.sub(text, done, tWidth)
	  if string.sub(temp, #temp) == " " then
		temp = string.sub(text, done, tWidth - 1)
		table.insert(lines, temp)
		done = tWidth + 1
	  else
		tWidth = tWidth - 1
	  end
	end
  end

They never yield, and they also never stop - there's no way the code underneath them will ever run.

It looks like you were perhaps trying to take every word in "text", and place them sequentially into a table? If so, you could replace the whole thing with:

for word in string.gmatch(text, "%w+") do lines[#lines + 1] = word end
When a computer/turtle starts running code, ComputerCraft starts a ten second timer. If that code doesn't yield before that timer ends then ComputerCraft will either crash the script or the whole computer (depending on the nature of the functions your script is calling). After each yield, any other systems waiting to run code may do so, then after they've all yielded, processing continues with a new time limit.

The reason why is that running your code chews up valuable server processing power, and so it shouldn't be able to monopolise it. In fact, only ONE CC device can run code at a time: While one is doing something, none of the others can do anything until it yields.

Whether or not it takes more than ten seconds for your code to execute has a little to do with the power of the Minecraft server it's running on, and a lot to do with how often you allow your code to yield. Pulling events (eg getting typed characters or checking timers) triggers a yield, and many commands (eg turtle movements, sleeping, or getting text input from the user) have to pull events to work anyway. Basically, anything that triggers a pause is pulling an event in order to do it, and in order to pull an event the code yields.

In your code, these loops here are your problem:

  while true do
	local tWidth = width
	while true do
	  local temp = string.sub(text, done, tWidth)
	  if string.sub(temp, #temp) == " " then
		temp = string.sub(text, done, tWidth - 1)
		table.insert(lines, temp)
		done = tWidth + 1
	  else
		tWidth = tWidth - 1
	  end
	end
  end

They never yield, and they also never stop - there's no way the code underneath them will ever run.

It looks like you were perhaps trying to take every word in "text", and place them sequentially into a table? If so, you could replace the whole thing with:

for word in string.gmatch(text, "%w+") do lines[#lines + 1] = word end

That's an an amazing explanation :D/> Thanks!