Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Topics - Larix

Pages: [1] 2 3
1
DF Dwarf Mode Discussion / Beards in Trees (0.43.05 fort)
« on: November 26, 2017, 09:10:01 am »
Nishasob, "Tradeboards" has lasted for 27 and a half year now and is home of 90 dwarfs (over 50 of which were born on site, since this was played with a population cap of forty). I had hoped to do it without digging at all, but the mandatory first mood required rough gems, so a very small mine was opened and instantly sealed and never touched again after some rubicelles were secured. There may have been a boulder or two from that mine used by the masons, but other than that:

no real digging, no underground constructions. All stone and metal came from imports, the most important building ressource was wood. I kept invaders off for most of the time, which probably didn't do much since the place was fairly peaceful anyway.

Tally after turning invaders on and changing the goblin civ's raws to a siege trigger of 50 people:
megabeasts: zero. Some named critter ended up slab-able as "missing" which might have been a forgotten beast - didn't show up on the units list, though.
semimegabeasts: one giantess, one ettin, one cyclops, two minotaurs (no werebeasts, no vampires, no necromancers)
goblins: mundane all-goblin assault squads, four attacks in total, spread over seven years. 96 goblins slain in open-field combat. Three dwarfs got titles (seems to require five notable kills).
The world used was quite young, so there were no visitors at all to the tavern/temple/library and no finished books were on offer in trade.

All notable slain units got a slab, as well as the one dwarven casualty: a child who was spooked by a black bear, fell into a pool and drowned (no combat report, so probably tried to climb/jump down and slipped). Curiously, some skunks were captured and tamed, and each and every one of those who died (well over a hundred) is eligible for a slab. Only applies to skunks, too, not to other (tamed or common domestic) animals.

Around year fifteen of the fort, caravans started to bug out. Elves and dwarfs recovered and kept visiting, humans had eternal stuck units on site and never sent a new caravan. From year 20 onwards, i regularly forbade the depot just before caravan arrival to force the merchants to spawn in random, hopefully un-bugged spots and it worked alright, although of course it meant no more wagon visits. The weird "phantom units" near the original entrance's map border (tiles which dwarfs have to crouch down and crawl through to pass as though an invisible immobile creature stood there) persisted and new ones were found on the relocated entry; i suspect they have something to do with the bugged caravans but have no idea if they're cause or effect.

Wealth: 9,2 Mio "created wealth" on site, 17,5 Mio exported, ~240 000 gifts. We generated unreasonable amounts of cloth crafts and prepared meals. Seven artefacts generated by moods, five scrolls, 27 named weapons and shields.

Building in trees

Tree trunks and branches provide support for buildings; walls, floors and the like can be built right on top of branches and twigs without trouble. Furniture and shops can be constructed on branches, too, but not stockpiles. I have not tried muddying branches to see whether farms can be constructed on them - but you'd have trouble getting them properly wet, with more tree and thus no fillable "pond" hole above them. Muddied built platforms (of any material, wood, stone, metal, glass, as long as it's muddied) are usable for farms as long as the z-level belongs to a farmable biome. I have a working farm on z+7, but a muddied platform on z+11 has "no seeds available for this location".

Most parts of a tree count as "outside", which means you have to construct a roof over them before you can install beds, chairs, tables or coffins. Bridges provide sufficient cover and take less material to build than normal floor (and provide happy thoughts if traffic passes by them). Trees take no harm if a bridge is constructed above them.

Interaction between bridges and trees is weird - twigs are not walkable, and bridges don't make these tiles walkable, either. If you have to cross twigs to pass e.g. from one tree to another, you'll have to build a floor over them.

Trees keep on growing over the years and if a tree spreads its twigs into the area of a bridge, it can make the bridge unpassable in a near-invisible fashion. Fun to troubleshoot. I was lucky and spotted the few cases where this happened before a dwarf came to harm.

Trees don't grow all that large when you look at the normal space consumption of a dwarven fort and don't provide much unbroken usable area: you won't have many opportunities to stick workshops in trees and rooms entirely based on branch floor won't get too big, either, which means your nobles will require fancy furniture to satisfy their room requirements. The most valuable furniture you can generate without imports are plant cloth bags and ropes.

You'll usually have 5+ levels of airspace that trees won't grow into. You can fill that area with buildings without harming the forest underneath. Much of my building efforts were eventually spent making dwellings above the trees.

If you want to use the trees as foundation of your dwellings, you'll have to think about your woodcutting strategy, since wood will also be a major ressource, for building, for crafting and as fuel for metalworking (in case you want a fort that can withstand attacks). While wood only gives one block per log, building from wooden blocks can still be useful - it keeps walls smooth and enables you to still get wood imports from elven and human caravans: all logs that you own in an unforbidden state are compared to your headcount, and if you have fewer logs than citizens, a caravan will try to bring enough logs to make the numbers equal. So - forbid unreachable felled wood (fallen in water, stuck in other trees), forbid windmills/axles/waterwheels after construction, build from blocks instead of logs - logs in constructions cannot be forbidden.

Spoiler: Piccies: (click to show/hide)

