「聖人含道映物,賢者澄懷味象。」 The sage embodies the Way and mirrors things; the wise clarify the mind and savor forms. — 宗炳《畫山水序》, Zong Bing, Preface on Landscape Painting (c. 400 CE)
A minimal digital clock floating over a living pointillist 3D terrain — a mountain rendered as breathing points of light. Ported faithfully from the hero animation on ingtian.github.io.
Manifold — the terrain is literally a 2-manifold surface; the name also nods to manifold optimization and to many-folded mountain ranges (山水).
Screen saver — the terrain with a floating clock
Live wallpaper — the same terrain, no clock, behind your desktop
Swappable surfaces — the field morphs between eight math functions
Eye-Dome Lighting makes the sparse dots read as a solid 3-D ridge; the palette clips cycle through a few of the eight palettes (each cross-fading like a theme switch), and the surface clips morph between the eight terrain functions (picked live from the options sheet / menu bar).
The terrain is a height field z = h(x, y) sampled on a 33×33 grid, projected
through a fixed yaw+tilt rotation and drawn as ~1000 elevation-colored dots. Each dot
is shaded by Eye-Dome Lighting — darkened and shrunk where its screen neighbors
sit nearer — so the sparse cloud reads as a solid mountain rather than a flat scatter.
The field breathes slowly, and glowing "walker" particles periodically trace
gradient-descent paths downhill and settle with a soft glow. The Classic palette's
colors (sky gradient, elevation ramp, walker glow) are the exact values from the site's
SkyWash.css and terrain.js; seven more bundled palettes re-skin both light and dark.
Switching theme or palette cross-fades smoothly (a slow dawn/dusk transition)
rather than snapping.
The surface itself is selectable, too: the default Classic field is the site's five Gaussian bumps, and a gallery of eight math surfaces swaps in others — the classic optimization landscapes Ackley, Himmelblau, Rosenbrock and Rastrigin, plus a Gaussian-windowed monkey-saddle rosette, damped radial ripples, and a hexagonal wave lattice. Each has a closed-form gradient, so the walkers keep descending the real surface, and each is fitted to the same elevation band as Classic so the camera, colors and lighting stay tuned. (The optimization functions are apt: the walkers are literally gradient descent, so each surface becomes a live picture of basins of attraction, ill-conditioned valleys, and local-vs-global capture.)
Requirements: macOS 14+ and the Xcode Command Line Tools (no full Xcode).
If you don't have them: xcode-select --install.
Because you build it locally, macOS doesn't quarantine it — there's no "unidentified developer" wall and no Apple Developer account needed.
There are two pieces and you can install either or both. The one-command
installer takes a screensaver (default), wallpaper, or all argument:
# Screen saver only (default):
curl -fsSL https://raw.githubusercontent.com/IngTian/manifold/main/scripts/install.sh | bash
# Live wallpaper only:
curl -fsSL https://raw.githubusercontent.com/IngTian/manifold/main/scripts/install.sh | bash -s -- wallpaper
# Both:
curl -fsSL https://raw.githubusercontent.com/IngTian/manifold/main/scripts/install.sh | bash -s -- all(The -s -- passes the argument through to the piped script.)
Or from a clone:
git clone https://github.com/IngTian/manifold.git
cd manifold
scripts/install.sh # screensaver (default)
scripts/install.sh wallpaper # live wallpaper
scripts/install.sh all # bothThe screen saver installs to ~/Library/Screen Savers/Manifold.saver; the
wallpaper installs to /Applications/Manifold Wallpaper.app and launches
immediately. See Configuring & using below to turn
them on and tune them.
If the screen saver doesn't show up in System Settings right away, force a re-scan:
killall WallpaperAgent legacyScreenSaver 2>/dev/null || true
scripts/build.sh # build/Manifold.saver (universal)
scripts/build.sh install # …and copy to ~/Library/Screen Savers
scripts/build-wallpaper.sh # build/Manifold Wallpaper.app (universal)
scripts/build-wallpaper.sh install # …and copy to /Applications + launchRe-run the same installer — it fetches the latest source, rebuilds, and overwrites the installed copy in place. Your settings are not touched (they live in preference stores, not in the app):
# Update whatever you have installed (pick the matching component):
curl -fsSL https://raw.githubusercontent.com/IngTian/manifold/main/scripts/install.sh | bash -s -- all- Screen saver: the installer nudges the settings UI to reload; if a preview
looks stale, close and reopen the Screen Saver pane (or
killall WallpaperAgent legacyScreenSaver). - Live wallpaper: the installer quits the running copy, replaces the app, and relaunches it automatically — no logout needed.
From a clone, git pull first, then re-run scripts/install.sh <component>.
The same terrain can also run as a live desktop wallpaper — the breathing
mountain behind your icons, with an animated light↔dark cross-fade. It's a tiny
background app (Manifold Wallpaper.app) that shares the exact renderer with the
screen saver. No clock by design — a calm backdrop rather than a second clock
competing with your menu bar.
Why a separate app? macOS exposes no public API for animated wallpapers, so — like every third-party live wallpaper (Plash, etc.) — it pins its own borderless window at the desktop level (above the static wallpaper, below your icons). Because it never touches the screensaver subsystem, it's unaffected by MDM screensaver policies. It's battery-aware: 30 fps normally, 15 fps on battery / Low Power Mode, and it fully pauses (≈0 % CPU) whenever the desktop is covered, the display sleeps, the screen is locked, or the real screensaver runs.
The two pieces are configured in two different places — the screen saver
through System Settings (macOS only knows about .saver bundles there), the
wallpaper through its own menu-bar icon (it's a standalone app). Both remember
their settings across restarts and updates.
-
Turn it on: System Settings → Screen Saver → scroll down to the "Other" group → pick Manifold. Set the idle timer under Lock Screen → "Start Screen Saver when inactive".
-
Configure it: click Options… on the Manifold tile. Settings persist via
ScreenSaverDefaultsand take effect immediately in the preview:- 24-hour time (default on) —
14:32vs2:32 pm - Show seconds (default on) — small superscript seconds that tick
- Show date (default on) — spaced-caps weekday + date under the time
- Show walker particles (default off) — the glowing downhill walkers
- Shape lighting (Eye-Dome) (default on) — shades each dot by how much its screen neighbors occlude it, so the sparse point cloud reads as a solid 3-D ridge instead of a flat scatter. Turn it off for the plain pointillist look.
- Theme — Auto (match system) / Light / Dark
- Palette — the color scheme. Eight bundled presets: Classic (the ported teal/earth look), Nordic Slate (cool blue-gray), Sumi-e Ink (monochrome graphite), Glacier (cold cyan ice), Heather & Slate (muted violet-gray), Graphite & Copper (graphite with one warm accent), Basalt & Ash (warm neutral gray), Bordeaux Night (deep oxblood). The theme (light/dark) still picks the variant within the chosen palette, and palette switches cross-fade.
- Surface — the terrain's math function. Eight bundled surfaces: Classic (the site's Gaussian bumps), Ackley, Himmelblau, Rosenbrock, Rastrigin (four optimization landscapes the walkers descend), a Monkey-Saddle Rosette, Still Water (ripples), and Hex Interference.
- Font — System (SF Pro) / Rounded / Serif (New York) / Monospace
- Zoom — how much of the terrain fills the screen (0.60–1.15×); lower shows more
of its footprint (wide), higher zooms in. Default
0.85. - Motion — breathing strength (0–2×): how much the terrain wobbles.
0is perfectly still,1.0the tuned default, higher is livelier. - Motto — a small italic signature line below the clock, right-aligned to
the date (default
Lorem Ipsum). Any text works, including pasted Unicode such as Greek letters (α, β, σ, …); leave empty to hide.
The clock sits on the horizontal golden section (≈61.8 % of width), balancing the terrain's ridge on the left.
- 24-hour time (default on) —
Once installed, the app runs in the background and shows a ⛰ icon in the menu
bar (top-right). Everything is configured from that menu — there's no System
Settings entry, because it's an app, not a .saver:
- Theme — Auto (match system) / Light / Dark (switches cross-fade smoothly)
- Palette — the same eight presets as the screen saver (Classic, Nordic Slate, Sumi-e Ink, Glacier, Heather & Slate, Graphite & Copper, Basalt & Ash, Bordeaux Night); switches cross-fade
- Surface — the same eight terrain functions as the screen saver (Classic, Ackley, Himmelblau, Rosenbrock, Rastrigin, Monkey-Saddle Rosette, Still Water, Hex Interference)
- Shape lighting — toggle Eye-Dome Lighting (default on), the depth-shading that makes the terrain read as a 3-D ridge
- Zoom — Wide / Default / Close / Closest — how much of the terrain is shown
- Motion — Still / Subtle / Default / Lively — the breathing strength
- Walker particles — toggle the glowing downhill walkers
- Pause on battery — fully stop animating on battery (default off; it already drops to 15 fps and pauses when hidden regardless)
- Show message — toggle the bottom-left signature line
- Set message… — edit that line's text (editing it turns it on). Default
Lorem Ipsum; paste any Unicode you like. It sits at the lower-left golden section and cross-fades with the theme. - Launch at login — start the wallpaper automatically at login
- Quit Manifold Wallpaper — stop it (removes the desktop window)
Launch at login uses
SMAppService, which wants a stably-located, signed app — that's why the installer puts it in/Applications. If the toggle ever fails on an ad-hoc build the app still runs; enable it manually in System Settings → General → Login Items.
The scene is a small amount of closed-form math, ported verbatim from
terrain.js into
TerrainRenderer.swift. Here's the whole thing.
Elevation field. The terrain is a sum of
Each bump
Surface gallery. h is one of eight selectable surfaces (Classic above, plus
Ackley, Himmelblau, Rosenbrock, Rastrigin, a Gaussian-windowed monkey saddle, damped
ripples, and a hexagonal wave field). Each non-classic surface
Gradient. Walkers flow downhill along
and symmetrically for
Breathing. Each frame the elevation is perturbed by a slow travelling wave in
time
Projection. Each point
With a scale factor depth, and colored by a normalized elevation
Walkers. The glowing particles are literally gradient descent: from a fixed
start
Everything in the scene is sized as a fraction of the view — no hardcoded pixels — so it scales to any resolution or Retina scale factor. Verified on 16:9, 21:9, 32:9 super-ultrawide, and portrait. On screens wider than ~21:9 the terrain grows toward the width (a uniform zoom, never a stretch) so it fills the display instead of leaving empty side margins.
Sources/
Shared/ The framework-free engine, compiled into BOTH products:
Palette.swift SkyWash gradient + elevation ramps + walker colors (light/dark)
+ palette blending for the theme cross-fade
+ PalettePreset color schemes (8 presets)
TerrainRenderer.swift Core Graphics port of terrain.js (field, projection, walkers)
+ TerrainFunction surface gallery (8, closed-form gradients)
+ the animated theme cross-fade + surface-morph state machines
TerrainConfig.swift the shared render knobs (single source of truth for key/default/clamp)
Saver/ Screen-saver-only shell:
Settings.swift ScreenSaverDefaults-backed options + FontDesign/ThemePreference
ManifoldView.swift ScreenSaverView principal class (draw, layout, config sheet)
ConfigSheet.swift Programmatic AppKit options sheet
WallpaperApp/ Live-wallpaper-only shell (reuses Shared/):
main.swift accessory-app entry point
AppDelegate.swift per-display windows, status-bar menu, theme, launch-at-login
WallpaperWindow.swift borderless NSWindow pinned at the desktop level
TerrainWallpaperView.swift layer-backed view, CADisplayLink frame pacing
PlaybackGovernor.swift particle/battery/occlusion/sleep/lock pause logic
WallpaperSettings.swift UserDefaults-backed options (own suite, no ScreenSaver dep)
Resources/
Info.plist NSPrincipalClass = ManifoldView (the .saver)
Wallpaper-Info.plist LSUIElement agent app (the wallpaper)
thumbnail.png/@2x System Settings preview image (a real rendered frame)
scripts/
build.sh swiftc → universal .saver bundle (+ optional install)
build-wallpaper.sh swiftc → universal "Manifold Wallpaper.app" (+ optional install)
install.sh one-command clone + build + install
(arg: screensaver | wallpaper | all; also the updater)
tools/
render.swift Headless verifier: renders both products to PNGs
(saver = loads the real .saver; wallpaper = shared renderer)
verify-math.swift Math regression tests: every surface's analytic gradient vs
finite differences, + classic-field fidelity (run in CI)
This is distributed as source you build locally, which is the friction-free
path for a free, open-source macOS screensaver: locally-built bundles aren't
quarantined by Gatekeeper, so no Apple Developer account, code-signing identity,
or notarization is required. Your friends just run scripts/install.sh.
If you fork it, update REPO_URL in scripts/install.sh
and the bundle id com.ingtian.manifold (in
Resources/Info.plist and
scripts/build.sh) to your own namespace.
If you ever want it distributed as a signed, download-and-double-click bundle
(so users don't build it themselves), that requires the paid Apple Developer
Program ($99/yr): sign with a Developer ID and notarize —
codesign --options runtime --sign "Developer ID Application: …" then
xcrun notarytool submit … --wait and xcrun stapler staple. Not needed for the
build-locally flow above.
tools/render.swift renders either product to PNGs. In
saver mode it loads the built .saver and drives it exactly as the screensaver
host does (init(frame:isPreview:) on NSPrincipalClass) — proving the real
shipping bundle loads and draws. In wallpaper mode it drives the shared
TerrainRenderer (the same engine the app uses) with the wallpaper's own settings,
since the wallpaper is a plain app, not a loadable bundle.
SDK="$(xcrun --show-sdk-path)"
swiftc -sdk "$SDK" -O -parse-as-library -module-name Render \
-framework AppKit -framework ScreenSaver \
Sources/Shared/*.swift \
Sources/WallpaperApp/WallpaperSettings.swift tools/render.swift \
-o build/render
mkdir -p build/frames
# Saver: pass the built bundle. THEME forces light/dark.
THEME=dark ./build/render saver build/Manifold.saver build/frames 1600 1000
THEME=light ./build/render saver build/Manifold.saver build/frames 1600 1000
# Wallpaper: reads WallpaperSettings; PALETTE=<int> LIGHTING=0|1 ZOOM=<n> override.
PALETTE=1 THEME=dark ./build/render wallpaper build/frames 1600 1000- Fidelity: grid density (1089 pts), projection matrix, color ramps, breathing,
and walker timing are copied verbatim from
terrain.jsso the aesthetic matches the site. The device-pixel-ratio (g) factor is omitted deliberately — Core Graphics applies the backing scale itself, so point-space drawing is equivalent. - The bundle is ad-hoc code-signed, which is exactly right for the build-locally flow. See Publishing / forking above for the notarized-distribution path.
MIT © Ing Tian (Zeying Tian). Terrain aesthetic after ingtian.github.io.





