I've been trying to create a certain type of piston door with commands for 2 days but I can't seem to fix all the bugs. It has to have a very specific functionality and I can't settle for anything different, but it's been almost impossible to make with the given constraints.
The door is a 1-block-wide piston door that uses a button on each side to open it. The specific functionality are as follows:
- The button can't be hooked up to any redstone, it must work by detecting when the button is pressed through commands.
- The door has to work regardless of the distance you are from it as long as you pressed the button.
- Each time you press the button it either opens or closes the door. So if you press the button once, it opens, press it again, and it closes.
- The entire door command system must be able to run from one function/command block chain from anywhere in the world.
- You have to be able to use more than one door at a time. So you can quickly press 2 buttons for 2 doors and have them both work separately.
I've been able to achieve the first 4 criteria, but the fifth one has completely stopped me. I can't figure out a way to make the doors independent from each other while still only needing 1 function for the entire system.
I've tried for 2 days now for hours and I can't seem to figure out how to achieve such a simple effect. Every time I fix a bug, a new one just pops up, and I think I might have to change my approach to it entirely but I'm not sure how. If anyone who is experience at command blocks could work together with me here I would be really grateful.
And to give a little context I suppose, the door is supposed to look and function exactly how the doors do in SCP: Containment Breach, as I'm trying to recreate the game in Minecraft along with all it's mechanics. So if you know how that game works, you can understand what I'm going for.
The opening and closing functionality are done with a virtual flip-flop (tags or scores) but you already have that covered so I won't get into that.
I assume that you are placing a redstone block to extend the piston? If so, you can use an armor stand at the button and two armor stands at the redstone block spots. This way, you can detect the button press with an armor stand and then execute from that armor stand to the two armor stands that handle redstone blocks within a specific radius.
/execute as @e[tag=button] at @s if block ~1 ~ ~ oak_button[powered=true] run execute as @e[tag=rs_block,distance=..5] at @s run setblock ~ ~ ~ redstone_block
Actually, explain how you personally would make the opening and closing part, because it's almost certainly different than mine and possibly (probably) better.
I made two ways of doing it. One was by increasing a scoreboard variable by 1 every tick that the button was pushed, and then placing a redstone block at tick 1 and placing an air block at tick 2, and then resetting it back to 0 when it reaches the last tick.
The other method was by placing the redstone block if the button was pressed and if a variable was 1, and then in the next command block checking the success value of the first one, and if it couldn't place the redstone, then it would place air instead, and then set the variable to 0, and then have a command block that would set the variable to 1 only when the button isn't powered. And that worked and it was compact, but it didn't allow me to open or close more than 1 door at a time. I'm not sure if it's possible to modify it so it could work for more than 1 door at the same time, or if it's just the wrong approach entirely. I could show you the commands for it if you want, but I want to know what you would do.
Update: I finally figured it out and got it to work, with only 1 minor bug that shouldn't be too huge of a problem. However I do believe there's probably a more efficient way to do it so I'd still like some suggestions on other possible methods.
Here are the commands I used:
execute as @e[tag=button] at @s if block ~ ~1 ~ stone_button[powered=true] run execute at @s run scoreboard players add @s doorSwitch 1
execute as @e[tag=button] at @s if score @s doorSwitch matches 1..1 run execute at @e[tag=door,sort=nearest,limit=1] run setblock ~ ~1 ~ redstone_block
execute as @e[tag=button] at @s if score @s doorSwitch matches 2..2 run execute at @e[tag=door,sort=nearest,limit=1] run setblock ~ ~1 ~ air
execute as @e[tag=button] if score @s doorSwitch matches 19..19 run scoreboard players reset @s doorSwitch
Update: I finally figured it out and got it to work, with only 1 minor bug that shouldn't be too huge of a problem. However I do believe there's probably a more efficient way to do it so I'd still like some suggestions on other possible methods.
Here are the commands I used:
execute as @e[tag=button] at @s if block ~ ~1 ~ stone_button[powered=true] run execute at @s run scoreboard players add @s doorSwitch 1
execute as @e[tag=button] at @s if score @s doorSwitch matches 1..1 run execute at @e[tag=door,sort=nearest,limit=1] run setblock ~ ~1 ~ redstone_block
execute as @e[tag=button] at @s if score @s doorSwitch matches 2..2 run execute at @e[tag=door,sort=nearest,limit=1] run setblock ~ ~1 ~ air
execute as @e[tag=button] if score @s doorSwitch matches 19..19 run scoreboard players reset @s doorSwitch
This looks alright, I had something very similar in mind. Just one little side note: you don't need "at @s" in the first command.
Yeah I figured that part out. And the bug was simple to fix, it was just that on one side of the door the button was the same distance to the 2 closest door stands, but I just had to move the door stands on top of/inside the pistons to fix that.
I'm just wondering though if there's a way to do it without having to keep adding to the scoreboard variable for 19 ticks, because the door only operates for 2 or 3 ticks, so the rest are wasted. I know that it pretty much makes no difference at all on this scale, but the map will have many many functions constantly testing for many values at the same time and adding values to scoreboard variables all the time so I want to make sure it's as resource-conservative as possible with a relatively simple mechanism.
Yeah I figured that part out. And the bug was simple to fix, it was just that on one side of the door the button was the same distance to the 2 closest door stands, but I just had to move the door stands on top of/inside the pistons to fix that.
I'm just wondering though if there's a way to do it without having to keep adding to the scoreboard variable for 19 ticks, because the door only operates for 2 or 3 ticks, so the rest are wasted. I know that it pretty much makes no difference at all on this scale, but the map will have many many functions constantly testing for many values at the same time and adding values to scoreboard variables all the time so I want to make sure it's as resource-conservative as possible with a relatively simple mechanism.
why don't you just reset the score after 2?
After the redstone_block is removed, reset the score to 0 and the mechanism should be on standby.
Use chain command blocks to ensure the right execution order.
Well because the first command will add 1 to the scoreboard as long as the button is pressed, so once the count reaches 3, even if it resets, the button will still be pressed so it will keep adding to the score, which will open and close the door several times in one press.
Well because the first command will add 1 to the scoreboard as long as the button is pressed, so once the count reaches 3, even if it resets, the button will still be pressed so it will keep adding to the score, which will open and close the door several times in one press.
Try adding to the score only when the button is pressed.
0 -standby
1 -redstone block
2 -air and reset to 0
You can use this to increment your score without spamming:
/execute as @e[tag=button] at @s if block ~1 ~ ~ oak_button[powered=true] if block <x> <y> <z> air run scoreboard players add @s doorSwitch 1
it is important that the executing order is like: add score > place redstone block
In theory, this should only increment the score by 1 because the redstone block will be placed at <x> <y> <z> and therefore breaking the criteria.
Wait, I don't understand. Could you explain a little further? It sounds like it would just place the redstone block and then not run anymore if it only adds 1 if there's air there, which there wont be after the first run.
Wait, I don't understand. Could you explain a little further? It sounds like it would just place the redstone block and then not run anymore if it only adds 1 if there's air there, which there wont be after the first run.
exactly, the command will run only 1 time to increment the score by 1. This is to prevent the command from spamming and adding to the score over and over again. The second push of the button would result in the score being 2 because of the following command:
/execute as @e[tag=button] at @s if block ~-1 ~ ~ oak_button[powered=true] if block <x> <y> <z> redstone_block run scoreboard players add @s doorSwitch 1
If you want, I can give you another method which I used when creating my elevator up/down sequence. It uses a relaying system with tags to detect which state it is in. You will need more command blocks but it is definitely more stable.
What order would the commands in the command blocks come in then? If its
if air then increment --> if redstone then increment --> put redstone if 1 --> put air if 2 --> reset count if 2
Then it will place the redstone the first tick, then the air the second tick and reset, then it will just detect that there's air again the third tick and do it all over again. I'm assuming you're having it so it will place the redstone the first time you press the button, and then air the second time, rather than having them both be placed right after each other. Both of those methods will keep the pistons open or closed but right now I have it set up so the placing of the blocks takes 2 loops, or ticks, to complete, so I'm not sure how you would decide when to place the blocks.
And yes tell me about the other method as well if it's more stable than this one.
What order would the commands in the command blocks come in then? If its
if air then increment --> if redstone then increment --> put redstone if 1 --> put air if 2 --> reset count if 2
Then it will place the redstone the first tick, then the air the second tick and reset, then it will just detect that there's air again the third tick and do it all over again. I'm assuming you're having it so it will place the redstone the first time you press the button, and then air the second time, rather than having them both be placed right after each other. Both of those methods will keep the pistons open or closed but right now I have it set up so the placing of the blocks takes 2 loops, or ticks, to complete, so I'm not sure how you would decide when to place the blocks.
And yes tell me about the other method as well if it's more stable than this one.
Yeah sorry, I can't show you that one... turns out it's way more complicated than I thought and it would take me ages to re-create it and explain it to you. Hopefully, you can make something out of the code I already gave you or your own code.
Other than that, I have one more design but you would have to break one of your own rules (to use only one command block chain for all doors). This design uses a small relay (one for each door) and is also really stable. The only downside is that you have to have one for each door and it uses hoppers and redstone torches which are not so performance friendly. Here is a world download if you are interested: https://www.dropbox.com/sh/9aikf1rpamgp121/AADN_racbjw8EpEiIPNyaKq2a?dl=0
Ah, thank you. I'll look at it but since it has to run from one command block, I'll probably just have to deal with the method I already have. Which works fine anyway, I only wanted another version because I'm afraid of how much it might lag later down the road when there are dozens of other functions constantly testing for values and performing scoreboard calculations. But I doubt it would make much of a difference at that point. Thank you for your help though.
I'll probably be making other threads quite often about other functions that I fail to figure out lol.
Ah, thank you. I'll look at it but since it has to run from one command block, I'll probably just have to deal with the method I already have. Which works fine anyway, I only wanted another version because I'm afraid of how much it might lag later down the road when there are dozens of other functions constantly testing for values and performing scoreboard calculations. But I doubt it would make much of a difference at that point. Thank you for your help though.
I'll probably be making other threads quite often about other functions that I fail to figure out lol.
It Won't make much of a difference in performance anyway so just make what you want and how you want it.
More threads? can't wait to see more questions, it was getting really boring in the command section
I've been trying to create a certain type of piston door with commands for 2 days but I can't seem to fix all the bugs. It has to have a very specific functionality and I can't settle for anything different, but it's been almost impossible to make with the given constraints.
The door is a 1-block-wide piston door that uses a button on each side to open it. The specific functionality are as follows:
- The button can't be hooked up to any redstone, it must work by detecting when the button is pressed through commands.
- The door has to work regardless of the distance you are from it as long as you pressed the button.
- Each time you press the button it either opens or closes the door. So if you press the button once, it opens, press it again, and it closes.
- The entire door command system must be able to run from one function/command block chain from anywhere in the world.
- You have to be able to use more than one door at a time. So you can quickly press 2 buttons for 2 doors and have them both work separately.
I've been able to achieve the first 4 criteria, but the fifth one has completely stopped me. I can't figure out a way to make the doors independent from each other while still only needing 1 function for the entire system.
I've tried for 2 days now for hours and I can't seem to figure out how to achieve such a simple effect. Every time I fix a bug, a new one just pops up, and I think I might have to change my approach to it entirely but I'm not sure how. If anyone who is experience at command blocks could work together with me here I would be really grateful.
And to give a little context I suppose, the door is supposed to look and function exactly how the doors do in SCP: Containment Breach, as I'm trying to recreate the game in Minecraft along with all it's mechanics. So if you know how that game works, you can understand what I'm going for.
This is what the door looks like on either side.
Bears
The opening and closing functionality are done with a virtual flip-flop (tags or scores) but you already have that covered so I won't get into that.
I assume that you are placing a redstone block to extend the piston? If so, you can use an armor stand at the button and two armor stands at the redstone block spots. This way, you can detect the button press with an armor stand and then execute from that armor stand to the two armor stands that handle redstone blocks within a specific radius.
Command block engineer // Developer // #TeamTrees
Actually, explain how you personally would make the opening and closing part, because it's almost certainly different than mine and possibly (probably) better.
I made two ways of doing it. One was by increasing a scoreboard variable by 1 every tick that the button was pushed, and then placing a redstone block at tick 1 and placing an air block at tick 2, and then resetting it back to 0 when it reaches the last tick.
The other method was by placing the redstone block if the button was pressed and if a variable was 1, and then in the next command block checking the success value of the first one, and if it couldn't place the redstone, then it would place air instead, and then set the variable to 0, and then have a command block that would set the variable to 1 only when the button isn't powered. And that worked and it was compact, but it didn't allow me to open or close more than 1 door at a time. I'm not sure if it's possible to modify it so it could work for more than 1 door at the same time, or if it's just the wrong approach entirely. I could show you the commands for it if you want, but I want to know what you would do.
Bears
Update: I finally figured it out and got it to work, with only 1 minor bug that shouldn't be too huge of a problem. However I do believe there's probably a more efficient way to do it so I'd still like some suggestions on other possible methods.
Here are the commands I used:
Bears
This looks alright, I had something very similar in mind. Just one little side note: you don't need "at @s" in the first command.
What is the bug?
Command block engineer // Developer // #TeamTrees
Yeah I figured that part out. And the bug was simple to fix, it was just that on one side of the door the button was the same distance to the 2 closest door stands, but I just had to move the door stands on top of/inside the pistons to fix that.
I'm just wondering though if there's a way to do it without having to keep adding to the scoreboard variable for 19 ticks, because the door only operates for 2 or 3 ticks, so the rest are wasted. I know that it pretty much makes no difference at all on this scale, but the map will have many many functions constantly testing for many values at the same time and adding values to scoreboard variables all the time so I want to make sure it's as resource-conservative as possible with a relatively simple mechanism.
Bears
why don't you just reset the score after 2?
After the redstone_block is removed, reset the score to 0 and the mechanism should be on standby.
Use chain command blocks to ensure the right execution order.
Command block engineer // Developer // #TeamTrees
Well because the first command will add 1 to the scoreboard as long as the button is pressed, so once the count reaches 3, even if it resets, the button will still be pressed so it will keep adding to the score, which will open and close the door several times in one press.
Bears
Try adding to the score only when the button is pressed.
0 -standby
1 -redstone block
2 -air and reset to 0
You can use this to increment your score without spamming:
it is important that the executing order is like: add score > place redstone block
In theory, this should only increment the score by 1 because the redstone block will be placed at <x> <y> <z> and therefore breaking the criteria.
Same goes for the opening.
Command block engineer // Developer // #TeamTrees
Wait, I don't understand. Could you explain a little further? It sounds like it would just place the redstone block and then not run anymore if it only adds 1 if there's air there, which there wont be after the first run.
Bears
exactly, the command will run only 1 time to increment the score by 1. This is to prevent the command from spamming and adding to the score over and over again. The second push of the button would result in the score being 2 because of the following command:
If you want, I can give you another method which I used when creating my elevator up/down sequence. It uses a relaying system with tags to detect which state it is in. You will need more command blocks but it is definitely more stable.
Command block engineer // Developer // #TeamTrees
What order would the commands in the command blocks come in then? If its
if air then increment --> if redstone then increment --> put redstone if 1 --> put air if 2 --> reset count if 2
Then it will place the redstone the first tick, then the air the second tick and reset, then it will just detect that there's air again the third tick and do it all over again. I'm assuming you're having it so it will place the redstone the first time you press the button, and then air the second time, rather than having them both be placed right after each other. Both of those methods will keep the pistons open or closed but right now I have it set up so the placing of the blocks takes 2 loops, or ticks, to complete, so I'm not sure how you would decide when to place the blocks.
And yes tell me about the other method as well if it's more stable than this one.
Bears
Yeah sorry, I can't show you that one... turns out it's way more complicated than I thought and it would take me ages to re-create it and explain it to you. Hopefully, you can make something out of the code I already gave you or your own code.
Other than that, I have one more design but you would have to break one of your own rules (to use only one command block chain for all doors). This design uses a small relay (one for each door) and is also really stable. The only downside is that you have to have one for each door and it uses hoppers and redstone torches which are not so performance friendly. Here is a world download if you are interested: https://www.dropbox.com/sh/9aikf1rpamgp121/AADN_racbjw8EpEiIPNyaKq2a?dl=0
Command block engineer // Developer // #TeamTrees
Ah, thank you. I'll look at it but since it has to run from one command block, I'll probably just have to deal with the method I already have. Which works fine anyway, I only wanted another version because I'm afraid of how much it might lag later down the road when there are dozens of other functions constantly testing for values and performing scoreboard calculations. But I doubt it would make much of a difference at that point. Thank you for your help though.
I'll probably be making other threads quite often about other functions that I fail to figure out lol.
Bears
It Won't make much of a difference in performance anyway so just make what you want and how you want it.
More threads? can't wait to see more questions, it was getting really boring in the command section
Command block engineer // Developer // #TeamTrees