P.S. the fort has twenty melee soldiers and six archers. Six of the melees and all archers are only activated in case of trouble - and stationed far behind the front lines, as last backup. Two of the melees are not weaponmasters. The two most senior squads (made up of the first fort-born children to grow up, so started around fort-year thirteen) have been training non-stop for over ten years and are legendary (+xx) in all military skills (including biter and misc. object, one bit a goblin and shook them so hard the gobbo's spine broke), only "Leader" skill is merely proficient/competent in the squad leaders. They're the only squads to have seen actual battle and the only time one got wounded was when a hammerdwarf got enraged from being crowded during a training session and punched the spearmaster's ankle so hard the joint shattered.

I've never seen it in full swing before, so was quite impressed by how many ornaments dwarfs tend to pick up, especially with a workshop being on "make cloth craft/R" for years and years, with several legendary clothiers to do the work. It's getting difficult spotting the actual clothing among the up to sixty amulets, rings, earrings, bracelets and figurines the average dwarf is decked out in. I summed up the worn goods of the metalsmith i'd been paying extra attention to and it came out as ~18000 military equipment (steel gear including a masterwork spear), ~2500 clothing and ~15000 owned ornaments. Not every dwarf is as grabby, but several thousand ☼ of trinkets per dwarf looks pretty normal. Other small goods were only occasionally claimed - large glass gems, coin stacks...

The fort managed to get a beekeeper and a wax worker to legendary skill. All raw cookable food was kept in a barrel-less stockpile and an extra royal jelly stockpile set up near one of the kitchens, so the royal jelly was properly cooked off once we stopped collecting nuts. That's no joke, as far as i can tell cooks' primary preference is not "solid food in barrels before everything else", but rather "anything that is extracted from a container before bringing it to the kitchen before everything else", which does explain the preference for solid barrel-contents but also the insistence on cooking seeds - one by one - before touching stuff outside of containers and contained stuff that cannot be taken out of its container, i.e. flour and liquids.
Tl;dr - cooking nuts drives you nuts because they're drawn from bags one by one and have top priority over stuff sitting in the open.

We struck coins every year and ended up with 203 stacks, i.e. 101500 coins total. 100000 of those ended in the "coin vault", a coin stockpile behind a floodgate operated by a lever personalised to the mayor. (The remaining three stacks were claimed as personal property of dwarfs with fitting metal preferences.) The lever also opens/closes a hatch cover right next to it, in case the mayor desires to flush an unwelcome visitor from his sight. Right next to the lever is also a same-colour lever personalised to the duchess, captain of the guard, champion (main fisherdwarf/woodburner) and militia commander, which releases the cats. It's a secret special defence which is almost certain to be entirely useless, since attackers are quite unlikely to get anywhere near the cat cage during an invasion.

We ordered about sixty cut gems per year from the dwarven caravan and put them in our archer captain's capable hands to adorn random crap lying around the jeweller's shop. Apart from the usual mega-encrusted waterskins, we bought a musical instrument made of "liquid dark" from the elves (a bagpipe with a silk bag; since elves don't have normal access to silk, this results in random special materials like demon and divine silk; "liquid dark" was apparently the latter, since the instrument cost almost 30000, with no exceptional craftselfship involved) and encrusted it as much as possible - it broke the 100 000☼ mark eventually.

PPS: of course the fort would likely crumble if attacked by a fire-using foe. While wood walls are immune to flames, the construction is intertwined with the trees of the forest and collapsing trees might well take out crucial supporting structures.

2
DF Wiki Discussion / Minecart data dumps (Expanded)
« on: May 02, 2016, 09:37:34 am »
I've finally checked out DFHack's "watch-minecarts" script and can definitely say that way too often the data have been misinterpreted.

The cause is a simple rounding issue: the data printed to console have a "co-ordinate" field. And to find the actual tile on which the cart is present (and which affects it) you have to round down or up to the nearest integer. I verified this by stepping through moves of a minecart and checking against the watch script, taking note of the exact location data whenever a cart visibly moved from one tile to another. This always happens when the coordinate shown goes past x.5. This simple fact elegantly explains why ramps and rollers on tile (x) start affecting a cart as soon as coordinate is at least (x-1).5, and no longer have any effect once the coordinate is (x).5 - those coordinates are the actual borders of tile (x). Track features like corners, ramps and rollers only affect the cart while it's on their tile, their influence doesn't stretch into the previous tile.

Spoiler (click to show/hide)

In other words: tile (20:20) contains the coordinates (19,5:19,5) to (20,5:20,5). The exact coordinates (20,0:20,0) represent the middle of the tile. If the tile's a corner, the corner applies when the cart passes the x,5000 point - and since rounding is done arithmetically and not by truncation, that means it applies at the very end of the tile.

I'll try to remove the misinterpretations currently present in the minecart article.

PS: Lifting a dump from this thread thanks to user fricy, because i just won't install DFHack for that purpose:

Code: [Select]
(1.)016-65.905400590001535400
(2.)016.29990.29990.29990.299959000153000
(3.)016.59980.29990.2999059000153000
(4.)016.89960.29980.2998-0.000159000153000
[...]
018.39710.29930.2993-0.000159000153000
(10.)018.63880.24170.2992-0.000159000152-100
(11.)018.884930.246130.34810.048959000152000
019.165630.28070.3970.048959000152000
[...]
(25.)025.961160.730191.03270.048959000145-100

I added cardinal numbers for lines of interest and cut out uninteresting data.

It shows a cart coming off a medium-speed roller and diving into plain downward ramps after two tiles of flat floor.

I don't know how faithful the dump is to the game's internal data structures, but i'll assume it's generally correct:

My interpretation:
All the periods in this dump are not delimiters between data chunks, but plain old decimal points. If you see a point, whatever's left of it is probably the full part, and what's right of it the fractional part of a single number. The borders between individual numbers are mostly invisible.

So the first number we're seeing is not a "tile identifier" that stops at the period, it's the coordinate given to four decimal places, which must be rounded arithmetically to find the current tile occupied. The actual game tile occupied is not shown directly by the script, it must be derived by rounding the coordinate. As i said above (and put onto the wiki), the middle of the tile is the zero-fraction sub-coordinate, the borders are the +/- 0,5 coordinates.

The cart starts out in the middle of tile 16 (shown as "16", i.e. 16.0000). In the first line, the other data are a bit iffy to interpret, for the basic structure, let's first look at

the second line:
current location: 16.2999 (speaks for itself, just over halfway between the start - middle of the tile - and the tile border.
movement since last measurement: 0.2999 (the zero belongs to this value, not to the current location co-ordinate; see above - the script usually strikes "trailing" zeroes), on the x-axis.
current speed: 0.2999 (positive, on the x-axis)
speed change since last measurement: 0.2999 (accelerated to medium-roller speed by the roller, then decelerated by one tick due to track friction)
This also resolves the most likely meanings for the remaining entries:
current y-location: 59 (.00000) - middle of tile 59 in the other "flat" dimension
movement on y-axis since last measurement: 0
current speed on y-axis: 0
net change in y-speed during last turn: 0
current z-location: 153 (.00000) - standard floor (notional middle!) of z-level 153
movement on z-axis since last measurement: 0
current speed on z-axis: 0
net change in z-speed during last turn: 0

- each of the zero values (location change, speed, speed change) is given as a plain zero without decimal points or anything, without any indicator that a new datum has begun. Since the cart moves in a straight line, the y-parameter data stay the same throughout the run, while the z-parameter changes by a flat one everytime a new ramp down is entered, but this happens without actually generating z-axis speed, it shows -1/0/0. It's not a "minus one hundred", it's a "minus one" followed by two zeroes, three distinct data; the dump script unfortunately doesn't separate individual entries in the data structure in a recognisable way. We need to internally decipher e.g. line two
016.29990.29990.29990.299959000153000
into
(0/)16.2999/0.2999/0.2999/0.2999/59/0/0/0/153/0/0/0.

Spoiler (click to show/hide)

In the third line, the cart moves to the next tile (16.5998 rounds to 17). The net zero speed change shows that acceleration/friction are processed before the cart moves - the cart begins its move on a roller tile and ends it on a non-roller tile; its speed at the end of turn is determined by the roller tile, i.e. the turn's starting tile. (NB: the same applies to ramps - ramp acceleration takes place before a cart takes its turn, thus a cart moving into a ramp tile is not accelerated on the turn in which it enters the ramp, only during turns which start on the ramp, including the turn on which the cart eventually leaves the ramp.) (NB2: the cart has a zero net speed change, the roller tile is not frictionless. What happens is that the roller first accelerates the cart from 29990 to 30000 (medium roller's operation speed), then track friction reduces it back to 29990.)

In the fourth line, the cart begins its turn on a flat non-roller tile. It is slowed down by track friction before taking its move, thus drops to 0.2998 speed before moving 0.2998 of a tile. The speed change is shown with the negative sign, as -0.0001. As far as i can tell, speed and movement are tracked only in two dimensions, i.e. depending on whether a cart's moving north or south it has negative or positive speed/acceleration.

In the tenth line, the cart moves onto the ramps. The first ramp is tile 19, which begins at coordinate 18.5. Entering the tile immediately moves the cart down a z-level without generating vertical speed (the -1/0/0 on the right) and the distance calculations switch to ramp mode. Presumably, the cart moves 0.1029 on the track until the ramp, then uses its remaining ~0.196 distance to move into the ramp itself, with changed distance calculations. The different distances are easier to see on the

Eleventh line
Movement since last: 0.24613
Speed: 0.3481
Speed change: 0.0489
I.e. speed is tracked without change, but distances on the tile are divided by sqrt(2). Feeding the numbers into my calculator gives divisors ranging from 1.41428 to 1.41432, i.e. the game probably uses a constant divisor (1.4143 or so), producing a very small rounding instability. Notably, distances on the ramp are tracked to five decimal places, while speed, speed increments and flat-track distances only really make use of four decimal places.

Twenty-fifth line:
Movement since last: 0.73019
Speed: 1.0327
Here, speed goes past one standard tile per step for the first time. I think this line shows quite clearly that the many zeroes seen before decimal points in previous lines indeed just display the "full" part of the numbers, periods shouldn't be mistaken for delimiters between data.

Minecart data dumps get much funnier when going around corners, because carts "teleport" from one tile border to another, giving substantial distance increments, and the direction change produces fairly large displayed speed changes. When multiple speed changes take place in the same turn, the data dump script isn't very enlightening, since it just records the net change: a cart leaving a ramp actually accelerates on the ramp, suffers the related track friction, makes its standard move, then gets teleported to the end of the checkpoint tile and is checkpoint-accelerated in the opposite direction, all in the same turn. The net speed change is a paltry ten ordinary friction, and that's all the data dump script is able to show.

PPS: carts pushed by a dwarf onto normal track leave the new tile a mere two steps after first showing up in the pushed-to square. This doesn't seem to fit expectations: cart is pushed to the middle (not the start! :P ) of the tile, then must move thrice (at ~20k push speed) to leave the tile, but we see this happening a mere two steps after we see the push. How come? The reason is simply move order - there's more than just the push happening in the turn of the push. Dwarfs' slot in the movement queue comes before minecarts', and the push is the dwarf's, not the minecart's action. I.e. the dwarf uses his or her turn to "set" the cart into the middle of the adjacent tile and provide it with 20k speed. The cart still has to take its own turn for the same game step, which it does by losing 10 speed to friction, then moving 19990 distance units forward: the cart finishes the push turn 0,2 tiles past the middle of the pushed-to tile and only takes two more turns to pass over the tile's border. Or, differently put, it does take three moves to get off the tile, but the first move is already taken on the turn on which it's pushed.

Move order may be worth working into the wiki somewhere...

3
The dwarfs of Degelkol, Galleywheels, don't think much of military prowess. Consequently, they have no standing military and in fact no citizens with significant military skill.

That doesn't mean they are pacifists. Their wealth has attracted many goblins and other hostile creatures. To keep themselves safe, the people of Galleywheels have built many traps. However, the items found in the "traps" folder are generally only the backup plan, goblins are mashed by various other contraptions.

N.B. Both Galleywheels and Blamelesscloister are .34.11 forts. I've tested the concepts in .40.24 and they still work, although the exact efficiency may have changed in some cases. Hard to say with un-co-operative goblins who rarely bother to show up.

Exhibit one: automated Atomsmasher.

        

Two 3x10 bridges that must be travelled lengthwise. The two doors in the middle enclose one tile of water (pond, filled from above). Whenever a door is opened, water spreads off the tile, the pressure plate in it (responds to 0-5 water) fires and indirectly triggers a 200-step repeater that controls both bridges. Bridges change state roughly every 105 steps. Creatures on the bridges while they raise are thrown around (unless they're on the wall tile, where they get crushed right away), stunning them, often breaking bones and effectively preventing them from moving forward. Creatures in the corridor while the bridges come down are crushed, destroyed with no remains. Very convenient, since it cuts out all the goblinite hauling. Since it's triggered by an opening door, trapavoiders are caught, too. On the downside, it also crushes merchants, diplomats and citizens when allowed.

Between uses, the water cell must be refilled via pond order. That's visible to the right - it's the level above. The traps are the backup in case some flyer gets through the pond opening. The connection between the smasher and the fort is through a raisable control bridge. For added safety, a citizen-triggered pressure plate frequently hinders dwarfs from commiting suicide by bridge - it opens a hatch cover in their path. If the control bridge is up, invaders will not path into the crusher.

To prevent mis-crushes, the repeater is triggered indirectly:



The hatch to the left responds to the trigger, but the cart can only enter the proper activation loop when the hatch in the southeast (orthoclase) is also open. That hatch is controlled by a dedicated "arm bridge" lever.

This was our first defensive machine, and it's been the go-to device when dealing with goblin/troll siege forces. No hauling, little mess, very efficient. It can't be used when an invasion force includes large animals and is useless against semi- and megabeasts (bridges break when trying to lift or crush something too big).

For the big stuff, our recourse was
Exhibit two: spike corridor. Once again, pretty simple:



Doesn't look like much, but these fifteen spike assemblies took out numerous large war beasts, a few titans, a roc and a dragon and two demons. It's run off a minecart repeater tuned to optimum period of 82 steps per full spike cycle. It takes four pressure plates to achieve this, which isn't optimal.
To the north and below, the corridor continues through several weapon traps, which in fact took care of a few particularly nimble victims.

The spike corridor gets triggered by lever-pull and can be selectively shut to the outside world or the fort.

Since the entrance to the spike corridor is rather exposed, we built an extra door just for diplomats (originally also for migrants):



A spider-web of underground tunnels, leading to a bridge-lock, guarded by a few weapon traps and a war dog. Since the entire surface is set to "restricted" pathing, it safely channelled migrants through the underground passages when we still got migrants. Dog and traps take care of ambushes and thieves that try to sneak in with the diplomat.

The caverns under Galleywheels were home to several massive beasts. While it's entirely possible to lure them with an artefact piece of furniture and poke them with spikes, we decided to try out some minecart applications:
with impulse ramps and/or the checkpoint effect, carts can be set to perpetual motion. A sufficiently heavy cart can deliver quite a punch, and with ramps, it can keep giving additional punches after the first one. The first design was a simple accelerator coil, tried out against goblins:

Exhibit 3a - goblin exploder



Cart circulates counter-clockwise in the six-ramp cycle, reaching maximum ramp speed. When the door to the south is opened, the cart exits, at bone-breaking speed. Anything not substantially heavier than the (metal) cart will be blown apart, but it seems to only hit one opponent at once. The cart is re-cycled by an impulse ramp on the collision spot, sent around the southwestern loop over a hole in the floor (so even if a crowd wants to enter, everyone tries the door instead of going around).

Not fully satisfactory, since with large opposing forces, the cart can get stopped on a flat tile. I think this test device failed half-way through an ambush.

Thus, improvement:
Exhibit 3, high-speed minecart grinder



A twelve-ramp loop. To get the cart around corners without losing ramp acceleration, corners go up a level. On the level above, there's another impulse ramp sending the cart back down on the other side. No matter where the cart collides with a target, it cannot be fully stopped. I built two grinders in a row, in case something got through the first one, and a lockable door and spike array, in case something got through the second. Nothing got through the first so far. Actually, we seem to have run out of forgotten beasts. Yes, that design has killed three forgotten beasts (not at the same time).

The design works against goblins, too:



And against trolls ;)

To make the whole thing start- and stoppable at will, carts are first deposited on mechanically operated hatches. However, those hatches attract trolls (and forgotten beasts). They have to stand inside the grinder to destroy the hatches, so that's actually still useful, but once the hatch is gone, there'd be no more way to stop the cart. So we _also_ installed one 1x1 retractable bridge in a corner of each grinder cell.

Large crowds can clog the grinders. It seems that a cart can only push one creature per tile, and large/heavy creatures, especially when there are several in one tile (like trolls while taking a hatch apart), can block a cart's movement into their tile.

So, not perfect, but adequate. Can deal with normal sieges.

It's also possible to build grinders with much less floor space - two ramps per cart are enough:

Exhibit 3b - chain of tiny grinders

     

The trolls got to grinder Nr. four out of nine. Once again, trolls clump together to take down hatches, blocking the cart until they spread out again. The grinder chain took out 26 units of a siege, which broke the morale of the rest.

Each grinder cell consists of two straight ramps, nothing more. Since they touch each other, they "lean" in opposite directions. A cart will keep bouncing between these ramps at substantial speed forever, or until offered an exit (above). That's what that mess of doors and hatches is for - it allows extracting the carts from their cells and in fact deposits them back onto their hatches, ready for operation at the flick of a lever. The nice thing about this design is that every tile of path goes straight through minecart-occupied ramps, there's no way to sidestep them.

There's another way of crushing things with minecarts: by dropping from above. Due to a rather weird bug, minecarts deliver collision damage through solid floors to creatures directly below. Out of curiosity, we tried this out against forgotten beasts, as well:

Exhibit four: minecart percussion corridor



A row of rollers pushing west, a tile of floor and a pit. Looks quite unassuming. Carts touch the rollers and get pushed west. Carts coming from floor do not enter downward ramps at all, they always jump. Carts jump past the pit, smack into the wall and fall down.



Into a simple double-ramp pit. After hitting the floor, the carts climb out east, towards the roller that throws them back in.

And on the level below that, through unbroken floor:



Those were six forgotten beasts, of various materials up to gemstone. Ten copper minecarts regularly punching from above >> forgotten beaasts.

I've tried the design against HFS, and it works quite well. Very beefy types can take quite a lot of punishment, but if you manage to keep them under the carts for long enough, they should succumb eventually. Haven't tried it against goblins, feels like overkill. Percussive minecarts can be had without power, too.

Something i haven't built in Galleywheels, but which also works remarkably well:

Exhibit 5: powered minecart grinder



The six roller pairs in the centre-south are the grinder. Each roller pair tosses a heavy, massively loaded cart back and forth when powered. Nothing gets through. This simple setup has taken out 444 units (mostly hostile) so far. It's backed up with traps and coupled with bridges to offer an alternative path and/or block path through a busy grinder - to keep traders alive. It's built in a glacier with practically no planning, thus the spaghetti pathing.


The main downside of automated defences is that they're largely static. The best magmacannon does nothing for you when the goblins aren't in the target zone. Waiting for the enemy to enter your prepared crusher/spike corridor/trap field can become quite boring. Fortunately, most creatures with legal path _will_ move at some point. And if they just won't, you can always flood the area with magma.



4
DF Dwarf Mode Discussion / Programmable Dwarven Computer. With Minecarts.
« on: January 19, 2015, 05:39:44 pm »


Links for further documentation:
Data Sheet and code reference

Control Logic

Program Listings

Usage advice for the savefile

Map

Savefile (0.34.11)

Excessively large write-up on much of the theory and praxis behind the thing

I'd messed around with minecart logic for quite a while and when i worked out ways to make an adressable memory cell and mass data storage with them, i decided to try building a computer. In the early conceptual stages i decided i was not going to untangle program and data coming from a shared bus and completely separated program and data storage. Since my mass storage concept looked like a good model for expanded program storage, the instruction length worked off the three bits encoded per cart in the mass storage. Thus, the computer uses six-bit instructions, a three-bit operator and a three-bit operand. It operates on ten-bit data: since program and data storage are separate, there's no need whatsoever to use the same or even related register sizes.

In spite of the tiny instruction set, the computer can access output (the line above is the result of a "print to screen" program) and do basic mathematical operations, albeit impressively slowly: addition is trivial, since it's one of the actual instructions, but the computer can also subtract (by constructing the binary complement first), multiply, divide, calculate a Fibonacci sequence (limited by the ten bits, of course) or...

calculate square roots:



The bottom line contains the actual number, the top line the square root. (sqrt of 840 is 28).

Spoiler: program (click to show/hide)

The program was started on 24 Moonstone 268 and finished 12 Malachite 269 - six months and 17 days, 185 days total. Barring accounting errors, those were 567 program steps, at a rate just over three operations per day, 392 steps per operation, 35,47 microurist clock rate by dwarven time, ~ 50 millihertz realtime.

A map has been uploaded: http://mkv25.net/dfma/map-12378-faintedposts

Bits and pieces

User interface



The place to interact with the machine. From here, you can enter program code, set the data registers, set the status bits, connect/cut main power, reset the computer, directly load the first program module from the ROM into active program storage, keep track of the main registers' contents and of the four status bits, shut down the main registers...

and of course start the computer.

It's riddled with more or less helpful notes; i wouldn't find my own way around it otherwise.

Memory cells

I use three different types of read-/writeable memory cells. I could have done with only two types, but kept the powered-cell register in the end, as an hommage to the pioneers of minecart computing. While it takes a lot of mechanisms and is power-dependent, it's fast, reliable and probably quite intuitive for people more into pure mechanical logic.

1. Linear read/write latch



Data register A, containing 0000 011 100 (28). These are ten memory cells, built horizontally, with "double-action" read, write-adressable.

Spoiler (click to show/hide)

Most memory cells i built here used this design.

2. Settable flipflop with optional carry generation



Three cells of the first counting register (register D).

Interlinks between individual cells allow the register to count up or down and cells can easily be written to. Reading its state is more complicated, it has to be done through a separate evaluation circuit.

I'm afraid the construction is a bit too complicated to convey it here. The core is a three-ramp pit with a single hatch cover over the "corner" tile:

Spoiler (click to show/hide)

3. Powered latch



Six bits of memory using Tinypirate's variant of the powered minecart memory cell (first published in Bloodbeard's minecart computation thread).

