Jump to content
  • Sky
  • Blueberry
  • Slate
  • Blackcurrant
  • Watermelon
  • Strawberry
  • Orange
  • Banana
  • Apple
  • Emerald
  • Chocolate
  • Charcoal
XyFreak

Big Reactors Grid Control

Recommended Posts

Ok since I need a github account I'm just gonna ping @payonel and hope he's the right guy for the job! ;)

Here's what's up:

This commit here broke BRGC - and it actually broke timers in general whenever event.pull is involved.

BRGC uses events and timers all over the place. The entire thing is running asynchronously. Now usually you don't want to drop to the prompt when running a program so here's what it does:

function libGUI.run()
	while event.pull(math.huge, "libGUI_terminate") == nil do end
end

It just waits for a libGUI_terminate event and then cleans up stuff. Pretty easy.

 

Now with the linked commit, this event.pull continues to eat timer messages. The timers are only executed once a non-timer event is executed (such as a key press or a touch).

Here's a small PoC:

event.timer(5, function() print("canary") end, math.huge)

Prints "canary" every 5 seconds - pretty easy - nothing should go wrong here. If you now do a simple

while event.pull(math.huge, "tell_me_to_terminate") == nil do end

you will stop seeing "canary" show up - it's dead ;)

--- SNIP because I didn't want to believe the issue is complicated and looked further into it ---

And here's your bug:

In /lib/event.lua line 36 computer.uptime() is read and stored in a variable called current_time that is never updated again. Afterwards we enter a post-checked loop. Inside of this loop, on line 54, this line is executed:

local event_data = table.pack(handlers(closest - computer.uptime()))

Nothing wrong with that, until you realize, that calling handlers actually calls _pullSignal, which allows time to pass. Later, current_time is used to check if timers have expired. The issue? current_time is no longer current, because _pullSignal was called and time has passed!

So unless you return from computer.pullSignal (=> cause a non-timer event to be triggered like a key press or a touch), current_time is never updated so timers will never trigger.

The fix is really easy: update current_time after _pullSignal has been called.

Here's a patch:

--- C:\Games\MultiMC\instances\Draconic Computers 1.12\.minecraft\saves\BRGC\opencomputers\a201b7a4-e2fd-4565-8b4b-79a6993a7e62\lib\event.lua.bak
+++ C:\Games\MultiMC\instances\Draconic Computers 1.12\.minecraft\saves\BRGC\opencomputers\a201b7a4-e2fd-4565-8b4b-79a6993a7e62\lib\event.lua
@@ -54,6 +54,7 @@
     local event_data = table.pack(handlers(closest - computer.uptime()))
     local signal = event_data[1]
     local copy = {}
+    current_time = computer.uptime()
     for id,handler in pairs(handlers) do
       copy[id] = handler
     end

 

That was a b*tch to figure out... holy molly.

Link to post
Share on other sites

I just realized that timers had a drifting problem since forever by the looks of it:
Even since before the commit that broke things, if a timer called something that let time pass (i know this is bad anyways but it CAN happen), it would actually fully delay the deadline of successive timers (instead of just delaying the timer once).

Here's another patch

--- C:\Games\MultiMC\instances\Draconic Computers 1.12\.minecraft\saves\BRGC\opencomputers\a201b7a4-e2fd-4565-8b4b-79a6993a7e62\lib\event.lua.bak
+++ C:\Games\MultiMC\instances\Draconic Computers 1.12\.minecraft\saves\BRGC\opencomputers\a201b7a4-e2fd-4565-8b4b-79a6993a7e62\lib\event.lua
@@ -62,7 +63,11 @@
       -- nil keys match anything
       if (handler.key == nil or handler.key == signal) or current_time >= handler.timeout then
         handler.times = handler.times - 1
-        handler.timeout = current_time + handler.interval
+        -- we need to make sure the timer doesn't drift but at the same time doesn't get rescheduled
+        -- immediately if it's execution had been delayed significantly (>= handler.interval * 2).
+        repeat
+          handler.timeout = handler.timeout + handler.interval
+        until handler.timeout > current_time + handler.timeout
         -- we have to remove handlers before making the callback in case of timers that pull
         -- and we have to check handlers[id] == handler because callbacks may have unregistered things
         if handler.times <= 0 and handlers[id] == handler then

I decided to go with a loop instead of math based, because the most likely case is this loop getting executed exactly once. Solving this with math would require math.floor which would propably be slower than this most of the time.

Link to post
Share on other sites

@XyFreak becuse you've given it such thought, please consider my PR: https://github.com/MightyPirates/OpenComputers/pull/3059

this change also reduces memory load by another ~100 bytes

Also, fyi, calling computer.uptime() is direct, you can call it roughly 17k times without any thread yielding. so the increase in calls to uptime() will not have any negative impact

Link to post
Share on other sites
On 2/20/2019 at 2:36 AM, CygnusiaX1 said:

