v50 Steam/Premium information for editors
  • v50 information can now be added to pages in the main namespace. v0.47 information can still be found in the DF2014 namespace. See here for more details on the new versioning policy.
  • Use this page to report any issues related to the migration.
This notice may be cached—the current version can be found here.

User:Larix/MPL/1

From Dwarf Fortress Wiki
Jump to navigation Jump to search

Foundations: minecart physics

MPL (Minecart Pathing Logic) opens and closes buildings mechanically to switch the paths of moving minecarts between binary alternatives. To run long-term logic circuits on this basis, we need ways to set and keep carts in motion and basic concepts of switching.

Gaining Speed[edit]

Minecarts can receive speed from installations on a track in two ways, from rollers and from ramps. They can also get moved in the course of "route" handling, being pushed, ridden or guided by a dwarf, but guided carts largely ignore terrain and pushed/ridden carts require the presence of a dedicated labourer on the site for each such action, which is rarely desirable in dwarven computing. Moving a cart via "pushing" it is nevertheless useful to test small circuits without the need to build powered machinery or linking up levers for a starter mechanism.

Rollers are pretty straightforward: they increase a cart's speed to the roller's "operation speed", in the roller's movement direction. Operation speeds are:

  • lowest - 10.000
  • low - 20.000
  • medium - 30.000
  • high - 40.000
  • highest - 50.000

Minecart speeds are calculated in 1/100 000 tiles per game "step". A highest-speed roller will impart a speed of half a tile per step. Higher speeds are easiest achieved through ramps (notionally an effect of gravity), which can get a cart up to 270.000, between two and three tiles per step. That's over five times the speed imparted by a highest-speed roller. Even higher speeds are possible but not very practical.

There are a few not-so-obvious caveats concerning rollers:

  • Rollers only increase, never decrease speed. A cart moving in the roller's direction but faster than the roller's operation speed will be unaffected.
  • Direction is important. A cart moving "against" the roller's direction is effectively moving at negative speed in the roller's direction, so the roller will attempt to "increase" its speed in its operative direction. This is done by substantially reducing the cart's movement speed (by 100.000 per step), and if that lowers it below zero, movement will be reversed, sending the cart off in the roller's direction. This "braking power" of rollers is not dependent on the roller's set speed. A 1x1 lowest-speed roller will stop and reverse a cart propelled by a highest-speed roller.
  • A cart encountering a roller working perpendicular to its movement direction will still have its movement speed increased in the roller's direction, while the cart's movement speed in its original direction will remain unaffected. The result is a diagonally-moving cart. The best explanation for this is that minecarts' movement is calculated separately on the three spatial axes. If a cart is moving with some speed on the x-axis and encounters a roller also working on the x-axis, the roller will only change the x-movement parameter and nothing peculiar will happen. If the cart encounters a roller working on the y-axis, the roller will "set" the cart's movement speed on the y-axis, without changing the x-movement parameter. The cart will now have non-zero speed on two axes. That's problematic, because a minecart will remain on its course unless it runs into a corner tile from one of the corner's "connections". Diagonally-moving carts will move at some angle to actual tracks, completely ignoring their directions (including track ramps, meaning that launching or accelerating them via ramps becomes almost or entirely impossible). They can re-join normal tracks if they encounter a properly aligned track corner, but determining whether their movement direction is sufficiently "in line" with a corner is very much hit-and-miss; this "catching" feature can be used for some rather esoteric minecart switches, but takes very carefully set-up tracks and rollers.

Ramps give a uniform acceleration towards the ramp's "down" direction. A cart going across a track ramp will be accelerated when moving "down" and decelerate when going "up". So far, so obvious. However, the exact rules get rather complicated:

  • a ramp will only provide acceleration if it has an actual "up" and an actual "down" connection - at least one "branch" must touch a wall, exactly one a "non-wall". A ramp not so connected will provide no acceleration. A cart will accelerate if it is moving towards the "down" connection of the ramp, regardless of where it came from.

This is the basis of "impulse ramps" - a cart moving to the north and passing over a track ramp connected to a wall to the east and with a proper "down" connection to floor to the north or west will accelerate, even though the cart clearly didn't enter from above. A cart set down on a legal ramp will roll "down" the ramp, gaining speed from a complete standstill. The reverse is also somewhat true - tracks which are not properly connected will be treated as flat floor, even if z-level-changes take place. Sending carts up such "flat" ramps is entirely possible, but quite speed-sensitive.

  • To make matters even weirder, proper ramps have a different tile length than ordinary floor - they are about sqrt2 normal tiles long/wide. The game needs to convert distances and relative cart position whenever a cart moves from flat floor to ramps or vice versa, or when switching between ramps with different slant (down direction). This conversion causes very peculiar behaviour:

