Lesson Nine: Practical implications of the checkpoint bug The checkpoint bug affects all manner of minecart constructions, as soon as ramps get involved. For a start, let's look at the lowly single-ramp cyclotron:
##### #####
#╔═╗# #╔═╗#
#╚▲╝# #╚╔╝#
##### #####
Cart cycles counter-clockwise and its speed oscillates somewhere between 70.000 and 80.000.
It won't go any faster, ever, although one step of ramp acceleration gives 4900 speed while four corners and, say, seven steps of movement cost no more than 4070. Evidently, if the cart spends only one step on the ramp, this acceleration is eaten up by the checkpoint compensation when moving off the ramp to level floor. It'll only really pick up speed when it spends at least two steps on the ramp and it must be slower than ~72.000 for this to happen.
Indeed, the cart cycles at an oscillating speed: it goes five rounds at eight steps each (spending two steps on the ramp each time) and seven steps in the sixth round (spending only one step on the ramp).
For speed to keep building up, you need an unbroken stretch of three impulse ramps: due to the greater length of ramp tiles, the maximum speed available through ramps (270.000) is just less than two ramp tiles per step, so a cart will always spend at least two consecutive steps on the three-ramp stretch. Such a three-ramp cyclotron is enough to achieve maximum ramp speed.
***
When moving a cart laterally onto an impulse ramp track, the checkpoint effect can be used to prevent diagonal movement.
Throwing a cart directly into a sideways impulse ramp
a) b)
#### #### #### ####
▲▲▲▲ ╝╝╝╝ ▲▲▲▲ ╝╝╝╝
║ ║ ▲# ╚#
from the south like in a) will have the cart accelerate to the west on top of a pre-existing and lingering northward speed. It'll either bump into the wall and temporarily stop or exit the impulse stretch on a diagonal trajectory. Sending it through an immediately adjacent impulse ramp lets it pass right through the first ramp of the acceleration stretch via checkpoint effect, stopping it against the wall and cancelling the northward speed instantly, so that it can accelerate west on a straight course.
***
Of course, others have, often unknowingly, used checkpoint effects in their constructions. Take the "impulse elevator" on the wiki:
#### ##╗# ####
▼╔╝# ##╚# ╔╝▼#
▼### #▼▼# ##▼#
All track on ramps, going up from left to right.
Looking at the thing in action, we'll see that the cart moves at a rate of exactly one tile every step until after five levels or so it stops, rolls back from an "up" ramp in eight turns, spends another eight steps on the ramp behind, then starts going at the previous rate for another five levels. Clearly, this means that the cart moves at one ramp-length per step, i.e. 140.000 speed, right?
Haha, of course not. It's checkpoints all the way up. The cart hiccups and stops not because it's too fast, but because it ran all out of speed and had to checkpoint-cheat itself some new steam.
Observe the ramp slants in the example above: E, W, N, S, W, E. Slant changes every tile, thus every tile is a full checkpoint. The checkpoint bug runs the cart up at a rate of one ramp every step, until speed falls to zero. At that point, the cart makes it onto the next tile (and technically all the way "up" on it) but has no more speed to make it to the next tile (up), so it stays on the ramp and accelerates there for the full eight steps. This moves it back to the last (opposing) ramp, which it again fully crosses, but here it bumps against a wall and accelerates all the way forward again. With the shiny new 35.000 speed, it can take the up checkpoint and have speed leftover to keep moving.
It's peculiar that this thing loses speed so quickly - it appears to burn through its store of ~35.000 speed points in five levels, although it should only lose 1.000 speed per level for the corner. It's almost as if there's something fishy with corner ramps that enforces a higher speed loss.
***
Another ramp spiral was invented by WanderingKid and has the advantage of doing without the annoying back-and-forth every few levels. The cart in that design just keeps going. Let's check it out:
z+0 z+0, track z+1 z+1, track z+2 (z+0 mirrored)
#### #### #### #### ▲▲╗#
▼### ▼### ##▲# ##║# ##▼#
╚▲▲# ╚╔╝# ##▼# ##▼# ####
#### #### #### #### ####
This one surprised me at first, because it "somehow" manages to send a cart up
two levels, seemingly with a single checkpoint. Spoiler: of course it's two checkpoints.
The east-pointing ramp on z+0 works as a proper speed-granting impulse ramp here, because the cart enters it from flat floor, not from another ramp. When i tried it out, the cart spent two or three steps (repeating pattern of different rates, like in the cyclotron above) on the ramp each time, so there was always speed gained here. The corner up ramp is, unsurprisingly, a checkpoint, the cart passes it in a single step. What i hadn't fully understood yet - the next, straight, ramp is
also a checkpoint, because the slant of ramps changed, from west to south. The flat corner is yet another full checkpoint, which doesn't really matter in and of itself, but the fact that it's normal floor and not a ramp saves the following impulse ramp from being a full checkpoint, so it can actually do its impulse work.
***
Let's crack an old puzzle next: the 2x2 ramp spiral. It's a notoriously ill-behaved contraption, carts keep stopping on it for no discernible reason. At the same time, it looks so simple:
#### #### #### #### ####
#╔╗# #▲▼# #▼## #### ##▲#
#╚╝# #### #▲## #▼▲# ##▼#
#### #### #### #### ####
Spread over four levels, one corner on each level, each leading into the next. Throwing a cart down such a spiral lets the cart start going at one ramp per step, but after five, it stops, starts again, goes another five, stops again etc.
Ho hum. Is it picking up too much speed? I put a few stone blocks into a cart and sent it down there. The blocks staid in the cart. Well, it was moving at one ramp per step, so it was probably checkpoint-hopping again. Makes sense, of course, since ramp slant changes on every tile. So it probably stopped simply because its speed dropped to zero. Still, a cart going
down a ramp spiral and losing speed? I revved up a cart in the trusty cyclotron and sent it down a nice long spiral. It kept going and emerged 21 z-levels below - at 130.000 speed. The cart was definitely losing ~6.000 speed on every ramp, a few more tests confirmed this. In fact, a downward spiral slows down a cart exactly as much as an
upward spiral.
Inspired by rhesusmacabre's long table:
http://www.bay12forums.com/smf/index.php?topic=125679.msg4223763#msg4223763i built a few simple test spirals, and yes, i was getting checkpoint-movement up the spirals, over nice large numbers of levels, and my eyeballed speed loss of 6.000 per level seemed to work out.
I definitely needed to crack the puzzle of corner ramps. But first, some light entertainment.
***
Since different-slant ramps work as checkpoints for each other and the compensating speed effects cancel out their acceleration, shouldn't it be possible to send
reallllly slow carts along a line of impulse ramps, bouncing one ramp per step until ramps stopped and the actual speed reasserted itself? I built a line of 24 impulse ramps stretching from east to west and with wall to the south, alternating between NS and SW every step, hatch-dropped a minecart on the easternmost (SW) ramp and watched it. Yep, cart rolled down the usual five steps, then went forward at a rate of one ramp every step over the whole line, and once it emerged from the ramp line, it crawled along at the actual ~19.000 speed (five to six steps used for every tile).
But shouldn't the northward acceleration, although it's cancelled instantly, result in a minor northward displacement on every NS ramp that should eventually push the cart past the northern border? I expanded the row to ~40 ramps, and sure enough, after the thirtieth ramp (15th NS ramp) the cart moved off the ramp-line to the north. To make sure it's really displacement and not northward velocity, i covered ten ramps with a bridge so that north-pointing ramps #15 to #19 were obscured. The cart moved over this stretch without diverting, went over the SW ramp directly behind the bridge - and made its step to the north when it checkpoint-passed the NS ramp behind it, the twentieth northward ramp in the line, but this time, the fifteenth touched by the cart.
Fifteen pushes of presumably 4900 distance units give 73500 distance units, just over half the assumed length of a ramp (140.000 or so - i don't know the exact number Toady uses). Enough to move over the border to the next tile when starting in the middle of a tile. Seems that it works out.
Of course, northward displacement can simply be compensated by southward displacement. I dug out a track all across the embark (normal embark, so just 190ish tiles) and carved out a nice stretch of 160ish alternating track ramps. First ten "forward" ramps interspersed with 10 North-slanted ramps, then (changing the adjacent wall) 20 forward with 20 south-slanted, then another 20/20 stretch forward/north etc.., finally a bit of flat track leading into a little loop at the far end. The cart was dropped in via hatch as usual and moved all across the embark without falling off the row, passing one tile per step as long as it was bouncing over ramps, while the flat track at the end demonstrated its internal speed remained at the original 19.000. The loop itself contained a nice juicy acceleration rail, increasing speed on the route back to ~120.000, and the cart went back all the way, once again at 1 tile/step externally, unfazed by the 80 "opposing" impulse ramps.
Lesson Ten: Corner rampsCorner ramps had been bugging me for a while now, so i built a simple test rig:
above below
#▼═════ ▲#
║
With a SE (╔) track ramp.
First of all, send a cart up the ramp: no matter what i do, when given straight track, the cart will move diagonally and the first step aside happens after 11 steps, adequate for a lateral component of just under 5000 speed, i.e. the acceleration gained by a single step on a ramp. Curiosly, while the corner should convert all south-to-north velocity of the cart into west-to-east velocity and the ramp slants to the south, the aberration was to the north.
Unsurprisingly, the culprit is the checkpoint bug: almost always, a corner ramp passed upward leads to a checkpoint - the ramp slants south and the most sensible connections above are flat track or a west-slanting ramp. Thus, the checkpoint effect is applied: a) the next tile is crossed in a single step. b) compensative acceleration is applied
which is opposed to the ramp's slant. That's it - the corner outputs the cart on a pure-eastward path but
then the "compensating" speed is applied and gives the much-abhorred diagonality to the cart.
So, putting it in numbers: when a cart checkpoint-hops up a corner ramp, it loses 5000 from its original incoming speed to ramp acceleration, loses another 1000 for the corner, and the checkpoint doesn't "refund" the 5000 speed but rather (since it's applied after the corner turn) applies it as lateral/diagonal speed towards the "outside" of the corner.
A cart going up a corner ramp at any speed loses 5000x(time on ramp)+1000(corner penalty) speed, and gains 5000 lateral.That was the easy part.
Let's send a cart
down the ramp now.
If the cart is fast enough (about 45.000 minimum), it takes the corner and continues perfectly straight in the corner's exit direction, with a speed loss of ca. 6000. I tried it with a highest-speed roller, and the cart going through a corner ramp would emerge at 44.000 speed, while a cart going down a straight ramp would gain ca. 5000 and emerge at 55.000.
Once again, we're dealing with checkpoints and a corner, so let's step through it:
On the corner ramp, all acceleration goes to the side, it doesn't accelerate the cart in its original travel direction. Here, we have a cart going west, which is accelerated south. Unsurprisingly, the westward speed isn't increased by this event. At the
end of the turn on which the cart wants to leave the tile, the corner comes into play, converts all westward to southward motion overwriting the extant southern vector, the acceleration gained is therefore lost. On the next step, the cart reaches a checkpoint and to compensate, it is "accelerated" 5000 units to the north. Summa: all southward acceleration was ignored because of the corner, but the compensative deceleration still applies, so the cart loses 5000 speed, plus 1000 for the corner. 6000 in total.
What's that about a 45.000 minimum speed? Ah well, losing speed on a down ramp is not the weirdest thing here. A cart moving at lower speeds than that is liable to malfunction even more blatantly. A cart propelled by a dwarven push emerges at a mostly-south-and-slightly-west trajectory, going off the straight line after two tiles. A cart entering the ramp at between 30.000 and 40.000 speed leaves at an almost-45° angle, a very sharp diagonal. It took me quite a while to think up a solution for that one, but i think it works out:
Corners are only checked when a cart tries to leave a tile, and they only check whether the side opposed to the "border" over which the cart is trying to leave is connected. In understandable: if a cart on a southwest heading is trying to leave a tile going over the western border of the tile, the pathing algorithm checks if the tile underneath is a track corner with an eastern connection. If yes, the cart is turned around towards the corner's other connection. If the cart tries to leave over the southern border, the algorithm checks whether the tile is a north-connected corner. If the checked border is not connected or if the tile isn't a corner, the cart leaves normally and its speed(s) is (are) unchanged.
So what happens with these slower carts is this: they move so slowly to the west and thus pick up so much southward speed on the ramp, that the cart's "exit" direction from the tile is south (or SW (??) in the case of the somewhat-slow cart), and thus the corner has no power over them. Consequently, they move off on their screwy diagonal course.
A cart going down a corner ramp, properly taking the corner, loses 5000(checkpoint compensation)+1000 (for the corner)=6000 speed, independent of lingering time on the ramp. If time on the ramp is too long, the corner starts checking the wrong (unconnected) side of the tile when the cart tries to leave and no longer applies. In that case, the output trajectory is purely diagonal, presumably incoming speed in the incoming direction + 5000x(lingering time minus one) lateral (towards ramp slant), no corner penalty.
Bodycount: nothing new, no new tests required. I just wrote up what i had worked out previously.
This concludes our course on Minecarts. Annotations, corrections, claims of priority will be gracefully accepted and carefully considered. Possibly. I've tried to link to sources and earlier findings. I owe a large debt to other players for their research and inspiring inventions.