@XyFreakAlright... (shutdown, disabled Optifine, restart) I do have a blinking cursor, but I still have to click to manually refresh the screen. I am using a modified version of FTB Revelations, with all mods updated to their latest versions (except Extreme Reactors... their prepping/flattening for 13 fubar'd my Yellorite gen in my world, so I rolled back to the version before.)

EDIT: If I reboot the computer, I have the blinking cursor. If I run the GUI and exit, no more blinky...

Hi there. What exactly happend? I have code in place to convert blocks in existing chunk so your Yellorite Ores should be still there

Link to post
Share on other sites
19 hours ago, XyFreak said:

I just realized that timers had a drifting problem since forever by the looks of it:
Even since before the commit that broke things, if a timer called something that let time pass (i know this is bad anyways but it CAN happen), it would actually fully delay the deadline of successive timers (instead of just delaying the timer once).

Here's another patch


--- C:\Games\MultiMC\instances\Draconic Computers 1.12\.minecraft\saves\BRGC\opencomputers\a201b7a4-e2fd-4565-8b4b-79a6993a7e62\lib\event.lua.bak
+++ C:\Games\MultiMC\instances\Draconic Computers 1.12\.minecraft\saves\BRGC\opencomputers\a201b7a4-e2fd-4565-8b4b-79a6993a7e62\lib\event.lua
@@ -62,7 +63,11 @@
       -- nil keys match anything
       if (handler.key == nil or handler.key == signal) or current_time >= handler.timeout then
         handler.times = handler.times - 1
-        handler.timeout = current_time + handler.interval
+        -- we need to make sure the timer doesn't drift but at the same time doesn't get rescheduled
+        -- immediately if it's execution had been delayed significantly (>= handler.interval * 2).
+        repeat
+          handler.timeout = handler.timeout + handler.interval
+        until handler.timeout > current_time + handler.timeout
         -- we have to remove handlers before making the callback in case of timers that pull
         -- and we have to check handlers[id] == handler because callbacks may have unregistered things
         if handler.times <= 0 and handlers[id] == handler then

Hey @XyFreak I'm a noob in LUA an OP so what i have to do to solve that problem ?

Edit: I dont know why but IT'S WORKING 

Thank you very much for your work :)

Link to post
Share on other sites
19 hours ago, ZeroNoRyouki said:

Hi there. What exactly happend? I have code in place to convert blocks in existing chunk so your Yellorite Ores should be still there

I'm not exactly sure. I updated the mod and core mod, making sure to pull my ingots and ores out of all containers and kept them in my inventory before I did so. After updating, I wasn't getting any ore-gen in my worlds... I checked the config, and noted all ore-gen was set to false. I updated the config, set everything to true, whitelisted my dimensions, and even deleted the mining dimension entirely, but I still wasn't getting anything. I ended up just using void ore mining (which was on my itinerary anyway) so I've got more than enough yellow goodness to go around. 

Link to post
Share on other sites

So I did start using this program, but I was wondering what something meant as I have not been able to figure out what it is used for and it also never really showed a number for me. 

On the grid page it says Energy Demand(Weighted), but I never seen the weighted part have any sort of number show so I'm not sure what the purpose of this part is?

So is there a best way to get this to work the best way since I been trying to get it to work properly for a while but for some reason there's always somewhere that get's the better of it sadly. So there some sort of order I best do put things to the system or it should not really matter? And how well does the RFtools cell work when it is wirelessly linked all over the place?

Since I been trying it several times and it doesn't seem to really get a good grasp on things since when it says it needs 14,5krf it doesn't seem to activate the proper turbines to make this power happen, and sometimes it just is spinning with the coils off. 

So yeah bit at a loss since it just seems unable to find out what is good and then eventually power is going down so I'm not sure what I'm doing wrong, I connected the reactors and turbines to the computer ports and then did 1 RFtool cell(all of my cells are with those cards that do it wirelessly) with an adapter attached. There anything else that would need to be connected or am I supposed to power them fully down for it to do the best work? 

Link to post
Share on other sites

Hi @GenSmicer

The order to connect everything from a CLEAN INSTALL is:

  • Turn on the turbines to make sure steam can be consumed.
  • Connect the reactor.
  • Wait for calibration to finish.
  • Connect the turbines.

That should be everything you need to do.

What does "it also never really showed a number" mean?

There is indeed an issue with RFTools power storage as it caps out at 2^31-1 RF stored (limitation of the API they use).

Link to post
Share on other sites

AH ok so I guess I never really did it the right way yet lol :p.

And the number did show for the Weighted part just after I posted that so nevermined that one. 

WEll seems to work, just going to see if placing some Thermal Cells is making it react better, since now it only activates a turbine again when the power total drops below 30% or something.

Link to post
Share on other sites

Well it works now but the odd thing is that now that number for the Energy Demand (Weighted) is now not doing anything again. So what does this weighted even mean cause I only seen it do something once in all my attempt so I'm not sure what it is supposed to tell me.