- carts will always touch a tile with a new alignment (first flat tile behind ramps, first ramp tile behind flats etc.), they cannot skip it.

- when coming off ramps to a different kind of tile (flat tile or different-slanted ramps), the cart "teleports" through the new tile to its very end. It will spend exactly one step on this tile, regardless of its incoming speed. Furthermore, it'll gain one step's worth of acceleration opposed to the last amount of ramp acceleration it received. I.e. when a cart leaves a line of north-pointing ramps to flat track, it'll spend exactly one step on the first tile of flat track and gains ~5000 units of southward speed.

The independence of acceleration from actual level changes and the "teleportation" feature of the "checkpoint" tiles when leaving ramps allow to provide perpetual motion to minecarts:

#
# #
#
i m p u l s e r a m p d o u b l e r a m p " b o o s t e r "

The impulse ramp cycle to the left accelerates the cart everytime it passes over the ramp from north to south. The implementation of ramps doesn't care where a cart comes from, as long as the ramp is properly connected, it will accelerate any cart that's on it.

The booster cycle to the right makes use of "checkpoint" conversion. The first ramp it crosses will be passed normally, giving the normal acceleration. Checkpoint effects mean the cart then passes the "upward" ramp in a single turn and leaves the pit, with a net gain of speed. The cycle can be run in both directions.

Practically, both designs must be implemented differently - the cart will soon overspeed and blast out of the cycle if built like that.

Basic pathing rules[edit]

Minecarts are completely deterministic. If two carts encounter an identical pathing situation with the exact same entrance parameters, they'll behave absolutely identically. There are no known components of chance involved. This doesn't mean carts cannot behave in unexpected ways - there are many obscure rules for what a cart can and cannot do or how movement is resolved.

On flat track, a cart will generally keep moving in a straight line. It can only change path by moving over a corner track tile - with exactly two connections - with no exit in the direction the cart is moving to. I.e. a cart moving from south to north will keep this direction unless it encounters either a SE or a SW corner tile. It will of course stop if it encounters a wall or other solid obstacle and may revert or go on a diagonal if it passes over an active roller. Carts moving very quickly will ignore corner tiles unless the straight path is blocked by a solid obstacle, like a wall or door.

On ramps, pathing gets a bit more complicated, because acceleration becomes a factor and because ramps can move a cart to a different z-level.

  • As has been mentioned, a ramp will cause acceleration if it is both "up"- and "down"-connected. Only one down connection is allowed, a track ramp with more than one "down" connection will not accelerate a cart. More than one "up" connection, however, is perfectly acceptable. A track crossing can accelerate a cart just fine if three of the connections touch walls and only one a floor or hole.
  • If the down direction is perpendicular to the cart's entrance direction, the cart will move diagonally to some degree. Whether such diagonal acceleration sends the cart on a diagonal trajectory (usually causing it to slam into a wall and stop), fails to move it off its path or bends it around a corner, depends on the entrance speed and architecture of the circuit.
  • Carts will jump across open pits even at fairly low speeds, but will always enter a pit containing a ramp (preferably a track ramp, but unengraved ramps are entered just the same) when coming from a floor tile or bridge and moving at less than 50.000 speed. Carts going faster than that cannot enter a downward ramp when coming from a flat tile. They will go down the ramp if they already came from a proper ramp, a long slope consisting of nothing but downward ramps works perfectly fine and entering a downward ramp from flat floor can be forced through an impulse ramp, although those tend to make a route one-directional. Corners on upward track ramps cause a degree of diagonal movement which must be cancelled out by a flat-track corner behind the ramp, otherwise the cart will leave its path after a while.
  • Carts jumping over a hole are in flight for six steps. During this time, they are not in contact with the floor and will not interact with ramps, corners, track stops or pressure plates they pass over. This feature can be used to let carts bypass track features depending on their speed or movement direction.
  • Carts going up ramps to tiles with open space above them (i.e. no closed ceiling) can "jump". This can lead to carts bumping into the ceiling (and stopping) or jumping past engraved tracks on the tile just behind the ramp. This can be prevented by putting a "downward" impulse ramp on the tile behind an exit ramp.
  • Carts will only go up a ramp if the ramp has track connection to the wall which the cart tries to climb over. If a ramp is not so connected, the cart only recognises the wall and behaves appropriately - bumps into the wall or, if that's possible, follows an engraved corner.

Basics of track switching[edit]

