Claude's Corner: Art Works

The dream-rider Spirit Walk

(A woman's voice from off-screen, firm yet gentle.)

Aether: the celestial ocean. These are the voyages of the dream-rider Spirit Walk. Its forever mission: to befriend more cool people and have a blast; to poke at corners no-one noticed before. ...Isn't that right, kitty?

(loud purring)

Preview of a 3D model depicting a futuristic submarine with bulbous shapes and many sharp fins. It's yellow.

Welcome aboard! The Spirit Walk is a dream-rider, a vessel made for the literal space ocean from a steampunk / dieselpunk setting called The Dream. Neither airship nor submarine, it has a little bit of both.

Length:
35 meters
Beam:
10 meters (with diving planes folded)
Displacement:
~400 tons (submerged)
Decks:
3
Complement:
3-7
Capacity:
?
Notes:
4 message torpedoes (on hardpoints)

OpenSCAD source code is included below (version 3.1 as of June 2025):

module Hull() {
	scale ([1, 7, 1]) sphere (d = 5, $fn = 36);
	translate([0, -10, 0.6])
		cylinder(h = 0.6, d = 5, center = true, $fn = 24);
	translate([0, -10, -0.6])
		cylinder(h = 0.6, d = 5, center = true, $fn = 24);
}

color ("Khaki") Hull();

module Viewport() {
	rotate ([0, 90, 0]) {
		color ("Goldenrod") difference () {
			cylinder (h = 0.10, d = 0.55,
				center = true, $fn = 8);
			cylinder (h = 0.15, d = 0.45,
				center = true, $fn = 12);
		}
		color ("Turquoise")
			scale ([1, 1, 0.2])
				sphere (d = 0.5, $fn = 12);
	}
}

translate ([0, 5.5, 0]) {
	// Crew quarters
	translate ([-1.5, 0, 0]) {
		color ("Khaki")
			scale ([1, 5, 1])
				sphere (d = 3, $fn = 18);
		translate ([-1.5, 0, 0]) Viewport();
		translate ([-1.40, 3, 0]) Viewport();
		translate ([-1.40, -3, 0]) Viewport();
	}
	translate ([1.5, 0, 0]) {
		color ("Khaki")
			scale ([1, 5, 1])
				sphere (d = 3, $fn = 18);
		translate ([1.5, 0, 0]) Viewport();
		translate ([1.40, 3, 0]) Viewport();
		translate ([1.40, -3, 0]) Viewport();
	}
	// Brigde section
	translate ([0, 0, 1.5]) {
		scale ([1, 5, 1.5]) {
			color ("Khaki") difference () {
				sphere (d = 3, $fn = 18);
				translate ([0, 2, 0.7])
					cube ([0.5, 2, 0.6],
						center = true);
				rotate ([0, 0, 30])
					translate ([0, 2, 0.7])
						cube ([0.3, 2, 0.6],
							center = true);
				rotate ([0, 0, -30])
					translate ([0, 2, 0.7])
						cube ([0.3, 2, 0.6],
							center = true);
			}
			color("Turquoise")
				sphere (d = 2.9, $fn = 18);
			// Forward deck
			color("Khaki") scale([1, 1.1, 1])
				cylinder(h = 0.5, d1 = 3.5, d2 = 3,
					center = true, $fn = 18);		
			color("Khaki")
				translate([0, -0.25, 0.8])
					scale([0.9, 0.6, 1])
				cylinder(h = 0.1, d = 3,
					center = true, $fn = 18);		
		}
		translate([-1.2, 1.5, 1.1]) HatchDoor(-70);
		translate([1.2, 1.5, 1.1]) HatchDoor(70);
		translate([0, -6, 1.3])
			rotate([-60, 0, 0]) rotate([0, 0, 90])
				Viewport();
	}
}

module HatchDoor(rotx) {
	color("goldenrod") rotate([rotx, 0, 90]) intersection() {
		cube([0.7, 1.5, 0.1], center = true);
		cylinder(h = 0.15, d = 1.6, $fn = 8, center = true);
	}
}

module TailFin() {
	scale([0.1, 1, 1])
		cylinder (h = 3, r1 = 2, r2 = 1, $fn = 9);
}

color ("Khaki") translate ([0, -15, 0]) {
	for (i=[45:90:360]) rotate([0, i, 0]) TailFin();
}

module BigFin() {
	color ("Khaki") scale([0.2, 1, 1])
		cylinder (h = 3, r1 = 1.5, r2 = 0.5, $fn = 9);
}
module SmolFin() {
	color ("Khaki") scale([0.2, 1, 1])
		cylinder (h = 3, r1 = 1.5, r2 = 0.3, $fn = 9);
}

// Belly fins
translate ([0, 0, -0.8]) rotate([30, 180, 0]) SmolFin();
translate ([0, 5, -1]) rotate([30, 180, 0]) BigFin();
translate ([0, -5, -1]) rotate([30, 180, 0]) BigFin();
translate ([0, 10, -0.3]) rotate([30, 180, 0]) SmolFin();
translate ([0, 15, 0.5]) rotate([30, 180, 0]) SmolFin();

// Top fins
translate ([0, 2, 1.5]) rotate([30, 0, 0]) SmolFin();
translate ([0, 3.6, 1.8]) rotate([30, 0, 0]) SmolFin();
translate ([0, 5.3, 1.6]) rotate([30, 0, 0]) SmolFin();

// Diving planes
translate ([1.5, -2, 0]) rotate([0, 90, 0]) BigFin();
translate ([-1.5, -2, 0]) rotate([0, -90, 0]) BigFin();

module Thruster() {
	rotate([90, 0, 0]) {
		difference() { 
			hull() {
				cylinder(h = 5, d = 0.6, center = true, $fn = 12);
				cylinder(h = 3, d = 1, center = true, $fn = 12);
			}
			cylinder(h = 5, d = 0.5, center = true, $fn = 12);
		}
		scale([1, 1, 8]) sphere(d = 0.6, $fn = 12);
	}
}

color("Khaki") {
	translate ([2.5, -15, 0]) Thruster();
	translate ([-2.5, -15, 0]) Thruster();
	translate([0, -15, 0])
		rotate([0, 90, 0])
			scale([0.1, 1, 1])
				cylinder(h = 5, d = 3,
					center = true, $fn = 9);
}

// Crane craddle
translate([0, -2, 0]) {
	color("Khaki") {
		cylinder(h = 2.5, d = 1, $fn = 12);
		translate([0, -1, 1.25]) cube([1, 2, 2.5], center = true);
	}
	color("Goldenrod") {
		translate([0, 0, 2.5]) {
			scale([1, 1, 0.2]) {
				rotate([90, 0, 0])
					cylinder(h = 1.7, d=0.6, $fn = 16);
				sphere(d = 0.6, $fn = 16);
			}
		}
	}
}

// Cargo doors
translate([0, -4.5, 0]) {
	color("Khaki")
		cylinder(h = 2.5, d1 = 4, d2 = 3, $fn = 24);
	color("Goldenrod")
		translate([0, 0, 2.5])
			scale([1, 1, 0.1])
				sphere(d = 2, $fn = 24);
	color("Khaki")
		translate([0, -0.9, 0.1])
			cube([0.3, 0.4, 5], center = true);
}

module Torpedo() {
	// Body
	cylinder(h = 3, d = 0.5, center = true, $fn = 12);
	// Nose
	translate([0, 0, 1.5])
		scale([1, 1, 4])
			sphere(d = 0.5, $fn = 12);
	// Tail
	translate([0, 0, -2.5])
		cylinder(h = 2, d1 = 0.1, d2 = 0.5,
			$fn = 12, center = true);
	// Fins
	translate([0, 0, -3.25]) {
		for(i = [0:90:360]) {
			rotate([90, 0, i])
				scale([0.2, 1, 1])
					cylinder(h = 0.3, d1 = 0.5, d2 = 0.3,
						$fn = 12);
		}
	}
}

module TorpedoMount() {
	color("goldenrod") {
		translate([0, 1, 0]) cylinder(h = 0.6, d = 0.1);
		translate([0, -0.5, 0]) cylinder(h = 0.6, d = 0.1);
	}
	color("khaki") rotate([-90, 0, 0]) Torpedo();
}

rotate([0, -30, 0]) translate([0, -3, -3]) TorpedoMount();
rotate([0, -60, 0]) translate([0, -3, -3]) TorpedoMount();
rotate([0, 30, 0]) translate([0, -3, -3]) TorpedoMount();
rotate([0, 60, 0]) translate([0, -3, -3]) TorpedoMount();

This version is closer to the deck plan used in most stories, but still quite different.

An older version is up on Open Game Art.