開發歷程:把紫微斗數做成 100% 瀏覽器本地的排盤工具

這是 LocalPapa Notes 開發紀錄系列的第十三篇。命理服務系列正式開始。

如果 OKF 那篇是「讓 AI 讀懂網站的知識包」,這篇則完全相反方向——把一套高門檻的傳統命理術,翻譯成瀏覽器跑得動的演算法。

為什麼從紫微斗數開始?

LocalPapa 的立場很清楚:100% 瀏覽器本地、不上傳資料。命理服務本來就是高隱私敏感題材——你的生辰八字比手機號碼還私密。這讓「本地優先」不只是技術選擇,而是倫理預設。

紫微斗數(Zi Wei Dou Shu)是華人傳統命理術中最複雜的一套:十二宮、十四主星、四化、大限,每個環節都有細緻的演算規則。正因如此,它也是最值得花時間做對的一個——做好了,後面的命理服務都是在它的基礎上複用。

兩軌架構:靜態知識 + 動態計算

開發前最重要的決定:什麼屬於「知識」,什麼屬於「計算」?

  • 靜態知識層:十四主星的本質、十二宮的領域定義、四化的規則、五行局的格局——這些對所有人都相同,適合用 OKF 知識包的形式沉澱,AI agent 可以直接讀取。
  • 動態計算層:根據你的生辰(西元年月日時、性別)推出命宮、排十二宮、落主星——這個結果每人不同,屬於「計算」,在瀏覽器本地跑,結果不離開你的裝置。

這個切分讓 ziwei-engine.jsbuild_ziwei_okf.py 各司其職,不互相耦合。

算盤引擎裡的五個關鍵算法

ziwei-engine.js 是純計算模組,不碰 DOM,與 UI 完全解耦。裡面有五個核心算法:

1. 農曆轉換

採標準 1900–2100 的 lunarInfo 壓縮表(每年三個 32-bit 整數,編碼月份長短、是否有閏月、閏月在哪)。農曆轉換是後面所有計算的地基——年干支、月支、日干支都從這裡來。

2. 五虎遁年上起月(命宮天干)

命宮的地支由「生月+生時」推得;天干則靠「五虎遁年上起月」:依據年干(甲己年、乙庚年……五組)查起虎之干,再順數到命宮月支對應的天干。這個「天干」決定了後續命主/身主的五行,以及四化祿存的計算。

3. 納音五行局

「五行局」決定了大限起始歲數與紫微星的落宮演算法。它的來源是命宮干支的納音——六十甲子的每個干支對,都有對應的「納音五行」(金木水火土),五種各自對應一個「局數」(二、三、四、五、六)。

4. 古法起紫微

這是整個引擎最有趣的一段,也是最多說明文件說不清楚的部分。核心公式是:

N = 局數 × n - 餘數(調整至整除)→ n 就是紫微落在第 n 宮

更精確地說:給定五行局數 s 與農曆日 d,目標是找最小正整數 n 使得 s×n ≡ d (mod s);找到 n 後,再依「偶數日順行、奇數日逆行」決定紫微的實際宮位。這個「偶順奇逆」的傳統口訣,在網路上常被簡化或錯傳——實作時靠著翻出老版算法書核對。

5. 大限方向

大限(十年一大限)的排列方向是「陽男陰女順行,陰男陽女逆行」。初版寫反了(常見錯誤,許多線上工具也有這個問題)。靠著用已知命盤交叉驗證才發現——也因此,交叉驗證是命理引擎開發的必要步驟,不是選配。

怎麼確認排盤準確?

命理計算沒有 unit test 可以直接驗證「對不對」——除非你有已知正確的命盤可以比對。我們用了三組已知值:

  1. 1984-02-02 → 農曆甲子年正月初一(大年初一,無歧義)
  2. 2000-01-01 → 農曆己卯年十一月廿五
  3. 庚午年農曆 25 日,土五局 → 紫微在午宮(古算法書載明)

針對四化、祿存、天魁、天馬、命宮干,逐項對照多個版本的紫微書籍與可信的線上工具,確認吻合後才上線。大限方向的修正就是這個過程中抓到的。

CSS Grid 4×4 還原傳統盤面

十二宮的傳統排法是:

`` 巳 午 未 申 辰 酉 卯 戌 寅 丑 子 亥 ``

四邊各三宮,中央 2×2 空出來放命主資訊。用 CSS Grid 4×4,把十二宮的 grid-area 一一對應,中央四格合為一個 grid-area: center。星曜依主星(紫色)、吉星(藍色)、煞星(紅色)上色;生年四化以彩色徽章(祿橙、權綠、科藍、忌紅)標示在星名旁——讓一眼就能看出哪顆星在飛化。

build_ziwei_okf.py:知識與工具的橋

build_okf.py 一樣的哲學:不手刻 40 個 Markdown,讓 Python 結構化資料持有知識,由產生器同時輸出:

  • okf/ziwei/:40 個 OKF .md,涵蓋十四主星、十二宮、四化、五行局、概念頁——AI agent 可直接讀取這套命理知識
  • tools/ziwei-interpret.js(後來新增的解讀層):瀏覽器用的 window.ZiweiInterpret,免 fetch、可離線快取