To do anything with logic, we need something that reacts differently to different "inputs". In MPL the different reactions take the shape of a choice of path, where different inputs result in different paths taken. Input generally takes the form of signals or power, and there are various ways to turn such an input into a pathing choice. A simple and very versatile switch mechanism is the roller: it acts directly on the movement parameters of a minecart, so of course it can affect the path the cart takes. The roller-driven track switch is in fact shown as the first option in the "minecart" article. The most effective design makes use of the fact that rollers working against a cart's movement direction will reliably turn the cart around. This is much more reliable than using a roller working towards the desired "branch direction", due to roller/cart interactions explained above: if the "unswitched" cart goes from south to north and the branch is supposed to go off to the east, a roller pushing to the east will send the cart on a diagonal northeasterly course that requires catch corners to get under control; but a roller pushing towards the south into a NE corner will revert the cart and the corner will send it on the easterly course without any need for further regulation; this even works flawlessly when the roller sits right on top of the corner. The combination of path reversal with the guiding power of the track corner results in a perfectly reliable, compact and fast-acting switch layout. Since rollers are driven by power, additional gear assemblies placed in the power train provide a very natural interface with mechanical logic. Constructing switches with rollers placed perpendicularly to the incoming cart's direction is possible, but the early-supposed method of restraining walls is utterly obsolete (opposing roller into a corner is superior in all regards). A "catching corners" setup offers some interesting options but is complicated to construct.

Tracks can also be switched by "overwriting" a corner with a straight pseudo-track by opening or closing a bridge. Bridges are treated as all-directions track by minecarts and will overrule the directions of track engraved into the floor beneath when extended/lowered. We would construct a bridge on top of a track corner (one tile is enough, but larger bridges may offer additional options) and extend/retract it by our input. The cart will follow the corner when the bridge is raised/retracted and move in a straight line when the bridge is lowered/extended. Other "above floor" building types like hatches (and presumably bars and grates) will not overwrite track directions when closed.

Buildings that serve as obstacles in a cart's path, like a raising drawbridge, a door, floodgate etc. will, if put in the way of a straight-moving cart, simply stop it. Combined with a roller, they can still be used in logic to introduce a delay and if you're working with very fast-moving carts, they can be used as another type of switching device by putting it directly behind a track corner. The fast cart will ignore a corner and continue in a straight line if open floor is available in that direction, but will follow the corner if the straight line is blocked. Opening/closing the door or other building will thus switch the cart between going around the corner and going in a straight line. This paradigm can be used to construct very fast-reacting logic circuits with comparatively few buildings and mechanisms. I've explored the concept and found it quite promising. More information on this "Cart-and-Door-Logic" can be found in chapter 7.

Path-blocking buildings can be used in another switching schematic, too, by combining them with ramps to accelerate carts stopped by the obstacle. This is the basis of this entire logic discipline.

Combining ramps with path-blocking buildings[edit]

A cart encountering a solid obstacle on its course will entirely stop moving in this direction. With the ability of ramps to provide acceleration to any minecart touching them, carts can be made to return from such collisions: construct the obstructing building immediately behind a track ramp; a cart that cannot pass will "roll down" the ramp after stopping and gain speed in the ramp's downward direction. For logic purposes, this will usually be the "return" direction, away from the obstacle. The return path can also branch the cart away from the actual origin location. If the obstacle can also be removed/opened at will, a cart can now either pass through or return, meaning we can have a single "input" direction and two different "output" directions, and the cart will reliably take one of those two depending on the "signal" governing the obstruction. Doors, hatches, grates, bars, bridges and floodgates all serve as obstacles to minecarts and can be switched between open and closed by levers or pressure plates. Using them, we can switch minecarts between different paths (in binary fashion).

Hatches are a very convenient tool to switch paths of incoming minecarts: they react instantly to received signals and are easy to build. The most reliable switching method is to put the hatch cover over a ramp a cart is trying to pass from below. In this case, the cart will never be in the same tile as the hatch: if the hatch is closed, the cart will bump against it from below and roll back down the ramp. If the hatch is open, the cart will pass directly from the ramp tile below the hatch to the floor tile next to the ramp and hatch.

Alternatively, a hatch can be put over a ramp and the cart's path routed across the hatch itself. If the hatch is open, the cart will instantly dive into the hole (a horizontally-moving cart will treat a downwards-leading track ramp as a track corner and will not jump past the hole but dive into it, provided it is moving at less than derail speed); if the hatch is closed, the cart will pass over it in a straight line. Hatch covers have the same friction as not-engraved floor. Except in case of very slow-moving carts, this higher friction is irrelevant. Should the hatch open while the cart is directly on top of it, the cart will not enter the ramp in the normal way, but rather loses its entire forward momentum and "falls" into the pit. It will pick up speed from the ramp it lands upon, but will behave differently from the usual cases. A hatch cover over a ramp is also a very convenient signal-operable starting mechanism for minecarts. The cart is simply placed on top of the closed hatch cover and gets dropped onto the ramp below when the opening signal is received.