And with RFtools you get the cell to be 1 single huge clump of all the power in that linked card network, but the Thermal Cell one don't do that, so do I need to have all Thermal Cells be connected with an adapter for it to give the best data or is the power storage not even required to be attached?

Link to post
Share on other sites

You need to have all energy storage devices connected that sit immediately behind your generators (note all generators need to be able to feed all of them - dedicated storage devices for each generator are not supported). Intermediary energy devices don't REALLY matter but it'd obviously give the controller a better understanding of how much power you actually have.

The wheighted is a rolling average where the factor is determined by how full your energy storage is ( formular is `wheighted_rft = (1 - (energy_stored / storage_total)) * current_rft + (energy_stored / energy_total) * wheighted_rft` ). That value is then used to determine how much power should be produced. The reasoning behind this is simple: If there's a lot of energy stored, react slowly cause there's energy stored - no need to up fuel consumption, is there? If there's less and less energy, the controller needs to react faster to changes in energy demand to not cause a power failure.

Link to post
Share on other sites

I think I might be doing something wrong. My GUI never updates unless I click a tab at the top.

I have the latest mod versions installed:

  • Extreme Reactors: 1.12.2-0.4.5.65
  • OpenComputers: 1.12.2-1.7.4.153
  • Computronics: 1.12.1-1.6.5
  • Minecraft Forge: 14.23.5.2825

I have others but not sure you want an entire mod dump.

I followed the installation and setup instructions to the letter, even made a new drive and did it again (I have no idea how to empty a drive so I just chuck them in the null and make a new one haha). I spun up the turbines and turned on the reactor, connected the reactor first so it could calibrate. The control rods were then stuck in to 99% and there it stays. 

Sorry if this is a lame excuse for a post but my skills with anything but a pickaxe in Minecraft are lacking, to put it lightly. so I hope you understand what I am explaining/asking.

Regards!

Link to post
Share on other sites
On 4/16/2019 at 1:30 PM, XyFreak said:

@BattyCynris

Sorry for the delay i JUST got the email notification that you posted something. You are running into an OpenOS issue that should be fixed by now (see posts a bit "earlier" on this page). Please update OpenComputers and then reinstall OpenOS.

This fixed it for me. I guess when I updated OpenComputers that OpenOS didn't update.

EDIT: Be certain to run this BEFORE installing BRGC or it will crash your (In-game) computer.

@XyFreak BTW, I love this program. Immensely!

Edited by BattyCynris
added into
Link to post
Share on other sites

@BattyCynris When you update OpenComputers (the mod), It doesn't change what is on the computers, it only changes the contents of the OpenOS floppy disk.

So updating the in-game computer after the mod update only requires you to insert the OpenOS floppy disk and running "install" again.

The tool you linked is basically just for those who can't update their mod (playing on a server with outdated version but need features of a newer version) so don't use it if normal updating is available.

Link to post
Share on other sites
16 hours ago, SpaceBeeGaming said:

@BattyCynris When you update OpenComputers (the mod), It doesn't change what is on the computers, it only changes the contents of the OpenOS floppy disk.

So updating the in-game computer after the mod update only requires you to insert the OpenOS floppy disk and running "install" again.

The tool you linked is basically just for those who can't update their mod (playing on a server with outdated version but need features of a newer version) so don't use it if normal updating is available.

No you have to run that tool. The tool downloads the latest openOS files from github.

Installing your pc with the floppy disk again just updates you to the files the currenly installed mod-version ships, which still contains the regression.

Link to post
Share on other sites
2 hours ago, Gavote said:

So, if I understand correctly, the tool applies a hotfix to the recursion issue? One that is not covered in the current version of OpenComputers?

It is the only thing that allowed my screens to update without being right clicked on. I removed and reinstalled OpenComputers and the issue was not resolved. I updated OpenOS on an existing computer that was already set up but it crashed the (in-game) computer. I had to update a fresh install of OpenOS on an empty drive and then reinstall BRGC.

That the OpenOS that ships with the current version of OpenComputers must not be the latest OpenOS is the only thing I can think to explain the resolution and that the updated version of OpenOS that the updater installs fixes the issue. But you cannot update your existing install of BRGC or the (in-game) computer will crash. So...

1) Install OpenOS on a fresh or erased drive.
2) Download and run the Updater on that link I shared.
3) Download and run the BRGC installer.
4) Profit.

Maybe I just like doing things the hard way or I didn't do something right but this method worked for me. I am only sharing my findings. :-)

Link to post
Share on other sites

@XyFreak: hi there. Could you tell me if you make any assumption about how an actively cooled Reactor shares the available hot fluid between all the connected (output) coolant ports?

Also, you may already noticed it, in the last release of a couple of days ago, I've changed a bit the way power is distribuited to the power taps of a Reactor or Turbine. Now the amount of available power is split equally between the power taps, then they try to send out their share to whatever is connected to them. Any leftover power is left in the internal buffer of the multiblock

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...


×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use and Privacy Policy.