Spoiler (click to show/hide)

The ten-bit register draws 265 power before input has established, not at all trivial when the entire computer draws 1380 in standby and rarely over 1650 in operation.

Signal bundling

Every main register bank has ten enabling doors and twenty read hatches. There are several operations which write to or read from a register. To avoid having to link all those buildings up to each function, i collected them to a bank of "control" circuits. This way, "write to register A" can be done by establishing a single link to that control circuit. As a simple case of expedience, i also collected the "write to program memory" commands like this: while i could have gotten away with a single "clear all program memory" function, that would have meant linking 48 doors and hatch covers to a single plate. That could easily have taken over half a year to do. In the interest of my own sanity, i collected the functions through eight "clear" and eight "write" controllers.

The obvious downside to such indirect operation is that it introduces reaction delay: a signal sent directly to the targetted building switches the building instantly, a signal sent via control circuit only arrives once the control circuit has responded. It will also only turn off after the control circuit's plate has recovered.

Spoiler: why not keep it simple (click to show/hide)

The remote circuit i settled for introduces a delay, but that delay is absolutely constant and signal length does not expand.



Write control.

All writing to active memory, clearing the buffer or program memory and reading from the buffer and registers A-C is done through such indirect devices.

Program instructions have their "read" commands triggered directly: each only gets activated in one case (when the instruction is needed for execution), affording no benefit from collected operation, _and_ since each possible operation has to pass this step, unnecessary delays here hurt the overall performance of the computer.