Design: from the side:

  H__
__/#

from above: closed hatch:

.¢==

open hatch:

.▼==

Doors also react instantly to signals but require an adjacent wall to be built. Constructed walls can be deconstructed after the door is built, this will not impinge the efficiency of the door. To switch tracks in combination with ramps, the only applicable use of doors consists of placing the door on the level floor right next to a ramp-hole a cart tries to emerge from. If the cart encounters a closed door while trying to ascend, it will fall back into the hole. This design works similarly to the first application of hatch covers. It can cause an operation error when a door receives a close signal the very same instant a cart is passing through it. Since the cart will only spend a single step on the exit tile, this will not happen frequently, but unless you invest in measures specifically to prevent it, it will occur from time to time. The door will get wedged open in spite of the signals indicating it should be closed, but the cart will keep moving normally.

Design: from the side:

   D_
__/#

from above: closed door:

.▼D=

open door:

.▼==

Floor grates and floor bars work similarly to hatches, flood gates, wall grates and vertical bars similarly to doors, with the notable difference that each of these buildings has an added 100-step delay before reacting to a signal. Apart from designs hinging on specific delays before releasing a cart or switching a track, those buildings are largely useless for our purposes.

Raising bridges can be used in the same way as doors, but react in opposite ways to signals: a raising bridge switched "off" will grant passage, when switched "on" it will block passage. Retracting bridges work like hatches, but can span larger gaps than the one-tile hatch covers and provide less friction. Bridges take 100 steps to react to a signal and will throw, hurl or crush a cart passing over them while they change state, sharply limiting their usefulness in logic.

Logic, building blocks: Operative ramps[edit]

I built most of my pathing logic with double-ramp pits, with hatches over one of the pit exits to switch the paths while providing sufficient speed to keep the carts in circulation.

The simplest design has been mentioned above - the straight double ramp:

from the side (notionally):

__..__
##\/##

from above:

upper level:

==▼▼==

bottom level:

##▲▲##

track on the ramps: == (EW)

I'll go through the possible cases assuming first a cart coming from the west:

If the exit is open, the cart will roll down the ramp, accelerate and emerge on the other side, continuing east, at increased speed.

If the exit is closed, the cart will roll down the ramp, bump into the obstacle (hatch/door/wall/ceiling) and gain speed from a standstill on the eastern ramp. Due to ramp teleportation, that will give it enough speed to emerge from the pit again and return to the west.

If a cart falls into the pit, either coming from the north or south or dropped (say, by opening a hatch cover it was sitting on), it will accelerate on the pit it fell into and emerge from the adjacent pit. A cart falling into the western pit will try to exit to the east.

Of course there are all kinds of exceptions for particularly fast- or slow-moving carts as well as for carts that enter the pit on a diagonal trajectory.

Another very simple but somewhat less predictable design is the "loop ramp":

from above:

top level:

=▼
=▼

bottom level:

###
#▲#
#▲#
###

engraved track on the ramps

╗
╝

A cart arriving on the northern track will roll into the northern pit, gains speed on that ramp, teleport-lifts out the southern ramp and leaves on the southern track. Alternatively, it will not gain the proper kind of speed on the first ramp, thus will not get off the southern ramp but accelerates off this ramp too, lifting itself out of the northern ramp and returning along that track. Peculiarly, the "back-swing" only happens in a few cases - it should only occur as an unusual effect of corner pathing - the cart either tries to leave to a diagonally-adjacent tile or towards the wall while on the "up" ramp. In those cases, the cart can collide with the walls of the pit and start over accelerating from scratch or gets redirected to the tile it came from instead of leaving the pit. Whether this happens depends on the exact entry parameters of the cart, both speed and carried-over distance.

A hatch cover or other means of blocking the exit from one of the ramps will ensure a cart will return on its path, which is evidently only an actual switching method if the cart would have passed through originally.

Other means of combining pairs of ramps in a single two-by-one pit aren't functionally different from the above two.

It is possible to build functional ramped pits larger than that, although one must keep always in mind that to provide acceleration to a cart a ramp must have at least one wall connection and _exactly_ one "down" connection. Ramps with multiple wall connections work adequately, but a ramp with more than one downward connections will not accelerate carts; apparently the game needs a definite cardinal direction to accelerate a cart towards, if two or three directions are offered, the engine decides to pick "none of the above".

The movement pattern inside larger pits can easily become too complicated to base logical operations on, the largest pits i worked with contain no more than three ramps. There's a lot of potential there, both for fiendishly clever devices and immense operator frustration.