build_okf.py 的根 index 和 llms.txt 新增了「Knowledge bases」區塊,讓 agent 從入口就能找到紫微知識庫。這個「知識入口」設計,是上一篇 OKF 那條線的延伸。

誠實標示:命理是詮釋,不是預測

每個命理服務頁都標了這行字:本服務提供傳統命理詮釋,僅供參考,不構成任何預測或建議。

並且我們在說明裡寫清楚幾個流派差異:閏月命宮的歸月爭議、早晚子時的算法分歧、庚干四化(太陽/武曲 vs 太陽/天同)在不同版本的差異。沒有哪個流派是「絕對正確」的——我們選了一種、標明了出處,讓使用者知道這件事。

學到的事

  • 「知識」和「計算」要分清楚再動手。 知識適合 OKF、靜態快取;計算適合本地引擎、不上傳。兩軌清楚,才能解耦維護。
  • 命理引擎一定要交叉驗證。 用已知命盤測,否則你不知道哪裡算錯了——大限方向那個坑就是這樣找到的。
  • 傳統口訣要回溯到源頭。 「偶順奇逆」在網路上的版本很多都不準確,翻老書才是最可靠的。
  • 排盤不等於解盤。 排出來只是擺好星,怎麼讀還需要「解讀層」。這個後來繼續往下做(組合式查表、三方四正)。
  • 一套驗證好的引擎,是後面所有命理服務的地基。 達摩一掌經、生肖合婚、塔羅、西洋星座……都在這個基礎上複用農曆表。

一以貫之的問題

前面的工具問的是「能不能在瀏覽器完成」。命理服務換了一個問法:能不能在瀏覽器完成,同時讓使用者不必信任任何伺服器?

你的生辰不應該飛到雲端換一個命盤——所有計算在你的裝置上完成,關掉網頁就消失。這是「本地優先」在命理題材上最有說服力的一次體現。

下一篇,我們會繼續命理系列——看達摩一掌經如何用「仿紫微」的三層架構,以最小新增實現一個新服務。想追蹤系列?把 LocalPapa Notes 加入書籤吧。

Dev Log: Building a 100% Browser-Local Zi Wei Dou Shu Chart Engine

This is the thirteenth post in the LocalPapa Notes dev-log series. The divination service arc begins here.

If the OKF post was about "giving AI a knowledge pack it can read," this one goes the opposite direction — translating a high-barrier traditional metaphysical system into algorithms a browser can run.

Why start with Zi Wei Dou Shu?

LocalPapa's position is clear: 100% browser-local, nothing uploaded. Divination is inherently high-privacy territory — your birth data is more sensitive than a phone number. That makes "local-first" not just a technical choice, but an ethical default.

Zi Wei Dou Shu is one of the most complex Chinese metaphysical systems: twelve palaces, fourteen major stars, four transformations, decade luck periods — each with intricate calculation rules. That complexity is precisely why it was worth getting right — done well, it becomes the foundation every other divination service builds on.

Two-track architecture: static knowledge + dynamic computation

The most important decision before writing any code: what counts as "knowledge," and what counts as "computation"?

  • Static knowledge layer: the nature of the fourteen major stars, the domain of the twelve palaces, the rules of the four transformations, the Five-Element Bureau patterns — these are the same for everyone. They belong in the OKF knowledge pack, where AI agents can read them directly.
  • Dynamic computation layer: given your birth data (date, time, sex), derive the Life Palace, place the twelve palaces, place the major stars — the result is different for every person. This belongs in the browser, running locally; the result never leaves your device.

This separation lets ziwei-engine.js and build_ziwei_okf.py each do their job without coupling.

Five key algorithms inside the chart engine

ziwei-engine.js is a pure computation module — no DOM, fully decoupled from the UI. It contains five core algorithms:

1. Solar-to-lunar conversion