Spoiler (click to show/hide)

Mass Storage

By far most of the program code in this computer is stored in a type of ROM: 128 words of code in the bank, while only eight at a time are actually loaded. New code can be loaded into active memory (overwriting the previous contents) by the "load Module" instruction, and an additional status bit can switch between two banks of eight modules each. The actual program store is spacious but fairly unassuming (spoilered for size):

Spoiler (click to show/hide)

It's still fairly compact considering that it can store 768 bits on 75x36x2 tiles. just over 7 tiles per bit. Even more impressively, it does this with less than 500 mechanisms (including the entire adressing and output management). The secret is that information in the mass storage is encoded in minecarts of specified weights that are simply held in readiness in small ramped pits until their data is requested. Then they get released by opening an "output" bridge, weighed by four pressure plates which directly send set signals to the pre-cleared program latches and cycled around and back into their pit through an "input" bridge that's held open until all carts are safely returned; the output bridge closes again ~ 100 steps after it opened, quite a long time before carts have finished their round.

A pair of holding pits looks like this:
Code: [Select]
#####    #####    .B.B.
#═╚═#    #▲▲▲#    ═B.B═
#═╔═#    #▲▲▲#    ═B.B═
#####    #####    .I.O.
z-1, track  z-1     z+0

B - bridge
I - incoming
O - outgoing

enough to hold two minecarts, worth six bits or one program word. The impulse ramps in the pits linked to the walls prevent carts from bouncing back out of the pit after entering (from the west) - they can only leave the pit when the eastern "output" bridge opens.

Minecarts of seven weights (and no minecart as "zero" datum) are used to encode three bits of information per cart; sixteen carts (potentially fewer depending on presence of "000" code segments or unused words) make up a module of eight words, sixteen modules can be stored.

The principle of this mass storage is remarkably simple. It allowed me to build a computer with an extremely small active program memory without crippling computational capacity: longer programs are simply spread over multiple modules and loaded in succession.

Higher information density per cart is possible, and a denser packing of the module, too, but either would increase complication:

Spoiler (click to show/hide)

For added convenience, the module loaded in the first position can be transferred to the program memory by operating a dedicated lever in the control centre. The two-wide bridges over the return tracks can be raised to stop currently circling minecarts - this way, a program module can be unloaded.

"Programming" the ROM is a pretty slow and inelegant process: a cart must be deposited on a pressure plate operating the input bridges of the desired module and the correct-material minecarts assigned to sixteen routes (consisting of a single stop on the western end of the long straight path, with a "push east immediately" order). Entering one module of program code in this way takes two to three weeks.

Mechanical logic devices

1. Adder (not the animal)



The main tool for calculations, this machine adds two ten-bit numbers together. The correct sum rollers are instantly connected to power the moment the inputs are fully established. Reading the result and transferring it to the target register is done by roller-directed minecarts; since i insisted on the compactest possible layout for the adder itself (two lines per bit), logistics are a bit tricky.

The read-out procedure must be started with a notable delay, because inputs come from linear latches and have a "startup" latency of up to 35 steps.

Spoiler (click to show/hide)

2. The comparator



Compares two inputs, passes power (switching the path of a "measuring" minecart on the NE loop) when the tested-for condition is true.

Spoiler (click to show/hide)

5
DF Wiki Discussion / Minecart in fluid
« on: December 08, 2014, 08:24:27 pm »
In spite of poor measurement precision, the test results are quite convincing:

the table on the wiki http://dwarffortresswiki.org/index.php/DF2014:Minecart#Numbers_behind_the_scene
appears to be incomplete:

I ran a cart through a seven-tile water trough, at different depths. At depths 1-6, speed didn't change much: 42 tiles in 28 steps at 1-2/7 vs. 41 tiles in 28 steps at 5-6/7; since the cart spent five steps under water, this more or less agrees with the reported friction of 100 per water depth above 1.
However, while moving through 7/7 water, speed went down radically: the cart spent seven steps in the trough, two on the ascending ramp (costing it another ~5000 speed) and took 60 steps to move 43 tiles, i.e. ~72.000 arbitrary speed units. If water imposes per-turn friction, that implies 7/7 water has a friction not of 600, but of ~10.000 (subtiles/step²), as much as a high-friction track stop.
I tried it both with closed ceiling and open space directly above the water and the results are the same, the higher friction is an effect of the "full" water square.

As another outcome, i'm now reasonably sure that minecarts take on water (and probably magma) when moving at <10.000 speed while submerged in sufficiently deep liquid (7, maybe also 6). Naturally, hitting such a low speed is easier when moving through a "full" tile, thanks to the enhanced friction. Tests: highest-speed roller cart spends two steps in 7/7 water, emerges at 30.000 speed, takes on no water. High-speed roller cart spends eight steps in originally 7/7 water, takes on water after three steps (just under 40.000 - 3x10.000 puts it below 10k), emerges at about 8.000 speed. Loading of water and emergent speed were the same for a wooden and a nickel cart, so the slow-down is not an effect of the weight gain but only of "high-water" friction.

Unless someone can come up with better numbers/explanations, i'll edit these numbers (10k friction from highest water, 10k maximum speed for loading water; absent better data, i'll note that maximum magma empirically has even higher friction than highest water) into the wiki in the next days.

6
DF Dwarf Mode Discussion / Has climbing killed goblin logic?
« on: November 17, 2014, 06:15:23 pm »
I can't say really, because i haven't got my fingers on a captive goblin in the recent versions, but experiments with redirecting dwarfs through creature logic circuits were a complete failure: letting a dwarf walk towards a target and re-directing them via opened hatch to block their path and an opened door to offer an alternative:

Code: [Select]
     #####+....#
Start....^#####.target
     #####¢....#

pressure plate is linked both to the door and hatch (hatch over a pit), which in .34.11 makes a one-way path: dwarf calculates path across the hatch, but stepping onto the plate opens the hatch and breaks path. Since the door is opened at the same time, the dwarf simply walks through the door (usually without missing a beat) and can return across the hatch, temporarily blocking the path behind them.

In .40.16, the dwarf will step on the plate, then climb into the open space over the open hatch, decide they can't continue because of dangerous terrain, cancels the job (if a job led them here), and consults the job roster for another occupation. They'll also usually drop their job item onto the pressure plate. I haven't found a way to prevent this behaviour - they'll climb onto a pit surrounded by nothing but open space and level floor; perhaps they'd been hanging onto the ceiling? Anyway, if goblins behave anything like that, we'll regretfully have to bury goblin logic. A shame, it was a pretty neat concept. The worse news is that it may require longer, deeper, multi-hatch pits in "goblin grinder" and similar path-interdiction traps.

7
DF Wiki Discussion / Fluid logic, some improved gate designs
« on: November 15, 2014, 08:09:50 pm »
Since i've fiddled with fluid logic under both magma and water, i went and updated/revised the relevant part in http://dwarffortresswiki.org/index.php/DF2014:Fluid_logic

Research report:
http://www.bay12forums.com/smf/index.php?topic=15096.msg5808780#msg5808780

I built and tested all designs i've changed on the wiki. I think doing away with the drains and reducing the space consumption warrants an update. I also took the freedom to rename it away from CMOS - while the doctrine is a complementary logic, it very definitely isn't MOS.

