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

Fingercomp

Members
  • Content Count

    132
  • Joined

  • Last visited

  • Days Won

    34

Reputation Activity

  1. Like
    Fingercomp reacted to Zen1th in Minecraft server on OC   
    Not a Minecraft server about OC, but a Minecraft server running on OC. More specifically an 1.15.2 Minecraft server. (btw sorry for low video quality, but 2 Minecraft instances with one modded is CPU-intensive, so..)
     
    Installing
    Just look at the github: https://github.com/zenith391/OCMCS
  2. Upvote
    Fingercomp got a reaction from BrisingrAerowing in OpenSecurity EntityDetector + Door   
    I am sorry, but unless I'm misreading your code, it can't possibly throw an "attempt to index a nil value" error, with any people in proximity or without. And the question is contradictory, stating both that the program crashes and that it freezes (the latter is correct, however). Actually, I'm unsure what the actual question is. Therefore, I'll do the only thing I can here: that is, explain what your code does wrong and how to fix it.
    Before I can proceed to fix the actual issues in the program's logic, I have to get rid of some minor problems. The first such problem is that the code is indented poorly. Of course, Lua doesn't care how you format your code, but it isn't why you do that. Indentation helps you, the program's author, to keep track of what it does, to visually separate chunks of code. And other people benefit from that too, for properly formatted code is much more readable. Without further ado...
    local component = require("component") local colors = require "colors" gpu = require("component").gpu alarm = require("component").os_alarm door = require("component").os_door entity = require("component").os_entdetector local w, h = gpu.getResolution() local delay -- sleep time local player -- list of players while true do os.sleep(2) if entity.scanPlayers(64) == true then scan = entity.scanPlayers(64) name = scan[1].name if name ~= "sav" then door.close() alarm.activate() print("Hello " .. scan[1].name) os.sleep(2) alarm.deactivate() elseif name == "sav" then door.open() alarm.deactivate() print("Welcome Home Sav") os.sleep(2) end os.sleep(4) end end ...And the second thing to take care of is the global variables. Unless you need them such (which rarely happens and this is no exception), make them local. Finally, you've already required component, so there is no reason to do so again; and, while fixing that, let's also remove the unused variables: gpu, colors, delay and player. You can re-add them later yourself if you need.
    local component = require("component") local alarm = component.os_alarm local door = component.os_door local entity = component.os_entdetector local owner = "sav" -- insert your nickname here while true do os.sleep(2) if entity.scanPlayers(64) == true then local scan = entity.scanPlayers(64) local name = scan[1].name if name ~= "sav" then door.close() alarm.activate() print("Hello " .. scan[1].name) os.sleep(2) alarm.deactivate() elseif name == "sav" then door.open() alarm.deactivate() print("Welcome Home Sav") os.sleep(2) end os.sleep(4) end end Great, so now we can start dissecting the code. What does it do?
    First, we require the component library, get proxies of the components we need, and proceed into the main loop. There we first sleep for 2 seconds... Why do we sleep for 2 seconds, again? I'm not sure; let's keep it there for now.
    Then we perform a scan, calling entity.scanPlayers(64), which returns a table, and compare if it is equal to true. Wait. There is no way a table can be equal to true, not unless you mess with metamethods, which we don't. Very suspicious. If we interpret the code literally, we skip the whole if, and end up at the start of the loop again. It's not interesting, so let's pretend that somehow the if's condition is satisfied to understand what the author's intent was.
    And then we perform another scan... hang a minute, another one? Haven't we already done that? Why should we be in dire need of repeating ourselves? Anyway, I think I realized what the code was supposed to do: scan the surroundings and check if there's anyone around. After all, running an alarm without anybody to listen to the marvelous sounds of it is just a waste of energy, isn't it? Let's put it into words in Lua.
    ... while true do local scan = entity.scanPlayers(64) if scan and #scan > 0 then ... else door.close() alarm.deactivate() end os.sleep(2) end We do the scan as soon as we're in the loop. If the scan result is present (neither a false nor a nil), which means the entity detector had no errors, and the length (#) of that table (#scan) is greater than 0 (#scan > 0), then we'll do something about it. The previous sentence is basically how you'd read the code in English.
    Note that if scan happens to be empty, we close the door and disable the alarm. And we shouldn't forget to sleep, for the sake of energy conservation.
    All right, so let's do something about the scan. scan the variable is a table of tables. In other words, scan is a table that stores other tables. Each "other table", in turn, contains information about one player nearby. We have already checked that at least one player is present, but there may be more people gathered around, totally not planning a siege, and we don't yet know whether you are there. You blindly assume you would be the first player in the returned list. Unfortunately, the entity detector couldn't care less about that, and your entry could easily be the second or the last one. Or not present at all, if you happened to carelessly abandon your fortress.
    Our mini-goal is to walk through all the entries of the table (this is called iterating a table) until your entry is found. If after iterating through all items we have yet to found yours, you're not around. So we close the door and activate the alarm. Otherwise, we do the opposite. This is how you do it:
    local ownerNearby = false for _, entry in ipairs(scan) do if entry.name == owner then ownerNearby = true break end end if ownerNearby then door.open() alarm.deactivate() print("Welcome home!") else door.close() alarm.activate() print("Hello, whoever you are.") end Something isn't right... The program will keep spamming "Welcome home!" if you're in vicinity, which isn't quite courteous. Let's make it greet you only if you weren't around before that, and do likewise for greeting intruders. To do that, we need to remember the previous state of your program: whether there was nobody, an intruder, or you.
    local component = require("component") local alarm = component.os_alarm local door = component.os_door local entity = component.os_entdetector local owner = "sav" -- insert your nickname here local previousState = "nobody" while true do local scan = entity.scanPlayers(64) if scan and #scan > 0 then local ownerNearby = false for _, entry in ipairs(scan) do if entry.name == owner then ownerNearby = true break end end if ownerNearby and previousState ~= "owner" then door.open() alarm.deactivate() print("Welcome home!") previousState = "owner" elseif not ownerNearby and previousState ~= "intruder" then door.close() alarm.activate() print("Hello, whoever you are.") previousState = "intruder" end else door.close() alarm.deactivate() previousState = "nobody" end os.sleep(2) end Well, this is the whole program. I didn't test it, so any bugs are yours to find and exterminate.
  3. Upvote
    Fingercomp got a reaction from BrisingrAerowing in OpenSecurity EntityDetector + Door   
    Anything not impossible is possible, and this feature doesn't even require much perseverance to implement.
    Right now we're using owner to store the nickname of one player. We are going to replace it with a table, and therefore the name owner is no longer satisfactory. Let's rename it as trustedPeople and populate it with some test names.
    local trustedPeople = {"player1", "player2", "player3"} A table is the universal record type in Lua, that is, the type that stores multiple values. But we still need to choose the correct data structure. The table trustedPeople is a sequence. This means its elements are stored sequentially, without gaps, and can be accessed using integer indeces (trustedPeople[1], trustedPeople[2], etc.). Such a data structure is useful if we need an ordered collection of items to iterate over, for example. However, this is not the case here. What we need is essentially a set, which stores unique elements and can tell us in an efficient way if a certain value exists. In Lua, sets are usually implemented as follows:
    local trustedPeople = { ["player1"] = true, ["player2"] = true, ["player3"] = true, } The stuff in square brackets is called the key, and what follows after the equals sign is the value. If you have the key, you can quickly determine the associated value, which defaults to nil for nonexistent keys. The most important word is quickly. As for the previous data structure, to find if a table contains a trusted person, we would have to iterate over the sequence of authorized players for every element of the table.
    local ownerNearby = false for _, entry in ipairs(scan) do for _, trusted in ipairs(trustedPlayers) do if entry.name == trusted then ownerNearby = true goto out end end end ::out:: It's very inefficient and complicated. Now, compare it with the code that we would write if we use a set for trustedPlayers:
    local ownerNearby = false for _, entry in ipairs(scan) do if trustedPlayers[entry.name] then ownerNearby = true break end end  
    However, I like how easy it is to modify the sequence in the code. {"one", "two", "three"} is much more concise than {["one"] = true, ["two"] = true, ["three"] = true}. I'll make it so that we could specify the list of allowed people, and it would be converted to a set by the program.
    local trustedPeople = {"player1", "player2", "player3"} for index, nickname in ipairs(trustedPeople) do trustedPeople[nickname] = true trustedPeople[index] = nil end  
    Let's incorporate all of that in the original program.
    local component = require("component") local alarm = component.os_alarm local door = component.os_door local entity = component.os_entdetector local trustedPeople = {"player1", "player2", "player3"} for index, nickname in ipairs(trustedPeople) do trustedPeople[nickname] = true trustedPeople[index] = nil end local previousState = "nobody" while true do local scan = entity.scanPlayers(64) if scan and #scan > 0 then local shouldOpen = false for _, entry in ipairs(scan) do if trustedPeople[entry.name] then shouldOpen = true break end end if shouldOpen and previousState ~= "allowed" then door.open() alarm.deactivate() print("Welcome home!") previousState = "allowed" elseif not shouldOpen and previousState ~= "intruder" then door.close() alarm.activate() print("Hello, whoever you are.") previousState = "intruder" end else door.close() alarm.deactivate() previousState = "nobody" end os.sleep(2) end I've also changed a couple of names so that they would reflect their purpose.
  4. Upvote
    Fingercomp got a reaction from Molinko in OpenSecurity EntityDetector + Door   
    Anything not impossible is possible, and this feature doesn't even require much perseverance to implement.
    Right now we're using owner to store the nickname of one player. We are going to replace it with a table, and therefore the name owner is no longer satisfactory. Let's rename it as trustedPeople and populate it with some test names.
    local trustedPeople = {"player1", "player2", "player3"} A table is the universal record type in Lua, that is, the type that stores multiple values. But we still need to choose the correct data structure. The table trustedPeople is a sequence. This means its elements are stored sequentially, without gaps, and can be accessed using integer indeces (trustedPeople[1], trustedPeople[2], etc.). Such a data structure is useful if we need an ordered collection of items to iterate over, for example. However, this is not the case here. What we need is essentially a set, which stores unique elements and can tell us in an efficient way if a certain value exists. In Lua, sets are usually implemented as follows:
    local trustedPeople = { ["player1"] = true, ["player2"] = true, ["player3"] = true, } The stuff in square brackets is called the key, and what follows after the equals sign is the value. If you have the key, you can quickly determine the associated value, which defaults to nil for nonexistent keys. The most important word is quickly. As for the previous data structure, to find if a table contains a trusted person, we would have to iterate over the sequence of authorized players for every element of the table.
    local ownerNearby = false for _, entry in ipairs(scan) do for _, trusted in ipairs(trustedPlayers) do if entry.name == trusted then ownerNearby = true goto out end end end ::out:: It's very inefficient and complicated. Now, compare it with the code that we would write if we use a set for trustedPlayers:
    local ownerNearby = false for _, entry in ipairs(scan) do if trustedPlayers[entry.name] then ownerNearby = true break end end  
    However, I like how easy it is to modify the sequence in the code. {"one", "two", "three"} is much more concise than {["one"] = true, ["two"] = true, ["three"] = true}. I'll make it so that we could specify the list of allowed people, and it would be converted to a set by the program.
    local trustedPeople = {"player1", "player2", "player3"} for index, nickname in ipairs(trustedPeople) do trustedPeople[nickname] = true trustedPeople[index] = nil end  
    Let's incorporate all of that in the original program.
    local component = require("component") local alarm = component.os_alarm local door = component.os_door local entity = component.os_entdetector local trustedPeople = {"player1", "player2", "player3"} for index, nickname in ipairs(trustedPeople) do trustedPeople[nickname] = true trustedPeople[index] = nil end local previousState = "nobody" while true do local scan = entity.scanPlayers(64) if scan and #scan > 0 then local shouldOpen = false for _, entry in ipairs(scan) do if trustedPeople[entry.name] then shouldOpen = true break end end if shouldOpen and previousState ~= "allowed" then door.open() alarm.deactivate() print("Welcome home!") previousState = "allowed" elseif not shouldOpen and previousState ~= "intruder" then door.close() alarm.activate() print("Hello, whoever you are.") previousState = "intruder" end else door.close() alarm.deactivate() previousState = "nobody" end os.sleep(2) end I've also changed a couple of names so that they would reflect their purpose.
  5. Upvote
    Fingercomp got a reaction from SavageNoob in OpenSecurity EntityDetector + Door   
    I am sorry, but unless I'm misreading your code, it can't possibly throw an "attempt to index a nil value" error, with any people in proximity or without. And the question is contradictory, stating both that the program crashes and that it freezes (the latter is correct, however). Actually, I'm unsure what the actual question is. Therefore, I'll do the only thing I can here: that is, explain what your code does wrong and how to fix it.
    Before I can proceed to fix the actual issues in the program's logic, I have to get rid of some minor problems. The first such problem is that the code is indented poorly. Of course, Lua doesn't care how you format your code, but it isn't why you do that. Indentation helps you, the program's author, to keep track of what it does, to visually separate chunks of code. And other people benefit from that too, for properly formatted code is much more readable. Without further ado...
    local component = require("component") local colors = require "colors" gpu = require("component").gpu alarm = require("component").os_alarm door = require("component").os_door entity = require("component").os_entdetector local w, h = gpu.getResolution() local delay -- sleep time local player -- list of players while true do os.sleep(2) if entity.scanPlayers(64) == true then scan = entity.scanPlayers(64) name = scan[1].name if name ~= "sav" then door.close() alarm.activate() print("Hello " .. scan[1].name) os.sleep(2) alarm.deactivate() elseif name == "sav" then door.open() alarm.deactivate() print("Welcome Home Sav") os.sleep(2) end os.sleep(4) end end ...And the second thing to take care of is the global variables. Unless you need them such (which rarely happens and this is no exception), make them local. Finally, you've already required component, so there is no reason to do so again; and, while fixing that, let's also remove the unused variables: gpu, colors, delay and player. You can re-add them later yourself if you need.
    local component = require("component") local alarm = component.os_alarm local door = component.os_door local entity = component.os_entdetector local owner = "sav" -- insert your nickname here while true do os.sleep(2) if entity.scanPlayers(64) == true then local scan = entity.scanPlayers(64) local name = scan[1].name if name ~= "sav" then door.close() alarm.activate() print("Hello " .. scan[1].name) os.sleep(2) alarm.deactivate() elseif name == "sav" then door.open() alarm.deactivate() print("Welcome Home Sav") os.sleep(2) end os.sleep(4) end end Great, so now we can start dissecting the code. What does it do?
    First, we require the component library, get proxies of the components we need, and proceed into the main loop. There we first sleep for 2 seconds... Why do we sleep for 2 seconds, again? I'm not sure; let's keep it there for now.
    Then we perform a scan, calling entity.scanPlayers(64), which returns a table, and compare if it is equal to true. Wait. There is no way a table can be equal to true, not unless you mess with metamethods, which we don't. Very suspicious. If we interpret the code literally, we skip the whole if, and end up at the start of the loop again. It's not interesting, so let's pretend that somehow the if's condition is satisfied to understand what the author's intent was.
    And then we perform another scan... hang a minute, another one? Haven't we already done that? Why should we be in dire need of repeating ourselves? Anyway, I think I realized what the code was supposed to do: scan the surroundings and check if there's anyone around. After all, running an alarm without anybody to listen to the marvelous sounds of it is just a waste of energy, isn't it? Let's put it into words in Lua.
    ... while true do local scan = entity.scanPlayers(64) if scan and #scan > 0 then ... else door.close() alarm.deactivate() end os.sleep(2) end We do the scan as soon as we're in the loop. If the scan result is present (neither a false nor a nil), which means the entity detector had no errors, and the length (#) of that table (#scan) is greater than 0 (#scan > 0), then we'll do something about it. The previous sentence is basically how you'd read the code in English.
    Note that if scan happens to be empty, we close the door and disable the alarm. And we shouldn't forget to sleep, for the sake of energy conservation.
    All right, so let's do something about the scan. scan the variable is a table of tables. In other words, scan is a table that stores other tables. Each "other table", in turn, contains information about one player nearby. We have already checked that at least one player is present, but there may be more people gathered around, totally not planning a siege, and we don't yet know whether you are there. You blindly assume you would be the first player in the returned list. Unfortunately, the entity detector couldn't care less about that, and your entry could easily be the second or the last one. Or not present at all, if you happened to carelessly abandon your fortress.
    Our mini-goal is to walk through all the entries of the table (this is called iterating a table) until your entry is found. If after iterating through all items we have yet to found yours, you're not around. So we close the door and activate the alarm. Otherwise, we do the opposite. This is how you do it:
    local ownerNearby = false for _, entry in ipairs(scan) do if entry.name == owner then ownerNearby = true break end end if ownerNearby then door.open() alarm.deactivate() print("Welcome home!") else door.close() alarm.activate() print("Hello, whoever you are.") end Something isn't right... The program will keep spamming "Welcome home!" if you're in vicinity, which isn't quite courteous. Let's make it greet you only if you weren't around before that, and do likewise for greeting intruders. To do that, we need to remember the previous state of your program: whether there was nobody, an intruder, or you.
    local component = require("component") local alarm = component.os_alarm local door = component.os_door local entity = component.os_entdetector local owner = "sav" -- insert your nickname here local previousState = "nobody" while true do local scan = entity.scanPlayers(64) if scan and #scan > 0 then local ownerNearby = false for _, entry in ipairs(scan) do if entry.name == owner then ownerNearby = true break end end if ownerNearby and previousState ~= "owner" then door.open() alarm.deactivate() print("Welcome home!") previousState = "owner" elseif not ownerNearby and previousState ~= "intruder" then door.close() alarm.activate() print("Hello, whoever you are.") previousState = "intruder" end else door.close() alarm.deactivate() previousState = "nobody" end os.sleep(2) end Well, this is the whole program. I didn't test it, so any bugs are yours to find and exterminate.
  6. Like
    Fingercomp reacted to BrightYC in Cyan BIOS   
    The world as I knew it had a problem.
    A plenty of bootloaders had already existed, and they'd all shared the same flaw: it wasn't me who made them.
    I've decided to put an end to that.


    Cyan is a multi-bootloader and a replacement for the plain Lua BIOS. The features it encompasses include:
    a whitelist to prevent random strangers from tampering with the computer a Lua interpreter to test your sudden ideas support for hot-plugging filesystems if you've forgot to insert a floppy the ability to format or label a filesystem, while we're at it loading the boot payload from the internet when you can't afford an HDD and a gorgeous, minimalistic design Pictures:


    To install on OpenOS, run the following:
    wget -fq https://raw.githubusercontent.com/BrightYC/Cyan/master/installer.lua && installer.lua Or, if you're a MineOS user, look for the program (bearing the same name) at your local AppMarket.
    Here's how the whitelist works. You add trusted users to the list when the installer asks you. Then the bootloader will ignore any signals from other people. That's it.
    Oh, and you can also choose a less restrictive option: the Cyan BIOS can wait for input from a trusted user. Before that an authorized person can't access the bootloader.
    Lastly, a couple of words about the Lua interpreter. It doesn't wrap the output, and the input command must be less than the screen width. The last restriction can be circumvented by copy-pasting the command.
    In addition to that, the bootloader defines the following functions:
    os.sleep([timeout: number]) proxy(componentName: string): table or nil — returns a component proxy by its name (cf. component.proxy, which takes an address) read(lastInput: string or nil): string or nil — a primitive io.read() print(...) The source code for the curious: https://github.com/BrightYC/Cyan
    P. S. Big thanks to @Fingercomp for his lecture about string escapes and writing this text.
     
  7. Like
    Fingercomp reacted to TuxMan20 in Ctif-Present (A simple fork of Ctif-View for presentations and keynotes)   
    Hello!
    With the situation being what it is, and many companies (including my employer) having remote meetings, I wanted something original for presenting slides. I was blown away by the Better Than Minecon presentation and I wanted to use that!
    So I took to Minecraft and recreated our meeting room. Problem was, the BTM program wasn't released publicly, so I needed to create my own solution. Luckily, Asie's CTIF Viewer was already doing all the heavy lifting (Actually showing pictures to the screen). Only thing missing was a way to cycle through multiple pictures. On Discord, Forecaster and The_Stargazer suggested to simply modify the Lua file... so... here we are!
    pastebin.com/fKpwFwfd
    It's REALLY basic, but it gets the job done. 
    Instructions:
    Download the Lua file to your /bin or /usr/bin. Create a folder, put only your ctif images inside. Name them in numerical order you want them to appear (0.ctif, 1.ctif, 2.ctif...). From within the folder, run the program. 
    Click/Touch the screen for next slide. Ctrl+C to interrupt (exit)
    The resolution is still REALLY low so make sure to use big letter (or avoid text on your slide if you can). 
    I used the Aperture mod to lock the camera in place so my avatar would be in front of the screen and the view would stay fixed, then shared my screen on our video conferencing app. I've got to say it worked well! The hardest part in a virtual meeting is having people's attention, and ..well... people were intrigued. So.. mission accomplished? 

  8. Like
    Fingercomp reacted to Zen1th in Lukyt - Java on OpenComputers (without mod)   
    A while ago i made a JVM in Lua with the first goal of running Java on OC, just because i like Java and we all know it's a good programming language.
    So here's the JVM running a program that fills GPU:

    Oops, made a typo.

    Ok at first this might not seem impressive at all, but now you can interact with components using Java! That's an awesome thing for Java-ers like me!
    Race to first Java OS in OC? Anyone?
    Here's the (simple) code i used above
    import lukyt.oc.Component; public class ComponentTest { public static void main(String[] args) { String gpu = Component.getPrimary("gpu"); Component.invoke(gpu, "setBackground", new Object[] {0x2D2D2D}); Component.invoke(gpu, "fill", new Object[] {1, 1, 160, 50, " "}); System.out.println("Filled screen with RGB 0x2D2D2D"); } } Here's GitHub page (to download and use on your favourite OC computer): https://github.com/zenith391/lukyt
  9. Like
    Fingercomp reacted to Gabiiel in Scientific approach to Geolyzer   
    Due to quarantine, I got a bunch of time in my hands, I remember that since I first used this mod, back in MC 1.7 we had this phrase on Geolyzer description
     "It is theoretically possible to eliminate this noise by scanning repeatedly and finding an average. (Unconfirmed, needs further testing.)"
    Now, many years later, i do know quite some about statistics and got plenty of time
    So, lets begin
     
    We begin our dive in Statistics with an hypothesis, Does this number measured relate to an ore or stone, putting it in hardness terms, does the true number of hardness equal to 3(ores) or 1.5(stone), now we estabilish our null hypothesis. The null hypothesis is which one of them I want to minimize the most(it will make more sense in a bit), I prefer to avoid losing ores, therefore my null hypothesis is that the true hardness of the number measured=3 unless proven with enough evidence the contrary(again, more sense later)
    In statistic we have two kind of erros given in the table below, we want to minimize error type 1 even if type 2 grows, not so much as for example, mark every where as ore, 0 type 1 error and 100% of type 2. Or be it random where both errors are 50%,  so we have to have a small type 1 error without gigantic type 2 error ,let's try. I will from now on ommit "error" in type1 error.

     
    Let's first analyze on what I believe is the most traditional way, checking if a number is bigger than a threshold , I made a code to help me with that(DataCollector), given a line of 32 blocks, it will go through each one of them, measure 1000 times, and separate in intervals of 0,25. The result is given as every number smaller than the first column 

    It's quite hard to see it all, comparing it with a stone would be disastrous, but we can clearly see a pattern of every 4th increasing in one more row, so make it goes from 0 to 4, to 8 to... to 56, when possible I tried to use an exact distance, for example 40=sqrt(12^2+32^2) when not possible a very close number 56=sqrt(32^2+32^2+32^2), compare stones and ores side by side and we get this:

    based on this we can see the strengths and weakness of a single or multiple threshold, in my code I tried to give a general approach, so if you want to detect any other pair it's possible. 
    In my code, I used 2 variables, one to know the value when they meet, the distance where they meet, given by (Hhard-Lhard)*8, the second one is Havg, (Hhard+Lhard)/2, it gives the number when they meet. If the distance is smaller than "meet", the value will be bigger or lower than Havg but I will be sure after this check
    If we use a single threshold of >2.25 we would be fine up to 12, after our errors would be:
    16: type1=10.9% ; type2=11.4% | 20: type1=21.7% type2=19.2% | 24:type1=24.7% type2=23.9% | 28: type1=29.8% type2=26.7% | 32:type1=29.6% type2=32.7%
    As we can see, not good, not terrible
     if we want to be sure that its a stone or an ore, we must know what is the distance, find this new threshold, it could be done for each one of them but I dont see a particular distribution, but every 4 distance we have a good approximation of a uniform distribution( where every value is as likely to happen), but between  them it wont affect that much the chance of being wrong, type1 and type2 errors are equal to:
    16: 24% | 20: 42% | 24: 50.4% | 28: 58.1% | 32: 61.8% | 36: 65.8% | 40: 70.5% | 44:73.9% | 48: 75.4% | 56: 78.5%
    it seems bad to do it that way, we said earlier that our objective is to minimize type1 error, but we can use multiple measurements to decrease the error, we were already going to do that anyway for our second kind of analysis, I chose to do 6 but you can pick another number, I tried to make it easy to change in the code, butt keep in mind that every measurement takes a lot of time and energy, using the geolyzer is time consuming, for each time you add 55 seconds to scan, default(6) is about 5min 30s. The new errors after six times are, (error)^6:
    16: 0.1% | 20: 0.5%  | 24: 1.6%  | 28: 3.8% | 32: 5.6% | 36: 8,1% | 40: 12.2% | 44: 16% | 48: 18% | 56: 23.4%
    This is already much better, lower error compared to previus test, but this is still very high, we always have 32 distance, the height, with each command and with this test we would have a high chance missing anything, the robot would have to go around or increase the number of tests that adds up for a lot of time and energy, for such a poor result
    Now we begin using statistical theory, for that we need to know how the variance behaves given a distance, using Variance.lua code changing x and y and Variance1.lua to Z axis. This code gives Standard Deviation this represents how much from the mean it can be.

    plotting it in a graph we get that the standard deviation is given by approximately 0.35*distance. https://www.khanacademy.org/math/statistics-probability/sampling-distributions-library#what-is-a-sampling-distribution as this free class explains, the distribution of samples is a normal distribution, doesn't matter the original distribution. to visualize it, using DataCollector.lua code add ore nSamples to your code, default is 1, therefore it shows the original distribution now I am doing it with 6 samples

    the threshold for the average to given the Z value on the Ztable below is given by -Z*StandardDeviation(0.035*distance)/sqrt(nSamples(6)) + oreHardness(3)=OreT, Z is my type 1 error, my type2 error is given by StoneHardness*sqrt(nSamples)/(Z{positive now}*SD)=OreT. This is all a mess I know, lets give it some numbers, let's get a Z value equivalent of 5% wich is about 1.64 or 1.65, I will go with 1.64, distance of 56, we get -1.64*1.96/2.44+3=1,68, to find our type2 error we have Z=1.5*2.44/(1.96*1.68)=1.116 which is equal to 13.1%
    16: type1=5% type2=0.6% | 20: type2=1.9% | 24: 3.6% | 28: 5.3% | 32: 7.2% | 36: 8.8% | 40: 10% | 44:  11% | 48: 12% | 52: 13% | 56: 13,5%

    We can see that this is the best analysis until now overall, mainly on bigger distances, also even though its hard to understand, its super easy to implement it on code, but this analisys and the last one can be thought as independent events if we do both analysis we significantly lower the chance of any error for 56 distance we have type1=1.1% type2= 3.5%, wich is super low, but for my code I chose to do it until 40 of distance or 32^2+32^2+16^2=40^2, for me 1.1% is huge yet and 16*32*32 is enough volume but you can tune it to whatever you like
    I want to bring to attention that the code of both analysis was done with the ability of taking any pair in mind, be it dirt and stone or stone and ore, or ore and diamond block, it must have a decent enough interval tho. also it checks for anything lower than stone or bigger than ore, must do another analysis to remove the ones you want from it.
    https://github.com/gabiiel/GeolyzerOreFinder
    PS: I am not a professional coder or anything like that, I just wanted to burn some quarantine time, any questions or improvements or features, I am willing to help. I hope everyone could understand. Also I am leaving up to you guys how to get to the ores, this is a very low end program that can run on any machine, the ores are stored in a string there is a function to help write and read from it
    DataCollector.lua variance.lua variance1.lua
  10. Like
    Fingercomp got a reaction from BAT54 in Can't change max screen size in the config   
    I had this problem quite a long time ago, and I think I fixed it by also updating the settings client-side to match those on the server.
  11. Like
    Fingercomp got a reaction from MoonlightOwl in IRC library   
    There was no IRC library for OpenComputers, so I've made one. Here's a demo bot that uses it:
    local com = require("component") local event = require("event") local thread = require("thread") local gpu = com.gpu local irc = require("irc") local events = irc.events local env = setmetatable({ irc = irc, events = events, }, {__index = _G}) local client = irc.builder() :connection { host = "irc.esper.net:6667", throttling = { maxDelay = 2, maxThroughput = 5, }, } :auth { nickname = "oc-finger-irc", username = "fingercomp", realname = "OpenComputers IRC client library", } :bot { channels = {"#oc-finger-irc"}, tracking = { users = true, modes = true, account = true, userInfo = true, }, } :execution { threaded = true, reconnect = true, catchErrors = true, } :subscribe(events.irc.command, events.priority.high, function(self, client, evt) gpu.setForeground(0x00ff00) print("→ " .. evt.rawLine) gpu.setForeground(0xffffff) end) :subscribe(events.irc.write, events.priority.normal, function(self, client, evt) gpu.setForeground(0x00dbff) print("← " .. evt.line:gsub("[\r\n]*$", "")) gpu.setForeground(0xffffff) end) :subscribe(events.irc.message, irc.events.priority.normal, function(self, client, evt) if evt.source.nickname == "fingercomp" then if evt.message == "::quit" then evt:reply("Quitting.") evt.client:stop(("%s told me to quit."):format(evt.source.nickname)) elseif evt.message == "::spam" then evt:reply("1") evt:reply("2") evt:reply("3") evt:reply("4") evt:reply("5") elseif evt.message == "::longmsg" then local msg = {} for i = 1, 256 do if i == 128 then table.insert(msg, tostring(i) .. " ") else table.insert(msg, tostring(i)) end end evt:reply(table.concat(msg)) elseif evt.message == "::error" then (nil).test() elseif evt.message:sub(1, #"::exec ") == "::exec " then local code = evt.message:sub(#"::exec " + 1) local chunk, reason = load("return " .. code, "=irc", "t", env) if not chunk then chunk, reason = load(code, "=irc", "t", env) end if not chunk then evt:reply(("\x0304Error:\x0f %s"):format(reason)) else local result = table.pack(xpcall(chunk, debug.traceback)) local success = table.remove(result, 1) result.n = result.n - 1 for i = 1, result.n, 1 do if type(result) ~= "string" and type(result) ~= "number" and type(result) ~= "boolean" and type(result) ~= "nil" then result[i] = tostring(result[i]) else result[i] = ("%q"):format(result[i]):gsub("\\\n", "\n") end end if not success then evt:reply(("\x0304Error:\x0f %s"):format(result[1]:match("^[^\n]*"))) io.stderr:write(("%s\r\n"):format(result[1])) elseif result.n > 0 then evt:reply(table.concat(result, " ", i, result.n)) else evt:reply("\x0309Success") end end end end end) :subscribe(events.irc.ctcpRequest, irc.events.priority.normal, function(self, client, evt) if evt.ctcpCommand == "TIME" then evt:reply(os.date("%F %T")) end end) :subscribe(events.client.error, irc.events.priority.top, function(self, client, evt) print("Caught: " .. evt.traceback) evt:cancel() end) :build() local t = thread.create(function() repeat local evt = event.pull("interrupted") until evt end) env.client = client client:run() thread.waitForAny({t, client.thread}) client:stop("Quitting.") os.exit() I don't want to brag about it too much, but I think the code is pretty.
    Features
    Threaded execution. A nice API. IRCv3.2 capability negotiation. Throttling to prevent the bot from triggering anti-flood mechanisms. Tracks channel members, modes, nick changes, account names, etc. Automatically reconnects if it's disconnected from the IRC server. Splits long messages over multiple lines. The event bus can use coroutines as message handlers. Links
    The GitLab repository: https://gitlab.com/cc-ru/irc-oc Documentation: https://gitlab.com/cc-ru/irc-oc/-/wikis/home Demo programs: https://gitlab.com/cc-ru/irc-oc/snippets
  12. Like
    Fingercomp reacted to MoonlightOwl in Stem - easy internet bridge   
    What is STEM?
    Did you ever want to have a linked card, but without this pair-to-pair limitations?
    Well, you have internet card. And that is already half of the solution. The other half is to use Stem.

    Stem is a message transmitter for your OpenComputers devices with internet cards.
    Using a small OpenOS library you can use Stem to send and receive messages. Unlike the standard `modem` component, Stem-messaging uses not addresses, but `channels`. You can send messages to any channels, and you can subscribe to any number of channels to listen for messages from them.
    Installation
    The best way is to use HPM:
    hpm install stem If you do not have HPM, install it like this:
    pastebin run vf6upeAN If you do not want to use HPM repository, you can just use wget:
    wget https://gitlab.com/UnicornFreedom/stem/raw/master/stem.lua Example of a program using STEM
    local event = require('event') -- use STEM client library local stem = require('stem') -- open a connection to a STEM server -- the `stem.fomalhaut.me` is a default one local server = stem.connect('stem.fomalhaut.me') -- subscribe for messages from the channel with ID 'my-channel-id' server:subscribe('my-channel-id') -- then listen for events in a loop... while true do local name, channel_id, message = event.pull('stem_message') if name ~= nil then print(channel_id, message) end end -- ...or register an event listener event.listen('stem_message', function(_, _, channel_id, message) print(channel_id, message) end) -- you can also send message to the channel -- (you do not need to be subscribed to this channel, to send a message) server:send('my-channel-id', 'hello there') -- unsubscribe from channel server:unsubscribe('my-channel-id') -- completely close the connection to the STEM server server:disconnect()  
    That is all.
    But there is more.
    Web client
    If you open the link to Stem server in your browser: https://stem.fomalhaut.me/
    You will see some statistics and the web client. Enter your channel ID into the form, and you can send messages to your robot in real time, right from your phone, without even starting Minecraft.

    The web client is limited with UTF-8 encoding, though.
    (Using OpenOS you can send literally anything, as long as the message fits in 64kb of data.)
    Security Questions
    The channels by default do not have any special security measures applied. They do not have any authentication mechanisms, the do not have any encryption.
    Anyone who knows the ID of a channel can send a message to it and can listen for responses. But.
    The length of ID is 256 bytes. And that can be any bytes - from 0 to 255. That means, that you have 256^256 possible combinations for your ID. And that is a giant number. If you need to secure your channel - just use something long and incomprehensible as your ID.
    As an additional measure you can use end-to-end encryption, or anything else - this is up to you.
    Default STEM server uses HTTPS, and does not store any information - message in, message out.
    Self-hosted STEM solution
    For those of you who are strong in spirit and computer knowledge - there is a self-hosted option. You can build Stem server from sources and run it on your machine.
    This is also pretty easy. Additional instructions can be found on GitLab.
    Useful links
    GitLab repository: https://gitlab.com/UnicornFreedom/stem
    Protocol description: https://gitlab.com/UnicornFreedom/stem/wikis/protocol
    Default server: https://stem.fomalhaut.me/
    HPM package: https://hel.fomalhaut.me/#packages/stem
     
    If I forgot something - feel free to ask here, or in IRC (my nickname is Totoro there). Also the project contains at least one "Easter egg" feature, that can offer some interesting options if you know HTML/CSS/JS.
    The Stem protocol is open - you can modify it, you can create your own clients in any programming language, etc.
  13. Like
    Fingercomp reacted to Log in GPS on microcontrollers   
    Program and library for building GPS network.
    https://github.com/DOOBW/OC-GPS
    Download:
    wget https://raw.githubusercontent.com/DOOBW/OC-GPS/master/usr/bin/gps.lua /bin/gps.lua
    wget https://raw.githubusercontent.com/DOOBW/OC-GPS/master/usr/lib/gps.lua /lib/gps.lua
    The functionality is the same as in the ComputerCraft.
    Additional command "flash" allows to upload firmware to EEPROM.
    When the coordinates are precisely determined, when flashing the position of the microcontroller can be omitted - at the first start it will determine its position from neighboring satellites and save on EEPROM.
    GPS network startup example.
     
  14. Upvote
    Fingercomp reacted to evg-zhabotinsky in Preemptive multitasking and sysyield timeouts   
    This is a suggestion on how and why to rework OC's sysyield timeouts. The required fixes basically give ability to implement preemptive multitasking for free.
    1. Current implementation of sysyield timeouts is insufficient
    Currently, it is not a real protection against executor thread hogging. It is only a safeguard, and a very efficient one.
    Consider the following code:
    local function dos() while true do end end while true do pcall(coroutine.resume, coroutine.create(dos)) computer.pullSignal(0) end Flash it onto a EEPROM, and throw that into a bare T1 case with just a CPU, a smallest RAM stick, and some power to keep it going.
    Turn on that computer, and you have a hogged a single executor thread until someone shuts it down. Boot some more computers off the same EEPROM, and you can easily hog all executor threads on a server.
    On default config, running just 4 of such hogs makes other computers practically unusable, every sysyield causes a 5 second delay.
    Tweaking the timeout won't really help, since then programs will have to pull(0) much more often, and in the presence of such hogs every yield will cause a delay.
    Just killing the whole machine when it starts hogging executors won't help in some cases, specifically if computer is turned on by WoL, redstone signal or another computer.
    Even though it's highly unlikely, such hogging can happen accidentally. Specifically, if a system is built so that it restarts on unknown errors, sysyield timeout will not stop an accidental infinite loop in it.
    2. How it is currently implemented
    I don't think I have a complete understanding yet, but that's how I see it:
    The coroutine library is wrapped:
    coroutine.yield() adds an extra nil as the first value, to differentiate normal yields from sysyields coroutine.resume() repeatedly does following: Call sethook() on the coroutine to terminate it on a sysyield timeout Call the real coroutine.resume() If the first returned value is nil (i.e. normal yield), return the rest Otherwise (i.e. sysyield), yield all values and continue the loop Therefore, when sysyield happens (i.e. on computer.pullSignal), the whole stack of running coroutines is unwound, and the outermost one yields the computer. On the next tick, or whenever a signal comes, the computer is resumed, and the same stack of coroutines is rebuilt, and the innermost one continues its execution.
    The hook that is attached to each coroutine checks if computer has been running for too long, and throws an error if so, which terminates the currently running coroutine. It also extends the deadline by half a second exactly once, so that the parent coroutine has a chance to recover. So long as it does a sysyield in those half a second, or yields/returns and lets its parents do that, the deadline is reset and the computer can continue operating. If it does not, the remaining parent coroutines do not get a chance to recover, and the computer is halted with an error. And until the innermost coroutine times out, nothing can stop it unless it yields control.
    For example, if you type while true do end in the LUA repl, it will start that code in a coroutine and print an error message when it times out. If that same loop is explicitly started inside a coroutine, the error is caught and another infinite loop is started, the REPL will not get a chance to do anything, and the whole computer will crash.
    3. The suggested implementation
    The basic problem is, the hook set by Lua code with debug.sethook() cannot yield a coroutine. It can only throw an error, terminating the coroutine, therefore the timeout has to be long enough to let the program do whatever it needs to without doing sysyields all the time. This is problematic, since all the computers share the same few executor threads, and the timeout also has to be short enough to allow other computers to run normally.
    However, the debug hooks actually can yield, under certain very restrictive conditions: https://www.lua.org/manual/5.3/manual.html#lua_Hook The catch is, it can only happen from the native code (C for normal Lua, probably Java for LuaJ), and no values can be returned. I've written a simple test library in C to allow setting yieldable Lua hooks from Lua code: https://github.com/evg-zhabotinsky/yieldhook I tried to implement it myself at first, but then realized that I'm reimplementing debug.sethook... So I just copied it, cut out the unneeded bits and added a loader. If possible, it's probably cleaner to modify the original Lua library (ldblib.c for C version, not sure about LuaJ).
    The final interface of the modified debug.sethook() is that if hook mask contains an 'y', event is either 'line' or 'count' and the hook function returns truth, the paused coroutine is yielded with no values, i.e. coroutine.resume() returns just true. The normal return from coroutine with no arguments can be differentiated from a hook yield by checking if coroutine is now dead, and the normal yields can be wrapped to prepend an extra true value.
    tl;dr: see the test program in my repo, it demonstrates a simple preemptive multitasking implementation. Its wrapper for coroutine.resume returns:
    true plus the values on normal yield or return false plus the error message on error nothing on a hook yield (that's what different from the standard behavior) It should be pretty easy to modify the OC's existing wrapper and hook functions to sysyield instead of throwing an error on timeout. That timeout can then be made much shorter, since coroutines are no longer terminated. Preferably, it should be adjusted dynamically by machine.lua, so that cycles are distributed fairly (incl. according to CPU and memory tiers) with no leftovers and each computer runs exactly once every tick. Preferably, something like computer.getSliceTime() and computer.getRemainingTime() should return how much time the computer has been assigned during the tick and how much of it is left. The units of those functions can be declared "abstract cycle amounts" for the sake of "realism", in which case the slice time will be CPU frequency (quite unstable, just like the tooltip suggests xD) and the remaining time will be cycle count until the next bus synchronization or whatever.
    Having done that, there basically will be preemptive multitasking between all the computers, and none of them will have to wait long for their turn to run. For compatibility, the current "die if hung for 5s" behavior can be implemented in OpenOS, and allowed to be disabled for the sake of "power users".
    To allow for user-controlled preemptive multitasking on a single computer, I propose adding computer.setTimeout(time, coroutine), with time being the same units as computer.remainingTime() and coroutine being the timeout handler coroutine. The debug hook will work all the same, except it will yield prematurely if the soft deadline happens to be earlier. The wrapped coroutine.resume() will see that a timeout has happened, but hard timeout hasn't expired yet, and instead of yielding any further will disable soft timeout and resume the specified coroutine. The coroutine.status() has to be wrapped too to mark the "yielded by hook" coroutine as "normal", as if it called resume() on the handler coroutine. While the handler coroutine is running, soft timeouts are ignored. When it yields, the paused coroutine is resumed and soft timeout is enablet, if it was set again by the handler. However, if there is a pending soft timeout, the handler coroutine is immediately resumed again.
    The setTimeout behavior suggested above matches closely how a timer interrupt would be handled in a real CPU, exactly what machine.lua should contain. The rest of multitasking implementation and protection is on the OS.
    Apart of implementing a scheduler, synchronization mechanisms have to be implemented. Count hook can trigger in the middle of any non-trivial expression, so normal assignments cannot be used for unconditionally reliable synchronization. However, a coroutine cannot be resumed unless it's suspended, and everything on a computer runs in a single Lua state, so any coroutine body is a natural critical region, which can easily be leveraged to implement any kind of synchronization.
    4. Who is going to implement all that?
    Given some time, I can implement the Lua side of things. The native side, though... I'm afraid to break something there, and even though I've done the same modifications for the official Lua implementation, I don't know yet how to do the same for JNLua and LuaJ and in the context of OpenComputers specifically. Plus, I'm not keen on rebuilding OpenComputers from source. If someone confirms that there's nothing to learn or break and that it should just work, I'll probably do that too.
    Once the core functionality is implemented, I'm thinking more like implementing a more Unix-like OS, aiming for POSIX compatibility, and the ability to implement proper preemptive multitasking is a must for that. The ultimate goal is to be able to compile and run most normal C programs without modifications. I'm already working on a primitive C to Lua compiler, because I gave up porting a simplistic MP3 decoder to Lua by hand. (I want to have online radio in my bunker!)
    Aaanyway, comments and suggestions are welcome. I was more interested in the technical part, so I haven't really though much about API function names or how exactly to divide time among computers of different tiers, so there's that. (Also, is there a way to figure out tiers of arbitrary component from inside the computer?) I didn't think at all about how OpenOS would provide preemptive multitasking to its programs, too, and I have absolutely no idea if it would crash and burn when anything starts running "in parallel".
  15. Like
    Fingercomp reacted to TetraSource in Bundle - allows to use multiple filesystems as a single one   
    I just finished the first version of bundle - a rc application which virtually merges multiple filesystems into a bigger one. You can use it whenever a RAID full of tier 3 HDD isn't enough for your needs. On the picture above, for example, you can see 10 RAIDs with 30 tier 3 HDDs which yield a virtual HDD that can store over 200MB of data. You can also use filesystems of different size and create files bigger than any of the used filesystems since bundle is capable of storing a file on multiple HDDs.
    If you encounter any bug, please report it on my github repository. Also check out the wiki page.
    How to use it
    First of all you can download it from pastebin (id: TmeSNidd) or my github repository and install the file in the directory for rc script (/etc/rc.d/bundle.lua). Before using it you should configure the constants at the top of the script in accordance with their descriptions. Otherwise Bundle might work incorrectly. Then you need to add some filesystems by executing
    rc bundle add [address] in the shell. Please replace [address] by the address of the desired filesystem. Doing so wipes the added filesystem. However, Bundle never incorporates filesystems automatically. Next you should allow bundle to run in background by executing
    rc bundle enable Just reboot the computer and it should be listed by
    df
    Note that the label of the first added filesystem and the filesystem provided by Bundle are always equal since that's the way how bundle stores it. You can also view the added filesystems by executing
    rc bundle list You can also remove added filesystems by
    rc bundle remove [forcefully] Currently, this just removes the last added filesystem, however. If the removal causes the lose of data this fails except you set [forcefully].
    Usage notes
    Don't install the OS on a Bundle filesystem since Bundle requires some functions of OpenOS. Bundle uses a virtual copy of the file structure. On the one hand this makes "hardware" operations faster, on the other hand it might lead to errors when running out of memory. Bundle works with Lua 5.2 as well as Lua 5.3. Known bugs
    Seek operations that set the current position to a value that is bigger than the size of the file cause the file the become bigger than its actual physical size. This is also the case on filesystem components of Open Computers but with bundle it might cause internal errors. That is it for now, have fun using Bundle.
  16. Like
    Fingercomp got a reaction from krakodeel in Drone usage?   
    Of course there is. Assembling a drone with a leash upgrade produces a drone that can transport cows, horses, sheeps, and pigs. Like this:

    Or... like this:

    Besides, drones are entities. They move in straight lines; they don't get stuck in the fence and can actually enter a house through a door. They move pretty fast — about 6 blocks a second (robots are at least 2 times slower). Drone's movement is asynchronous, so the machine can execute some other code in the middle of the flight. Drones can fly above the block height limit. The screenshot above was made while enjoying the flight at a height of 260 blocks, for example. Oh, they can fly below the bedrock, too.
    Also, drones look cool.
    Jobs at which drones clearly outperform robots include player transportation (thanks to the leash upgrade) and item transportation (due to their mobility). And, if used with robots, drones can be useful for crop farming, autocrafting, and construction, for example.
  17. Like
    Fingercomp got a reaction from Mystery in Drone usage?   
    Of course there is. Assembling a drone with a leash upgrade produces a drone that can transport cows, horses, sheeps, and pigs. Like this:

    Or... like this:

    Besides, drones are entities. They move in straight lines; they don't get stuck in the fence and can actually enter a house through a door. They move pretty fast — about 6 blocks a second (robots are at least 2 times slower). Drone's movement is asynchronous, so the machine can execute some other code in the middle of the flight. Drones can fly above the block height limit. The screenshot above was made while enjoying the flight at a height of 260 blocks, for example. Oh, they can fly below the bedrock, too.
    Also, drones look cool.
    Jobs at which drones clearly outperform robots include player transportation (thanks to the leash upgrade) and item transportation (due to their mobility). And, if used with robots, drones can be useful for crop farming, autocrafting, and construction, for example.
  18. Like
    Fingercomp got a reaction from payonel in Drone usage?   
    Of course there is. Assembling a drone with a leash upgrade produces a drone that can transport cows, horses, sheeps, and pigs. Like this:

    Or... like this:

    Besides, drones are entities. They move in straight lines; they don't get stuck in the fence and can actually enter a house through a door. They move pretty fast — about 6 blocks a second (robots are at least 2 times slower). Drone's movement is asynchronous, so the machine can execute some other code in the middle of the flight. Drones can fly above the block height limit. The screenshot above was made while enjoying the flight at a height of 260 blocks, for example. Oh, they can fly below the bedrock, too.
    Also, drones look cool.
    Jobs at which drones clearly outperform robots include player transportation (thanks to the leash upgrade) and item transportation (due to their mobility). And, if used with robots, drones can be useful for crop farming, autocrafting, and construction, for example.
  19. Upvote
    Fingercomp got a reaction from ZefTheFox in Guide to the Sound Card   
    The sound card is added by Computronics, a wonderful addon for OpenComputers. There are a few who actually know what it does. Even less people are able to use it. No one dares to understand how it works, or so I hope.
    Anyway, it appeared a few years (?) ago, and is still mostly undocumented. There is a page in the in-game manual, which fails to explain how great the card is. Of course it does! It has a heap of different methods, which you can use to cast many crazy magics to make the sound card sound, and it's impossible to teach someone to do magic by reading a single page.
    OK, I'm serious now. Last year I managed to understand how to use it, and even wrote a few posts about that. In Russian. Half a year later, I translated them to English. And now I thought of posting a topic here so that you could read them, too.
    Here's the link.
    The first two parts are all about basic things, like getting simple sounds, ADSR, and modulation. The third part features a little bit more complex things, like complex numbers and Fourier transforms. I tried to keep it simple, so I could get something wrong. If so, please leave a comment there pointing out the mistake. Grammar fixes are also highly appeciated.
  20. Like
    Fingercomp reacted to EcmaXp in [MC1.12.2][OC1.7] OpenPython, micropython available on OpenComputers   
    https://minecraft.curseforge.com/projects/openpython
    https://github.com/EcmaXp/OpenPython
    OpenPython makes micropython available on OpenComputers.
    micropython is Python for embedded devices and is different from CPython.
    Currently, micropython is partially compatible with Python version 3.4 as of October 2018.
    Features include:
    - Fully persistable.
    - Runs in a sandboxed environment and does not require a separate native DLL.
    - Supports virtual file system.
    - It can call other components and supports Lua architecture's UserData.
    Limitations include:
    - The firmware is 256 KB and the memory limit has the same limit as the Lua architecture, but the stack is allocated in a separate memory.
    - Most modules are difficult to use because the battery is partially included.
    - The operating system is not yet fully implemented, so the Python interpreter now runs.
    - Ctrl + C is not supported, so if you accidentally run infinite repeated code, the only way to stop it is to turn the computer off and then on.
    To use the Python architecture, you need the following items:
    - EEPROM (OpenPython): I'm sorry, but you have to bring items from the Creative tab.
    - Floppy Disk (OpenPython OS): This item can be obtained by creating a floppy disk and Scrench, or you can check it on the Creative tab.
    - OpenPython CPU: You can choose OpenPython architecture by holding Shift + Right Click on the Lua architecture CPU.
    It is still unstable, but we plan to make further improvements in the future.
    I need help from people who are familiar with OpenComputers and Python.
    Thank you for playing.

  21. Like
    Fingercomp reacted to asie in Nadeshicodec - 320x200 OC video encoder   
    https://git.asie.pl/asie-minecraft/Nadeshicodec
    Apologies for scarce documentation, it's a bit of a project dump. It has a GUI, however. Feel free to fork and clean it up with the terms of the license in mind.
  22. Upvote
    Fingercomp reacted to Ta©ti Tac0Z in tacti OS window pased windows 7 expired   
    sence i saw igor Timofeev's mineos i was thinking if it was posible to get those static windows to move and infact there is:
     
    welcome to the first showcase of the (really un-creative named) tacti OS:
     
    as you can see it figtures moveable, sizeable, and interactive windows infact all programs running in the OS will be windowed!
    useing my easy-to-use windowLib and windowed-program-api i'll happyly resive any feedback (download link avalable in the below posts)
    (also its gonna happen anyway so come with those grammer currections poeple, i can take it)
     
    i hope you guys will like my project
    -thanks
  23. Like
    Fingercomp got a reaction from ben_mkiv in make opencomputers processors faster   
    Yeah, there is a way to make it faster. In fact, way faster. One of the things that makes it slow is... gpu.setBackground. It's quite expensive in terms of perfomance (tier 3 GPUs consume 1/128 of the call budget when this method is called). Fortunately, your program only involves 4 colors, so it can be easily optimized.
    Actually, there are two ways to do it. A somewhat naive way would be to process all cells of one color first, then process all cells of another color, etc. That would solve the issue with gpu.setBackground, but there's another thing to worry about. The gpu.set method isn't free. In fact, that program does 160 × 50 = 8000 sets, assuming it's running on the max tier 3 resolution. And that is a lot.
    Fortunately, OC supports Unicode. In particular, there's a character in Unicode called a full block — █. On OC, I prefer to think of it as of an inverse of " " (a space). If the foreground and background colors are swapped, the space would look like the full block, and vice versa. And it can help us reduce amount of GPU calls significantly. Try replacing the loops with the following:
    -- i = 0 gpu.setBackground(0xff0000) gpu.set(1, 1, " ") -- i = 1 gpu.setBackground(0x00ff00) gpu.set(1, 2, " ") -- i = 2, 3 gpu.setForeground(0xffff00) gpu.setBackground(0x0000ff) local fullBlock = "\u{2588}" local oddRow = (" " .. fullBlock):rep(math.floor(mx / 2)) local evenRow = (fullBlock .. " "):rep(math.floor(mx / 2)) for y = 1, my do local x = 1 if y % 2 == 1 then if y == 1 then -- Shift the x by 2 to the right to avoid rewriting -- the first two characters. -- OC truncates everything that goes out of the screen bounds, -- so there's no need to worry about that. x = x + 2 end gpu.set(x, y, oddRow) else gpu.set(x, y, evenRow) end end I can't launch Minecraft to run the program and measure the render time, but I can calculate the amount of call budget consumed by the GPU. Assuming the program runs on a tier 3 GPU and screen, there are 4 gpu.setForeground/gpu.setBackground calls, and 52 gpu.set calls. We get (4 × 1 / 128) + (52 × 1 / 256) = 15 / 64 ≈ 0.23. This is enough even if you have a tier 1 processor (whose call budget is 0.5), and the program should be able to run at 20 FPS, though it doesn't really change each frame.
    Oh, I meant to say "T3" (tier 3), sorry. A tier 2 GPU can only perform 128 sets and 64 fills.
    https://github.com/MightyPirates/OpenComputers/blob/master-MC1.7.10/src/main/scala/li/cil/oc/server/component/GraphicsCard.scala#L55-L60
    Also, there's a comment a few lines above in that file, which reminds me of yet another reason OC makes indirect calls take 1 tick to run — synchronization. OpenComputers, very much unlike ComputerCraft, saves the state of running computers so that they can be resumed when the chunk is reloaded. Methods that interact with the world in some way (like moving items around) must perform synchronization with the Minecraft world to avoid, well, messing things up. The comment says it's especially important on world saves. Despite that, the GPU methods were made direct, although a "nasty trick" was needed to do this. Well, safe concurrency is hard to achieve.
  24. Upvote
    Fingercomp got a reaction from Izaya in make opencomputers processors faster   
    Please calm down.
    There are some component methods that block the computer for a tick when called, yes. Such methods usually interact with the world. For example, a transposer allows to transfer items between invetories by calling the transferItem method, which takes a tick to execute (so you get up to 20 stacks/second).
    On the other hand, there are a lot of direct methods, which can be called several times per tick. For example, the GPU's methods are direct. And the processor (as well as RAM) determines how many direct calls are allowed per tick. I think T2 T3 setup allows you to call gpu.get one thousand times every tick. Or 256 gpu.sets. Or 128 gpu.fills.
    I also believe you don't realize how bad ComputerCraft is for servers. A really simple and stupidly-written program can eat up all the memory the server has. That's why OC limits the memory available for an in-game computer. And running CPU-intensive tasks on a CC's computer makes the whole server run slow, whereas OC requires scripts to pause to allow other in-game computer to run. OpenComputers imposes the limits not because the mod developers want users to suffer (although I do sometimes think of that when I try to do some stupidly complex things with it), but to make it server-friendly.
    What's important is that OC allows you to configure these limits for your needs. Have you opened its configuration file? It is more than a 1.5k lines long, and has more than 300 settings you can change, each with a comment that explains the effect of the setting. There's callBudgets to increase the direct call number limit. Or decrease it. There's also the ramSizes setting for memory, and hddSizes for the HDD sizes.
    But even with all of these limits, OC can run a lot of programs, including graphical shells, 3D games, reactor control systems. It allows you to send HTTP requests to the real websites, and open raw TCP sockets to interact with network services. It can display 320x200 images. It can even play videos — inside the game, and on the default OC settings!
  25. Upvote
    Fingercomp got a reaction from viluon in make opencomputers processors faster   
    Please calm down.
    There are some component methods that block the computer for a tick when called, yes. Such methods usually interact with the world. For example, a transposer allows to transfer items between invetories by calling the transferItem method, which takes a tick to execute (so you get up to 20 stacks/second).
    On the other hand, there are a lot of direct methods, which can be called several times per tick. For example, the GPU's methods are direct. And the processor (as well as RAM) determines how many direct calls are allowed per tick. I think T2 T3 setup allows you to call gpu.get one thousand times every tick. Or 256 gpu.sets. Or 128 gpu.fills.
    I also believe you don't realize how bad ComputerCraft is for servers. A really simple and stupidly-written program can eat up all the memory the server has. That's why OC limits the memory available for an in-game computer. And running CPU-intensive tasks on a CC's computer makes the whole server run slow, whereas OC requires scripts to pause to allow other in-game computer to run. OpenComputers imposes the limits not because the mod developers want users to suffer (although I do sometimes think of that when I try to do some stupidly complex things with it), but to make it server-friendly.
    What's important is that OC allows you to configure these limits for your needs. Have you opened its configuration file? It is more than a 1.5k lines long, and has more than 300 settings you can change, each with a comment that explains the effect of the setting. There's callBudgets to increase the direct call number limit. Or decrease it. There's also the ramSizes setting for memory, and hddSizes for the HDD sizes.
    But even with all of these limits, OC can run a lot of programs, including graphical shells, 3D games, reactor control systems. It allows you to send HTTP requests to the real websites, and open raw TCP sockets to interact with network services. It can display 320x200 images. It can even play videos — inside the game, and on the default OC settings!
×
×
  • Create New...

Important Information

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