Uses a standard 1900–2100 lunarInfo compressed table (three 32-bit integers per year, encoding month lengths, whether there's a leap month, and where). Lunar conversion is the foundation for everything — year stems and branches, month branch, day stems and branches all derive from it.

2. Five Tigers calculation for the Life Palace stem (命宮天干)

The Life Palace branch is derived from birth month and birth hour. The stem comes from the "Five Tigers" rule: depending on the year's heavenly stem (five groups: 甲己, 乙庚, ...), you find the starting stem, then count forward to the branch of the Life Palace month. This stem determines the Life Master's Five-Element affiliation and the Four Transformation calculations.

3. Nayin Five-Element Bureau

The "Five-Element Bureau" (五行局) determines both the starting age of decade luck periods and the algorithm for placing the Purple Star. It comes from the nayin of the Life Palace's stem-branch pair — every pair in the 60-cycle has a corresponding nayin element (metal, wood, water, fire, earth), each mapping to a bureau number (2, 3, 4, 5, or 6).

4. The ancient Purple Star placement algorithm

This is the most interesting part of the engine, and the part most often glossed over in documentation. The core formula is:

Find the smallest positive integer n such that bureau × n ≡ day (mod bureau) — that n is the palace index where the Purple Star lands. Then apply "even-numbered days go clockwise, odd-numbered days go counter-clockwise" to get the actual palace position.

The "even clockwise, odd counter-clockwise" (偶順奇逆) rule gets simplified or mis-stated in many online sources. We traced it back to classic algorithm texts to get it right.

5. Decade luck direction

Decade luck periods flow clockwise for yang-males and yin-females, counter-clockwise for yin-males and yang-females. The first version had this reversed — a common error that shows up in many online tools as well. We only caught it through cross-validation against known charts. Cross-validation is not optional for a divination engine.

How we verified accuracy

There's no unit test that can directly tell you if a chart is "correct" — you need known reference cases. We used three:

  1. 1984-02-02 → Lunar 甲子/Year 1 Month 1 Day 1 (Chinese New Year, unambiguous)
  2. 2000-01-01 → Lunar 己卯/Year 11 Month 25
  3. 庚午 Year, lunar day 25, Earth Five Bureau → Purple Star in 午 palace (stated in classic texts)

We checked four transformations, Lucky Star placement, Heavenly Benefactor, Heavenly Horse, and the Life Palace stem against multiple sources before going live. That process is what caught the decade-luck-direction bug.

CSS Grid 4×4 for the traditional palace layout

The traditional twelve-palace layout is:

`` 巳 午 未 申 辰 酉 卯 戌 寅 丑 子 亥 ``

Three palaces on each side, the central 2×2 left for the chart master's information panel. We used a CSS Grid 4×4, mapping each palace's grid-area to its position, merging the four center cells into grid-area: center. Stars are colour-coded by type: major stars (purple), auspicious stars (blue), inauspicious stars (red). Life-year four transformations appear as coloured badges beside star names (Prosperity orange, Authority green, Intellect blue, Obstruction red) — so the key stars are visible at a glance.

build_ziwei_okf.py: the bridge between knowledge and tool

Same philosophy as build_okf.py: never hand-craft 40 Markdowns. Python structured data holds the knowledge; the generator outputs both:

  • okf/ziwei/: 40 OKF .md files covering the fourteen major stars, twelve palaces, four transformations, Five-Element Bureau, and concept pages — AI agents can read this knowledge base directly
  • tools/ziwei-interpret.js (added later): the browser-side window.ZiweiInterpret, no fetch required, offline-cacheable via the Service Worker

The root build_okf.py index and llms.txt gained a "Knowledge bases" section pointing to the Zi Wei knowledge base — so an agent can navigate to the star/palace definitions from the entry point. This "knowledge entry point" design extends the OKF thread from the previous post.

Honest labelling: divination is interpretation, not prediction

Every divination service page carries this line: This service provides traditional metaphysical interpretations for reference only; it does not constitute any prediction or advice.

We also document the divergences between schools of thought: the disputed month assignment for leap-month birth dates, the split between early- and late-hour Zi calculation, the four-transformation table for 庚-stem (太陽/武曲 vs 太陽/天同 depending on the version). There is no single "correct" school — we chose one, documented the source, and let users know this is a real variance, not an error.

What we learned

  • Separate "knowledge" from "computation" before writing a line of code. Knowledge belongs in OKF, static-cacheable; computation belongs in a local engine that never uploads. Clear separation → clean maintenance.
  • A divination engine must be cross-validated. Use known reference charts — that's how we caught the decade-luck direction reversal. Without it, you don't know what you got wrong.
  • Traditional mnemonics need to be traced to source texts. Online versions of "偶順奇逆" vary and many are imprecise. Old algorithm books are the ground truth.
  • Laying out a chart is not the same as reading it. Placing stars is step one; interpretation is another layer (we added combinatorial lookup and Three Directions/Four Alignments later).
  • A well-validated engine is the foundation for every divination service after it. Yizhang, zodiac matching, tarot, Western astrology — all of them reuse the lunar calendar table from this engine.

The same question, applied to privacy

Earlier tools asked "can this be done in the browser." Divination services ask a sharper version: can this be done in the browser such that the user never has to trust any server?

Your birth data shouldn't fly to a cloud to come back as a chart — all computation happens on your device and disappears when you close the tab. This is local-first at its most compelling: the more sensitive the data, the more obvious the answer.

In the next dev log, we continue the divination arc — see how Yizhang (達摩一掌經) uses a "copy-of-Zi-Wei" three-layer architecture to ship a new service with minimal new code. Want to follow the series? Bookmark LocalPapa Notes.

探索 39+ 個隱私優先的瀏覽器工具
全程本地運算、檔案不上傳。
前往 LocalPapa →
Explore 39+ privacy-first browser tools
Everything runs locally — your files never leave your device.
Visit LocalPapa →

想看英文版?點右上角 EN 切換語言。

Prefer Chinese? Tap at the top-right to switch.