Looking at the pumping, flow and latency issues, i can understand why all seriously advanced dwarfputing was done in mechanics ;)

8
When building minecart tracks for distributing goods, one might sometimes want to route several lines across a common rail track. The problem then is separating the carts again so they go to their designated targets. There are of course several options, e.g. enabling the needed switches directly before giving the depart order, or using carts of measurably different weights, but since i found that minecarts follow exact build order rules to devolve their movements, i was sure carts' ages could be used as switch argument.

It wasn't easy, but i succeeded: one cart of four can be sent over a track into the switching array, and it'll be sent to the correct one of four destination bays, all through the magic of synchronised collisions.

Spoiler: large tangle of track (click to show/hide)

How does it actually work?
First of all, we need a proper collision: two carts must try to move in a way that conflicts with the other's movement, _in the same game step_. In each such collision, the older cart will take its move first. If two carts are immediately adjacent and basically try to move into each other's location, this means that the older cart will push the younger cart. The enter movement pulse of the older cart will pass to the younger. The younger cart moves away from the collision, the older cart comes to rest in the location it reached before the collision.

   
Paths only to the left, relevant buildings for the collision to the right.

The "traffic" cart that's to be switched enters from the right. It's coming in very quickly in the given system, somewhere around 80.000 speed, gets stopped and turned around by a highest-speed roller, setting speed in the switch itself to 50.000. When it passes over the pressure plate next to the roller, the plate activates the (also highest-speed) roller to the left, where the resident switch-"operator" cart sits and opens the door right to the south of it. This accelerates the operator cart to highest-roller speed and lets it out onto the collision track, facing the traffic cart.

The collision is fully synchronous and thus the older cart will come to rest in the middle of the collision track, while the younger cart moves off. In the switches i built, the traffic cart has reached its destination when it stops, if it's "too young" yet, it gets pushed off to the east, around the corner and to the next switch cell. It gets accelerated quite a lot on those impulse ramps, because that helps with ensuring a regular speed from the next roller.

Obviously, the resting cart also needs to be moved out of the way; it wouldn't be much of an automatic switch if every switching operation would require a dwarven vehicle hauling job for cleanup. How to do this? Why, with two more rollers, of course:

In the middle of the collision track, over the two possible stop locations, there are two single-tile rollers, the one to the left pushes the operator cart west, the one to the right pushes the traffic cart to its destination path south. The cart that gets sent out from the collision will always move over a pressure plate actually switching these rollers on. They're off otherwise (they must be off so the carts can actually cross them to collide). The plate crossed by the operator cart _also_ toggles the gear connecting its "home" roller: it gets engaged by the traffic cart and would stay on for 100 steps otherwise, sending the operator cart around repeatedly. One hundred steps later, when the traffic cart's plate resets, the roller turns on again, but at the same time the door closes, so the cart can't move anyway.

For the scheme to work with four routes/carts, three cells are needed and the seven carts must be built in the order
T1
O1
T2
O2
T3
O3
T4

Cart weights should not affect the ability of the switches to tell carts apart, but the output speeds of the collision can vary a lot when different-weight carts collide. To avoid misdirected traffic and derailings, the operator carts should be much heavier than the traffic carts (more than twice as heavy), which means pushed operator carts will move extremely slowly, if at all. I built it all with absolutely same-weight carts (all made from bayberry wood) which completely removed that concern, but that's obviously not an option for material transport routes.

I had to put three medium-friction track stops into the third switch cell and needed to build a corner into the second cell's destination route (seen in the pictures) because for some unfathomable reason the N->S roller gave the (presumably) resting cart a minimally diagonal push (but only in this cell, not in the others). This was likely all caused by letting carts run into working rollers full-throttle, resulting in weird distance offsets.

Actually getting the construction right with such a "just passing through" cart is quite tricky, because carts still calculate distances normally when moving over rollers; a wrong setup can give you impractically slow carts (much slower than the roller set speed) or errors caused by incompatible distance off-sets on the collision rail, where one cart invariably ends up a full step ahead of the other, so the collision's no longer synchronous. For an easier approach, the traffic cart should be fully stopped before being sent onto the collision rail, e.g. by temporarily switching off the incoming roller and letting the cart run into a wall behind it. That fully zeroes speed and apparently normalises position to the middle of the tile.

9
Oh, i know. Dwarfs are moody drunks, elves are stupid hippies and Friendship is Magma. Why bother experimenting with stuff trying to find how it works when you can murder a dozen dwarfs, set fire to their remains and get a sound round of applause for your ‼SCIENCE‼ ?

Still, i think i found out some stuff that's worth sharing. So let me tell you about trees!

No?

Come on, trees are awesome!

...

Alright, then i'll tell you about minecarts.

Contents:

This post: Lesson One: Track on flat floor, Lesson Two: Ramps, basics

Lesson Three: rollers and guided carts
Lesson Four: flight


Lesson Five: diagonal movement and how to fix it
Lesson Six: False ramps


Lesson Seven: Pathing across levels
Lesson Eight: Meet the checkpoint bug


Lesson Nine: Practical applications of the checkpoint bug
Lesson Ten: Understanding corner ramps


The wiki article contains a lot of varied information, but i've delved quite a bit into minecart pathing; i.e. where a minecart goes when you let it run free, how its paths change and so on. There's almost no in-depth information on all this stuff on the wiki and it seems to me that much of it isn't well understood.

I encourage all readers to replicate my designs and experiments and offer corrections or alternative interpretations. In order to properly trace what's going on, you will need to look at events closely and that means (unless you have an infallible hack script to do it for you) you'll need to pause the game, advance by single steps and count the steps exactly. You can't just eyeball the speed as "pretty fast" or "sort of sluggish", you'll have to e.g. count out a hundred steps and look how far a cart travels in that time, so you can definitely tell whether a cart moves at 45000 or 55000 speed.

Let's start simple.

Lesson One: Track on flat floor

In short, the only type of track that matters to a free-running cart are corners. All other types are irrelevant.

A sweeping statement, sure, but i found it to be perfectly true. The basic rule is that a minecart will move in a straight line. The only exception is when it encounters a track corner (the two-connection type, not T-junctions) that's connected to the direction the cart is coming from. Let's take an example:

Code: [Select]
a═══════╗   b═════╝
Cart gets pushed east from a/b, moves east until the corner and turns south/north there.


Code: [Select]
a║╚╔╣╩╦╠╗    b╬╥╨╞╡╝
Cart gets pushed and behaves exactly the same as above.

The cart incidentally also behaves like that when the route before the corner is entirely non-tracked floor, it'll path just the same, it will only slow down more thanks to higher friction.

Why is this so? As far as i can tell, the game doesn't calculate any sort of "heading" for the cart, it just keeps track of the velocity, probably split between x- and y- axis. When the cart moves over flat floor, all that'll happen on "direction-neutral" track is deceleration. When the cart is re-pathed by a legal corner, the whole input speed is taken and turned into speed in the exit direction of the corner.

"Straight" tracks have no pathing power over minecarts, they don't keep them "on track", because carts don't consider themselves "on track" in the first place. They're in contact with the floor and react to corners/constructions, or they're in flight and don't. That's it.


Lesson Two: Ramps, basics

Of course, everyone who works with carts for a while will probably get to love ramps. They allow carts to climb levels, they can provide speed, they even allow perpetual motion.

First of all, what makes a ramp tick?

A ramp is only fully traversible for carts and can only provide acceleration if it's properly connected by track. There are two arguments that get checked, and they concern track connections and nothing else. It doesn't matter where the cart comes from, whether it changes level or not, it's all about how the ramp is built.

* Requirement one: the ramp must have track connection to wall. One, two or three connections are all acceptable.

* Requirement two: the ramp must have exactly one track connection to a non-wall tile. This can be an adjacent ramp on the same level, flat floor or a hole (e.g. containing a down ramp).

Examples of functional track ramps

Code: [Select]
#    #    #    #     #     #
║    ║    ║    ╚+   #╩+   #╬#
+    ▲    ▼                +
All shown track engraved on up ramp.
▲ - up ramp
▼ - down ramp (i.e. hole containing a ramp)
+ - flat floor

Examples of non-functional track ramps

Code: [Select]
###   ###   ##
+═+   +╩+   #╝

First example: no connection to wall
second: more than one connection to floor
third: no connection to floor

When a ramp is properly connected, it provides acceleration towards its "down" direction; ~5000 speed units for every step a cart moves across it. Ten steps of acceleration give as much speed as a highest-speed roller, but you'll need multiple ramps for that.

The important part is that the game only checks if the ramp is properly connected, it doesn't check where the cart's coming from. This is the foundation of the fabled impulse ramp - a cart entering this ramp

Code: [Select]
###
+╚+

from the west will be accelerated towards the east, the same as a cart going down a level down such a ramp:

