-
-
Notifications
You must be signed in to change notification settings - Fork 637
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adds a test to determine piston stickyness #5383
base: master
Are you sure you want to change the base?
Conversation
This commit adds a condition to prevent sticky pistons from pulling items back if they have been extended for <= 2 ticks
5358007
to
e42d43f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks reasonable, just want to make sure the semantics here are desired.
Also, please add your name to the CONTRIBUTORS file so your contribution is recognised and to indicate your agreement to the LICENSE terms.
src/Blocks/BlockPiston.cpp
Outdated
if (ExtensionWorldTickTime - World.GetWorldTickAge() <= 2_tick) | ||
{ | ||
// Piston has been activated for less or equal to 2 ticks, bail out | ||
return; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ExtensionWorldTickTime is not persisted, so when chunks are un- and re-loaded, this will always return when a newly-loaded extended piston is retracted. Is that the correct behaviour?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, this might be an issue if the player let's a 2 tick clock running and goes to unload and load the chunk
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if this is still relevant with the changes I just pushed
Since there is only one handler and everything is static wouldn't this mean that if: Piston 1 extends at tick 0 Piston 1 will not retract its connected block as piston 2 has just set I think we need to keep a separate |
Oh yes, this is a BlockHandler not a BlockEntity! This won't work at all with more than one piston in the world, it needs something to be stored per-piston. |
Possibly in the redstone simulator? Not sure though, this needs a bit of thought. |
Pistons normally become a block entity while moving ("block 36"/the moving piston block thing). That block entity knows what block is being pushed and when the push should finish (if I recall correctly; the wiki should document it in more detail). |
We don't have a block entity for pistons at the moment (at least I think so). Creating one and using it to store this value makes sense. |
I totally did not thing of that at all |
I have created a PistonEntity class to represent both pistons and sticky pistons, but now I'm unsure where to go from there |
I have a feeling adding moving piston tile entities is going to be a lot of work (and introduce dupe bugs), we should figure out how vanilla pistons respond to signals and extension, retraction timings before starting any changes. Questions like how long does it take to extend, what happens when it loses or gains signal, a part of the piston is destroyed or a block is placed in the way during extension, retraction, what happens if the signal is pulsed in the same tick. Ideally there would be some way to replicate vanilla while only relying on the piston blocks as state. If we start adding too much complexity there's the risk of us repeating the countless vanilla piston dupe bugs over the years. |
But why would we need to add moving piston tile entities in the first place? |
I think Vanilla doesn't have piston entities, only the moving piston entities. |
So we MUST have it too ? I think that as long as we can keep away from (possible uselessly) added complexity, it's better, no? |
nah I don't like moving piston entities, hopefully we can figure something out which doesn't need any block entities at all. First though, we should have a spec of how pistons should behave on a tick-by-tick level, but I can't find this information on the wiki. |
Do you mind elaborating ? I'm not quite sure I understood everything ._. (and why we need to see why pistons work on a tick-by-tick level) |
At the moment Cuberite pistons work like this. From a resting state, Tick 0:
Tick 1:
and tick 2, 3 repeats. From this we can see that how a piston behaves depends on the state of the world ( We also see why pistons don't drop blocks as vanilla does, because the state of the pulled block is updated atomically, the block is either pulled or not; there are no intermediate states visible to the outside. |
I believe the answer here is that the moving piston block entity is considered indestructible. At least, it's impossible to place a block in the way during extension because the destination block is also converted into a moving piston block (with its block entity) during the moving process, and you can't place something into that. Breaking I'm less sure of; you can't mine it, but I'm not sure what happens if it's destroyed via an explosion. |
If we want to replicated vanilla behaviour, it seems we have to both
But, to do this robustly, I think we need to know exactly what vanilla does each tick a piston is active and how it responds to certain events in these newly introduced intermediate states, and formulate some sort of system to imitate it. As an example, why does vanilla take 3 ticks to extend a piston? How is it scheduling the events? Is it 1 tick delay + 2 ticks actual animation? Or something else? The system we eventually come up with will ideally not need moving piston block entities, because that's extra work to save and load to disk, and unclear is if those entities need to be sent to the client, and if doing that would conflict with the piston animation the client plays (which also using moving piston entities). But if that's the only way, oh well. However a piston entity wouldn't work because we'd diverge from what vanilla does - the save file could have our own custom block entity in it - and ideally Cuberite tries to remain compatible. |
I don't have the answers to this, maybe Pokechu our resident expert will, but these are only relevant if you want to overhaul pistons to make them 100% vanilla identical. If |
(as bearbin has already suggested at the start) |
Right, this is where it causes problems at, this means that the world wouldn't be able to be used by regular minecraft-server |
I don't think you need to send anything special to the client other than the piston block action, but unfortunately that's basically all I know on the subject; I don't have any further details on hand (and things may have changed since that rather sparse documentation was written, too). |
I mean, if not doing so could cause some major issues, then I see no reason why I would want to implement a temporary fix, I might as well try to overhaul the piston system (although I think I'm far away from having the technical knowledge to do such a thing) |
Actually, I remembered something else. I think the only relevant property of the moving piston/block 36 block entity for servers is that when the progress field hits its maximum, the block changes to the stored block. Everything else is only relevant clientside. Here's an old video showcasing an unusual use for block 36 (this predates command blocks); I think there was a commentated video that gave more context but I can't find it (the video credits Minecraft Forum user DiEvAl though, so maybe it's somewhere in their posts). |
I managed to dig up further context: this video (which is no longer public, but is archived here (invisible on the main page due to dependence on YouTube's flash player, I think, but also archive.org's download speed is rather slow and you're best off saving that video manually (~10 minutes), waiting for the download to finish, and then viewing it locally)). This video is from late 2012 (9 years old, yikes!), but should be somewhat vaguely informative. Note that in that case, |
So uh, I'm not sure where I would start of with something like this.. Trying to put together a list of things that have to be done for that overhaul is gonna be a challenge in itself |
1590d5b
to
d347054
Compare
I have decided to revert everything, as a plan to avoid using an entity altogether |
These changes modify the way we check by using an unordered_map that stores the position and the extension world tick time instead of a simple variable
@@ -93,6 +93,7 @@ class cIncrementalRedstoneSimulatorChunkData final : public cRedstoneSimulatorCh | |||
/** Structure storing position of mechanism + it's delay ticks (countdown) & if to power on. */ | |||
std::unordered_map<Vector3i, std::pair<int, bool>, VectorHasher<int>> m_MechanismDelays; | |||
|
|||
std::unordered_map<Vector3i, cTickTimeLong> PistonExtensionWorldTickTime; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std::unordered_map<Vector3i, cTickTimeLong> PistonExtensionWorldTickTime; | |
std::unordered_map<Vector3i, cTickTimeLong, VectorHasher<int>> PistonExtensionWorldTickTime; |
Need the hasher to fix compile.
if (!should_pull_block) | ||
{ | ||
// Piston has been activated for less or equal to 2 ticks, bail out | ||
// return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be uncommented?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also this block should have an extra indent
This commit adds a condition to prevent sticky pistons from pulling items back if they have been extended for <= 2 ticks
Fixes #5365