Code: [Select]
#═+
(cart's coming from track or a ramp on the level above). Impulse ramps thus grant speed without needing to sacrifice height, no more. They do not provide more or a different acceleration, just the exact same amount (which is quite a lot considering it means perpetual motion at practically any speed up to ~250.000 that you desire).

If a cart moves onto a ramp _from_ the ramp's down direction, it'll be accelerated in the direction it was coming from, i.e. it decelerates (at the normal ramp rate). Excepting a rather powerful bug that'll come up later, this deceleration will stop carts that are moving at the speed of a medium-speed roller or less before they reach a ramp's top, whereupon they'll roll back down from the place they've reached. The resulting speed when leaving the ramp again will be less than the speed the cart entered with, a cart bouncing between two ramps separated by one tile of level floor
Code: [Select]
#####       #####       #####
#▲═▲#       #═══#       #╚═╝#
ramps     track variants
will after about a dozen bounces stop on the flat middle tile. There's no observable difference between the two ramp layouts.


I built a fifteen-level straight ramp slope to measure the speeds different numbers of ramps will give to a cart. While the speeds found were just as expected and only of minor practical use (as reference to "generate" carts of specific speeds), the experiment provided a few valuable pointers, stuff that has been worked out by others before but doesn't seem to be widely known:

- a dropped cart (i always dropped it off a hatch) will land in the middle of the tile below and only roll down _half_ the ramp it lands on.
- the speed rises with the number of turns the cart spends on the ramps (just under 5000 speed for every turn, ~130 000 for a cart sent down a fifteen-level ramp), but one turn is subtracted from the count; i.e. the cart is charged ~5000 speed for leaving the ramps in the end.
- the "length" of a ramp is bigger than that of a flat tile. Since i only had full steps to calculate with, the numbers aren't super-precise, but it appears to be sqrt 2  times the length of a flat tile (the "lost" acceleration step mentioned above actually is needed for the length calculation to best fit the results).



Enough for now, more to follow.

10
DF Dwarf Mode Discussion / Need for speed (dwarven computing)
« on: July 17, 2014, 01:41:23 am »
NEW CONTENT on Page Two - reworked design, now actually executes a recognisable program!
http://www.bay12forums.com/smf/index.php?topic=140773.msg5496324#msg5496324

Spoiler (click to show/hide)



Spoiler: And the actual memory (click to show/hide)

Features:
six instructions:

write B XOR C to D (copper cart)
write A NXOR D to B (silver cart)
write garbled A NXOR B to C (wooden cart)
write garbled 3-input C XOR D to A (iron cart)
halt (heaviest cart, using platinum)
jump from "jump location" if associated register >=4, in all other cases nop (no cart)

four data registers, four bit each

clock rate: 105 steps (+-5)

construction expenditure - a bit over a fort year, about eight hours actual time, ~1050 mechanisms

Potential for more serious applications - with _somewhat_ reasonable instructions, actual computations might be possible, but the design isn't intended for large instruction sets, you basically have to hardwire every single instruction. Eight to ten plate-distinguishable minecart weights can commonly be procured, so there's already some potential in the unaltered premise. My deliberately dumb machine can already branch with condition and manipulate data (in dedicated registers).  The length of the "program" is not inherently limited and neither are the number of adressable data registers or their size. A fully pressurised water source is recommended.

11
DF Wiki Discussion / Restricted equipment in fatally hot locales
« on: July 04, 2014, 06:49:41 am »
Just noticed in a super-scorching embark:

In very hot biomes, dwarfs will not wear the full set of clothing on embark. The cutoffs are probably linked to specific temperatures, since more clothes seem to be missing as embark temperature rises.

In a scorching but not immediately murderous biome, dwarfs wore no cloaks, hoods or mittens - i.e. the "cover" clothing parts.
In biomes hot enough to be immediately life-threatening, the embark party will only wear a cap and shoes, i.e. no trousers and no upper body covering, meaning they'd be in serious danger of a tantrum meltdown even if you got them to survive the first four months. This may well be the absolute minimum clothing.

Even in an unplayably hot biome (hot enough to damage organic materials, preventing them from moving or acting altogether), the dwarfs will still spawn wearing a cap and shoes.

The heat limits only seem to apply to starting clothes - dwarfs in a "no hoods, no cloaks, no mittens" biome will still acquire and wear those items if provided later, they just don't bring them on embark (and probably migration). The same restrictions appear to hold for merchants - human caravan in the depot, and none wear cloaks, hoods or mittens.

Would this fit into the embark article somewhere?

12
DF Dwarf Mode Discussion / Yet Another Adding Machine
« on: May 14, 2014, 08:36:54 pm »
Yep, i did it again. Invented yet another sub-discipline of minecart logic and successfully applied it. The machine is not fully debugged, but got the right result in the test run (and the repeat).

I added 206+230 (1100 1110 + 1110 0110), and got the correct 436 (1 1011 0100).

I made a video of the repeat run: http://mkv25.net/dfma/movie-2661-signallesseight-bitadder

What's so peculiar and new about it? Well, the only moving parts in this adder are the minecarts. Construction took four in-game months, requiring a lot of digging and engraving, as well as the building of one bit of floor, seven track stops, 32 ramps inside the adders and about 40 more to speed up the read-out of the two topmost bits. 24 minecart routes needed laying out and supplying with carts.

And of course, the chief metric of complicated machinery:  Mechanism count: zero. The output consequently only consists of minecarts being placed in the output array or not.

Operation speed depends on the inputs of an adder - the slowest propagation of operation i had was 129 steps, the fastest 56 (yes, shorter than the reset time of a pressure plate). There was also a 45-step propagation in there, but that was actually too fast and will need fixing (didn't cause a false result in this case, though). The last output takes 129 steps from being triggered until the cart reaches its output position. The whole calculation from dwarven push to complete result took 903 steps.

The A- and B- input carts automatically return to their starting positions, only the activated sum carts leave their circuits, to actually provide an output. To change the calculation input, carts must be assigned (and removed) via the route management menu. Obviously, this is ludicrously slow.

The whole "calculation" consists of nothing but minecart collisions, using carts of different weights and with different speeds to stand in for the possible input combinations. Due to conservation-of-momentum calculations, the pushed carts in those collisions gain different speeds depending on inputs, and those speeds are separated into four different outputs by the design of the adder cells. Carts used are adamantine, willow and oak (indistinguishable by pressure plate); to push, either an adamantine (zero) or willow cart (one) is used, the pushed cart is either willow (one again) or oak (zero).

I think i'll have to explain this stuff some more at a later date. For now, some pictures:



Spoiler: result display (click to show/hide)

13
DF Dwarf Mode Discussion / Don't stop me now (supersonic cart)
« on: April 02, 2014, 10:19:12 am »
I talked about this in the "What's going on in your fort?" thread; the gist is that the 270000 is _not_ the fastest a minecart can go. It's "only" the fastest sustainable speed and the fastest speed reachable by acceleration.

_Some_ minecart collisions conserve momentum in such a way that momentum transferred from a heavier to a lighter cart can result in an increase of speed. Contrary to the real world, this is not the normal behaviour - banging a fast minecart into a standing cart will never result in a speed increase (this feature can even be used for speed regulation). Speed increases by minecart collision seem to require

- a frontal collision, where both momenta need to be in a certain range of each other (the less energetic cart still has to have about 1/3 of the more powerful cart's momentum i think)
- a lighter cart that weighs at least half as much as the cart pushing it (at the moment of collision, cargo weight is factored in).

Of course, the one thing i was curious about was if this'd allow me to exceed the claimed 270.000 speed limit. It does. As a matter of fact, even carts accelerated to above-terminal speeds will observe these rules, allowing them to pass the pulse on to lighter and lighter carts, resulting in very very silly speeds.

Since my two-tier collision system ended up working so well, i expanded it to three tiers:



And this is how it operates:
http://mkv25.net/dfma/movie-2652-supersoniccartfinalcut

The actual shot takes place at :55, you might want to fast-forward to it. The stuff before shows the operation.
You can see that the cart travels 170 tiles in the first 10 steps after the shot, so starting speed should be close to 17,5 tiles per step. (Final version, using a bloodthorn cart with three buckets for the initial impulse, transferring via oak and willow to adamantine.)

The snapshot was taken post-launch, all "left behind" carts can be seen, standing in their after-collision locations. The adamantine cart is goofing around at idiotic speeds a few screens to the west.

The main impulse comes from a bloodthorn minecart, loaded with two palm buckets, for a total weight of 54kg.
This cart smacks into a palm minecart (weight 27kg), boosting it to double the speed the bloodthorn cart had. The buckets will fly harmlessly out and can be collected and re-stashed. The palm cart collides with a willow cart (15kg), boosting it to 9/5 of the palm cart's, i.e. 18/5 of the bloodthorn cart's speed. The willow cart finally collides with an adamantine cart (8kg) and boosts it to 15/8 of its own, i.e. 27/4 the speed of the bloodthorn cart. The arithmetic is easy enough, but due to the rules laid out above, each collision must happen between carts within 1/2 weight of each other and similar speed. In the last collision, the adamantine minecart must be going at ~3 times terminal velocity, i.e. at a speed only reachable by two consecutive collisions. (I might be wrong and such collisions would work with less opposing momentum; i haven't tried this, and it could make multi-tier colliders much easier).

That's why i needed eight accelerator coils. In the southwestern pair, the bloodthorn and a palm minecart are accelerated before the doors are open and they're let out to collide. The accelerated palm minecart goes east into the north-south stretch. In the northwestern coil pair, a palm and a willow minecart are accelerated and collided. The willow cart goes into the north-south collision track and gets pushed by the aforementioned palm minecart. The willow cart now moves off, first north and then around the corner to the east. There, it collides with and pushes the adamantine minecart, which was accelerated and brought to sufficient pre-collision speed by two tiered collisions in the eastern half of the accelerator. The adamantine minecart zooms out straight east, where the now nonfunctional track loop can be seen. All collisions take place on consecutive steps:

0 - carts leave their ramp loops
1 - carts move into pre-collision positions
2 - all tier one collisions take place, pushed carts are all accelerated on this turn due to build order and move the five steps to the next pre-collision location
3 - all tier two collisions take place, the adamantine cart moves into its third-tier collision place, the willow cart (younger) tries to move into the place now occupied by the adamantine cart and stops. Momentum is transferred to the adamantine cart
4 - the adamantine cart acts on the momentum it received and moves off east, at a leisurely ~16,5 tiles per step.

I had first used the forty-tile track loop to try and measure minecart speed, but decided otherwise. Instead, i ordered a track dug and carved all around the embark area (a standard 4x4, 192x192 tiles of which the absolute border is not diggable, 756 tiles total track length). I put in a fake T link on every tenth tile for easier counting.

In this constellation, the adamantine minecart reaches a speed well in excess of 16 tiles per step initially. It slows down rapidly, however:
at above-terminal speeds, carts (maybe only on floor, but flight is hard to test at such speeds) are subject to immense friction. I kept track of tiles and steps, and the speed appears to go down by a full tile per step every ten turns: in the first run, with a slightly lighter bloodthorn cart, the adamantine cart moved 158 tiles in the first ten steps, 149 in the next ten, then 138, then 128, then 118 etc.

So my best approximation is that carts at beyond-terminal velocity experience a deceleration of 10000 per step. Other sources of friction (corners and plain track) _probably_ are factored in as well, but their effects are not easily measurable.

In the optimised run, the cart moved 162 tiles in the first ten steps and went a grand total of 1181 tiles in the first 100 steps. Taking into account that over that time, movement speed should have fallen by 1 000 000 due to the special friction, i arrive at an initial speed of 1 681 000, 6,225 times terminal velocity.

And how should we convert such speeds into real-world numbers? Well, taking ordinary fort-mode numbers would give hilariously low speeds for absolutely everything - a step is 1/1200 of a day in fortress mode, 72 seconds, and a tile is modelled as being three metres (i think) across. By this token, a living creature smashing into a wall at the breakneck speed of six metres in 72 seconds, 300 metres per hour, would blow apart from the collision. I think we need some better numbers: wikipedia cites terminal velocity for a falling human as 54m/s, while in DF, it's 2,7 tiles per step. I think it's justified to take 20m/s as reference frame for speed calculations (and only speed calculations!). Now, we got an initial speed of 16,81 tiles per step. Converting this, we find an initial speed of 336,2 m/s. Quite a lot, in fact, that number reminds me of something...

Ohoho:
http://en.wikipedia.org/wiki/Speed_of_sound#Practical_formula_for_dry_air
331,3 + 0,606 for every degree C above zero. Hmm, "underground" temperature is 15 Fahrenheit (PS above freezing, durrr stupid Fahrenheit scale with its weird null point), so that gives us 336,4 m/s. Soooo close. Assuming we lost speed through going around corners (seven total), that'd be another 7000 speed, i.e. 0,07 tiles per step ~ 1,4 m/s for a sum of 337,6. Supersonic minecart achieved. My work here is done.

Practical uses: none. You get a super-fast minecart, but that speed only lasts about 120 steps before it's eroded down to the intolerably sluggish terminal velocity. Every item (and creature, although i'm definitely not gonna try) in the carts will be flushed on the very first collision. You cannot shoot supersonic bullets like this.

Other things to possibly try: expand to the fourth tier just for the hell of it; test the flight capabilities of supercharged carts[1]; test "opposing momentum" rules in these collisions - if you don't need to build a full n-1-tier collider for every cart to _accept_ the full momentum, constructions wouldn't need to get quite so ludicrous if you went and modded material densities to allow a factor-100 speed crazifier.

[1] i'm damn sure the height limit is either "however many z-levels you have" or "tangens of ramp-launched angle of ascent *768" if you mod in z-levels like crazy. 768 is the maximum embark length. I reached 47 z with a simple one-tier collision boost and only didn't go higher because that was the embark border; it should have gone to about 55, i think. The challenge isn't getting the cart fast enough, it's building a launch with enough airspace. And no, you can't send a goblin into space, because the goblin will leave the cart in the first collision.

EDIT: switched from palm to oak for first transmitter, allowing an increase of the bloodthorn cart's weight from 54 to 56kg (just added another palm bucket): Distance travelled in 100 steps - 1244 tiles, over 17 tiles per step initially, definitely supersonic under the conversion used.
Two more tiers of collisions are imaginable - featherwood for an even lighter final cart, aluminium as primary pusher. To allow proper momentum transmission, the aluminium cart would need to be crashed into a pre-loaded bloodthorn cart, because it's more than twice as heavy as an empty bloodthorn cart. That'd reduce the effective push weight of the aluminium cart to 100kg; vs. a 4kg featherwood cart, this should allow a speed of 25x initial speed: theoretically up to 67,5 tiles per step (1350m/s).

For comparison, rollers are hampered by much lower starting speed, but they can still launch a metal cart 26 zlevels up without much effort, which calculates to around about terminal velocity:



In operation: http://mkv25.net/dfma/movie-2651-poweredflight

Trying it with metal carts this time, the chain is platinum,weighted (two schist, one limestone, Sa. 1707) - platinum, empty - lead - zinc. Weight factor just under six, the actual achieved speed was probably not over 280k, which was instantly dragged down to normal terminal by friction. Apex height 26 z, which is the norm for terminal-velocity flights. Well, terminal velocity without using ramps for acceleration, just 25 power. The zinc cart must be "pre-heated" with a loaded lead cart, or it won't go fast enough to catch the next train. The difference between empty lead and empty zinc is less than 60%. A minor benefit is that you don't need to reload carts after each shot, because all loaded-cart collisions happen on the first tier, at ordinary roller speed, thus no cart drops its stuff.

This setup, however, is of no practical use. You can reach the same speed with a simple impulse-ramp loop, and there's no weight limit on the carts you can accelerate with them.

EDIT: Postscriptum concerning the beyond-terminal-speed special friction.
I see no good way of testing this rigorously, but i found strong hints that this special friction applies whenever a cart moves at excessive speeds, both on the ground and when in flight. A single-collision propelled cart went at ~5 tiles/step before going over a ramp. As per usual, the ramp converted the "on floor" speed into diagonal speed with a horizontal component of a bit over three tiles/step and a vertical component of presumably just over 2 t/st.

The cart travelled ten tiles horizontally in the first three steps, but only 29 in the first full ten, 26 in the second ten, 28 in the third ten steps. Evidently, there are some strange carryover/rounding effects probably caused by the overall diagonal movement, but the basic restriction grinding down speeds to terminal velocity appears to apply in flight as well. It _also_ seems that the "speed limit" applies per movement axis, not to overall movement.

These are of course very poorly founded assumptions, since i had all of 30 steps of free flight to collect data from. Unfortunately, i'd need to accelerate the cart more for a better starting speed to base observations on, but that'd cut down the observable time so heavily the data'd be even less useful.

14
DF Wiki Discussion / Colliding minecarts
« on: March 28, 2014, 11:57:00 am »
I've messed around with bashing minecarts together a bit, and the rules of such collisions are pretty straightforward, although the consequences can get strange.

1. if a cart attempts to move into a tile currently occupied by another cart, it transfers its entire movement pulse to that cart and comes to a stop. If it was moving faster than derail speed, it will also let go of its cargo.
2. the speed at which the pushed cart will move is
incoming speed * incoming cart's weight/pushed cart's weight
capped at incoming speed. Apart from the cap, that's plain old conservation of momentum, i think.

But
2a. any potential speed of the pushed cart in the same direction is lost without a trace: a brass cart going east at maximum roller speed (50k) was chased by a high-speed (~120k) wooden cart, also going east. When the wooden cart caught up with the metal cart and pushed it, the wooden cart stopped and the brass cart slowed down to about 7k.

3. this speed transfer/speed erasure only applies to movement axes in which the incoming cart is actually moving at nonzero speed: if a cart moving S->N hits a cart going W->E, the eastward-heading cart will keep its eastward movement component and will gain an additional amount of northward speed, resulting in a north-east heading.

4. if two carts attempt to move into the same tile on the same turn, build order of the carts decides which one enters the tile first. I think it's last-built cart moves first, as with other build order checks, but haven't tested this recently. As a consequence, if two carts approach each other from opposite directions, trying to enter the collision tile on the same step, the "younger" cart will move off in the older cart's movement direction, with that cart's momentum, while the older cart simply stops. A precisely calibrated circuit doing this could sort minecarts by build order.

5. the speed cap allows regulating speed/momentum - letting the incoming cart smack into an aluminium cart, which then pushes a silver cart, which pushes the actual outgoing cart, will automatically cut momentum to ~1/4, before taking incoming/outgoing cart weights into account.

I've no idea where to put this. It's a part of minecart physics, but strikes me as a complete niche feature which most players will never really bother with.

EDIT: o wow, that's a whole subset of complete wtf stuff going on there.
I slapped together an ultra-simple test rig for build-order-driven minecart separation, with two minimally different architectures:
Code: [Select]

╚═C═╝   
Model A (conflicting entrance)

╚═cc═╝
Model B (conflicting exit)

In the first case, both carts try to _enter_ the same, currently empty square. In Model B, they reach immediately adjacent squares without colliding, the collision occurs when the carts try to _leave_ their squares and move into the one still occupied by the other cart. The collision takes place quasi-invisibly, during the build-order-determined resolution of moves of all buildings/creatures/items.

Under Model A the younger cart stops and the older cart moves off - the older cart moves first, enters the collision point first and thus gets pushed when the younger cart's turn in the resolution cycle comes up.

Under Model B, following the same logic, the older cart stops and the younger cart moves off. I.e. the older cart is the first to try and move, encounters the younger cart and pushes it, transferring its entire momentum to it (while the younger cart's momentum disappears).

In each case, the cart which comes to a stop does so on the tile it occupied _before_ the collision occurred, i.e. just one tile off the "C" point in Model A and on its own "c" spot in Model B.

So, first of all - it's the _older_ cart which moves first. Both designs accurately separate carts based on their build order, as long as the carts really come in during the same turn. Switching the directions from which carts come in doesn't change the results. The carts should preferably all be constructed before you install and link the hatch covers, just to make sure you don't add another degree of build order into the equations.

And because we were due another case of pure unadulterated wtf, these kinds of collisions _can_ transfer the unmodified, uncapped impulse in some cases. As far as i could determine, there are two conditions:

1. both carts must be moving before the collision; moving carts crashing into stationary carts cannot result in more than input speed. I had observed the latter in previous applications, so was rather surprised to see an exception to the "no faster than input" rule all of a sudden.
2. the relative weight difference between carts must fall within some limit, the pushing cart may have to be less than twice as heavy as the pushed cart. An iron cart will not cause acceleration when pushing an aluminium cart (weight factor larger than two and smaller than three), but a willow cart _will_ accelerate an adamantine cart (weight factor just smaller than two). This can result in above-derail speeds. Gotta see if i can pull this off with rollers, as a bonus "you totally can get derail speed with rollers" trick.

15
This didn't actually happen, but i built a "wireless" communication system in a fort. It sends messages between two partial forts which have no walking connection and thus also no shared mechanism links.

Information is sent via minecart, obviously. The exact information is transmitted by the minecarts' weights and decoded via pressure plates tuned to respond to the specific carts. As mentioned elsewhere, there are eleven distinguishable minecart weights. One cart is required for the "done" signal, so that leaves us with ten bits of space per message sent. Each individual bit in the message is represented by the presence or absence of the minecart in question, so sending the finisher cart alone actually sends 0000 0000 00. Sending carts one, two, five, seven and nine (and the finisher) sends 1100 1010 10.

Of course, to make the operation reasonable, a fair bit of auxiliary machinery was required. I wanted the message entered in one go and sent as a "package" instead of issuing each bit individually and wait for it to be sent before sending the next. This required a "dispatcher" to turn the lever-pulls at the main controls into a properly spaced sequence of launch signals.



Not very transparent, i'm afraid. Visibility doesn't exactly profit from it being built in the middle of a kimberlite vein and halfway over an older dysfunctional (too tightly spaced) design. Each lever opens one hatch cover (or not, if it is "off"). The dispatcher cart checks each ramp/hatch combination and if the hatch is closed, it bounces back out and is sent to the next without sending a launch signal. If the hatch is open, the cart passes through, activates the pressure plate sending the launch, bounces against a wall, back into the ramp-pit and out and to the next pit. This provides enough distance between the actual signalling carts so that they can eventually file back into their proper positions.

The signal carts sit each on their own individual hatch, which gets opened by the launch signal from the dispatcher. There's a bit of spacing provided because the carts that get started first in the sequence have the shortest distance to the main launch rail:



Quite simple, just a bunch of (SE) impulse ramps. The cart enters on the westernmost ramp, which is EW to guarantee a uniform starting speed. The ² things at the eastern end, where a proper ramp launches carts into the air, are the remains of a cat that got curious at the wrong time. Poor thing completely disintegrated.

The carts are sent off at somewhere in excess of two tiles per step, travel along a ballistic arch with an apex at z+17 (i have a picture of a cart in flight, but well, it's just a screenfull of empty space with a lone minecart) and lands about 90 tiles east of the ramp, here:



If you squint really hard, you can see the moat surrounding this sub-fort. Dwarfs cannot cross.
All pressure plates on the southern "incoming" path are weight-sensitive, ranging from 1-800kg for the first to 50-100 for the last. Each plate activates the door two tiles east of it, letting the cart pass, but if the cart is not the right weight, the cart follows the corner, touches the plate on the northward path, takes the next corner sending it west and eventually gets launched back out at the western end, two tiles northeast of the start of the incoming rail. This arrengement is why carts are sent from heaviest to lightest, with the bloodthorn cart as finisher - they can come in less than 100 steps apart, since each lighter cart is supposed to pass all doors passable by heavier carts anyway and thus, no false bits can be set.

In the picture, one cart is in the loop (the nickel one, judging by the plate it just went over) and the plate activated by an earlier cart (presumably lead) is still active - those carts were sent significantly less than 100 steps apart, and the launch for one cart between them was checked but wasn't required by the main controls.

After jumping back, the carts are pulled up two z-levels and sorted through this array of even more hatch-pits governed by weight-sensitive pressure plates:



Once again, the weight-ordering is used to ease the sorting process. Carts enter from the right and the heaviest carts leave on the left, so the plates/hatches are ordered by ascending weight. This was the part that needed the re-build of the dispatcher. I had an earlier design with closer-spaced launches, but that led to carts colliding here.

The plate activations at the reading end of the minecart jumps are first fed into a bunch of set/reset latches



and when the finisher (bloodthorn) cart touches its pressure plate, the main decoder/processor is activated:



Bottom left: a simple delayer - hatch cover/ramp loop holding a cart as long as the hatches are open, sending it over a pressure plate and back to the starting location after 100 steps are up. _This_ signal sends an open to all four floor grates to the middle-north, each holding back a minecart in a ramp-pit. These carts leave their pits after the grates open 100 steps later and pass over the track/bridges directly south of the grates. Two latches govern the positions of these bridges and which of the four carts gets to enter the main processing loop depends on the bridges' positions: there's a currently-retracted bridge immediately south of the grates. Currently, the second cart from the left gets to leave.

The operation cart then goes through eight latch-governed gates, sending signals to the main memory depending on cart weight and hatch positions. After finishing the cycle, the cart goes up to the above level, goes over another pair of bridges working like those below, sending the cart back to its origin pit and in the process sends an open signal to the bridge in the latch array, re-setting the latches.

One of eight cells of the main memory can be seen in the northeast. They're comically large, but can add, subtract, toggle or get set to a specific value.

The four minecarts in the operation loop are of four different weights (of course) and each hatch-gate has three pressure plates. Two are in the branch travelled when the hatch is open -
first plate responds to weights from 200-500, sends an "add" to its memory cell
second plate responds to weights from 400-max, sends a "subtract" to its memory cell

the other is in the branch travelled when the hatch is closed
responds to weights from 1-200, sends a "set to zero" to its memory cell.

Each of those main gates has an added hatch-pit cycle behind it. The hatch in it is triggered by the first and second pressure plates and if open, holds the cart back for 100 steps before it travels to the next gate. That's because carries can be generated in the main memory when adding or subtracting, the delay is supposed to prevent carries from failing to register.

The carts used are from wood (<50), copper (~350), silver (just over 400) and gold (770ish). So the operations are
copper - add
gold - subtract
silver - toggle status of every cell which has been selected, add without carry.

The wooden cart is first sent over a pressure plate which both sends a "set to one" to all memory cells _and_ holds the cart back for a hundred steps before it goes into the operation loop. Thus,
wood - set memory to transmitted bit chain. Sending the blood thorn cart alone sets the memory to zero.

Communication with this machine is one-way, to allow responses, a similarly large contraption would be required going the other way. One byte of information and a two-bit "opcode" take about 300 steps to get through the "dispatcher", each cart takes another ~200 steps to deliver its message, main operation starts another 200 steps after the bloodthorn minecart has come through and takes from 500 to 1500 steps depending on how many bits are set. About two dwarf-days to transmit and rudimentarily process one byte of information, ~3 to 5 mBit/s. It's gonna take a while before dwarfs start sending ballistic weight-encoded porn.

Pages: [1] 2 3