<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Tachyon</title>
    <description>The latest articles on DEV Community by Tachyon (@pyxm1618).</description>
    <link>https://dev.to/pyxm1618</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4099685%2Fd2607eb7-3c0b-4cee-bb7a-39e97832b323.jpg</url>
      <title>DEV Community: Tachyon</title>
      <link>https://dev.to/pyxm1618</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pyxm1618"/>
    <language>en</language>
    <item>
      <title>What I Learned Building an Online I Ching Casting Tool</title>
      <dc:creator>Tachyon</dc:creator>
      <pubDate>Sat, 29 Aug 2026 08:19:50 +0000</pubDate>
      <link>https://dev.to/pyxm1618/what-i-learned-building-an-online-i-ching-casting-tool-48gp</link>
      <guid>https://dev.to/pyxm1618/what-i-learned-building-an-online-i-ching-casting-tool-48gp</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7e6uxx99zd6apt1wbd73.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7e6uxx99zd6apt1wbd73.png" alt=" " width="799" height="387"&gt;&lt;/a&gt;&lt;br&gt;
At first, building an online I Ching tool sounded like a fairly small web project.&lt;/p&gt;

&lt;p&gt;There are 64 hexagrams. A user performs a cast. The application identifies the result and displays an interpretation.&lt;/p&gt;

&lt;p&gt;But while building &lt;a href="https://www.quickiching.com/" rel="noopener noreferrer"&gt;Quick I Ching&lt;/a&gt;, I found that the difficult part was not displaying a hexagram.&lt;/p&gt;

&lt;p&gt;The difficult part was deciding which parts of a traditional casting process had to survive the move into software.&lt;/p&gt;

&lt;p&gt;That turned into a useful lesson in domain modeling, product design, and the risks of simplifying a system too aggressively.&lt;/p&gt;

&lt;h2&gt;
  
  
  The final hexagram is not enough
&lt;/h2&gt;

&lt;p&gt;One of the first architectural decisions was to avoid treating a reading as nothing more than a number between 1 and 64.&lt;/p&gt;

&lt;p&gt;A cast contains more information than that.&lt;/p&gt;

&lt;p&gt;For the traditional line-based methods, six lines are generated. Those lines determine the primary hexagram, but they can also contain changing lines.&lt;/p&gt;

&lt;p&gt;If changing lines are present, they transform and produce a relating hexagram.&lt;/p&gt;

&lt;p&gt;So the useful state of a reading includes more than:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“Hexagram 24”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also needs to preserve things such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the six original line values&lt;/li&gt;
&lt;li&gt;the primary hexagram&lt;/li&gt;
&lt;li&gt;which lines are changing&lt;/li&gt;
&lt;li&gt;the relating hexagram&lt;/li&gt;
&lt;li&gt;the casting method used&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That distinction became important very quickly.&lt;/p&gt;

&lt;p&gt;If I stored only the final hexagram number, I would have thrown away information that the interface later needed in order to explain the reading properly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Line order is a domain rule, not a UI detail
&lt;/h2&gt;

&lt;p&gt;An I Ching hexagram is built from the bottom upward.&lt;/p&gt;

&lt;p&gt;The first line cast is line 1 at the bottom. The sixth line is at the top.&lt;/p&gt;

&lt;p&gt;That sounds like a small implementation detail, but it is actually a domain rule.&lt;/p&gt;

&lt;p&gt;The application therefore keeps the six lines in bottom-up order rather than allowing the rendering layer to decide what the order “probably” means.&lt;/p&gt;

&lt;p&gt;This was a useful reminder that domain-specific software often breaks in very ordinary places.&lt;/p&gt;

&lt;p&gt;A developer can build something that looks visually correct while quietly reversing the meaning of the underlying data.&lt;/p&gt;

&lt;p&gt;When the domain has established rules, those rules should be represented explicitly rather than reconstructed later from UI assumptions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Changing lines need to remain first-class data
&lt;/h2&gt;

&lt;p&gt;Changing lines are another place where an implementation can become too lossy.&lt;/p&gt;

&lt;p&gt;A changing yin line becomes yang.&lt;/p&gt;

&lt;p&gt;A changing yang line becomes yin.&lt;/p&gt;

&lt;p&gt;The transformed lines create the relating hexagram.&lt;/p&gt;

&lt;p&gt;For the software, that means the important sequence is not simply:&lt;/p&gt;

&lt;p&gt;cast → hexagram&lt;/p&gt;

&lt;p&gt;It is closer to:&lt;/p&gt;

&lt;p&gt;cast → primary hexagram → identify changing lines → transform them → relating hexagram&lt;/p&gt;

&lt;p&gt;The application needs to preserve that relationship all the way through to the result page.&lt;/p&gt;

&lt;p&gt;This is why I did not want changing lines to become a small decorative annotation added after the hexagram had already been calculated.&lt;/p&gt;

&lt;p&gt;They are part of the result itself.&lt;/p&gt;

&lt;p&gt;For users who want the non-technical explanation, I also documented the concept separately in the guide to &lt;a href="https://www.quickiching.com/guides/changing-lines" rel="noopener noreferrer"&gt;changing lines&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Different casting methods should remain different
&lt;/h2&gt;

&lt;p&gt;Another design problem appeared when supporting more than one way to cast.&lt;/p&gt;

&lt;p&gt;Quick I Ching currently supports traditional methods including the Three-Coin Method, Yarrow Stalk Method, and Mei Hua Yi Shu, alongside a Manual Cast option in the product.&lt;/p&gt;

&lt;p&gt;From a UI perspective, it would be tempting to make them all variations of one generic “random hexagram” function.&lt;/p&gt;

&lt;p&gt;That would certainly make the application simpler.&lt;/p&gt;

&lt;p&gt;It would also be misleading.&lt;/p&gt;

&lt;p&gt;The methods do not represent the same process with different labels.&lt;/p&gt;

&lt;p&gt;So in the codebase, the casting domain separates the method-specific logic instead of pretending that every method is interchangeable.&lt;/p&gt;

&lt;p&gt;There are distinct areas for Three-Coin casting, Yarrow Stalk casting, and Mei Hua Yi Shu, while shared hexagram logic sits separately.&lt;/p&gt;

&lt;p&gt;That boundary matters because the application can change or test one casting method without redefining what a hexagram result means everywhere else.&lt;/p&gt;

&lt;p&gt;The user-facing explanation of one of these methods is available in the &lt;a href="https://www.quickiching.com/methods/three-coin" rel="noopener noreferrer"&gt;Three-Coin I Ching Method&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Normalize the result, not the tradition
&lt;/h2&gt;

&lt;p&gt;The useful architectural pattern turned out to be:&lt;/p&gt;

&lt;p&gt;different inputs → method-specific logic → common result model&lt;/p&gt;

&lt;p&gt;The methods can differ, while the rest of the application can still work with a stable representation of a completed cast.&lt;/p&gt;

&lt;p&gt;That shared result can describe:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;six lines in their correct order&lt;/li&gt;
&lt;li&gt;the primary hexagram&lt;/li&gt;
&lt;li&gt;moving-line positions&lt;/li&gt;
&lt;li&gt;the relating hexagram when one exists&lt;/li&gt;
&lt;li&gt;which casting method produced the result&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This creates a clean boundary between “how the cast is produced” and “what the rest of the application needs to know about the cast.”&lt;/p&gt;

&lt;p&gt;I think this is a useful pattern for many domain-heavy products.&lt;/p&gt;

&lt;p&gt;Normalization should happen after the important domain-specific behavior, not by erasing those differences at the beginning.&lt;/p&gt;

&lt;h2&gt;
  
  
  Versioning the algorithm was worth doing
&lt;/h2&gt;

&lt;p&gt;One detail I initially could have treated as unnecessary was algorithm versioning.&lt;/p&gt;

&lt;p&gt;The casting result does not only record which method produced it. The domain model also has room for the algorithm version and the classic hexagram mapping version.&lt;/p&gt;

&lt;p&gt;That may look excessive for a small tool, but there is a practical reason for it.&lt;/p&gt;

&lt;p&gt;If an implementation changes later, a historical result should not become impossible to explain.&lt;/p&gt;

&lt;p&gt;Being able to say “this result was produced by this method using this version of the algorithm” makes debugging and future migrations much safer.&lt;/p&gt;

&lt;p&gt;It also prevents a subtle class of bugs where the software changes but old saved results silently acquire new meaning.&lt;/p&gt;

&lt;p&gt;The lesson here was not “version everything.”&lt;/p&gt;

&lt;p&gt;It was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If an algorithm creates meaningful persisted output, knowing which algorithm created that output can be part of the data.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The interface should simplify work, not erase structure
&lt;/h2&gt;

&lt;p&gt;There is always pressure to make a web tool feel effortless.&lt;/p&gt;

&lt;p&gt;For an I Ching product, the most aggressive version of that idea would be:&lt;/p&gt;

&lt;p&gt;click once → receive an answer&lt;/p&gt;

&lt;p&gt;But that removes almost everything that distinguishes an actual cast from a generic random result.&lt;/p&gt;

&lt;p&gt;I wanted the interface to reduce mechanical work while still making the important structure visible.&lt;/p&gt;

&lt;p&gt;A user should still be able to understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;how the cast was produced&lt;/li&gt;
&lt;li&gt;what the six lines are&lt;/li&gt;
&lt;li&gt;which lines are changing&lt;/li&gt;
&lt;li&gt;which hexagram is primary&lt;/li&gt;
&lt;li&gt;whether a relating hexagram exists&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The computer can do the bookkeeping.&lt;/p&gt;

&lt;p&gt;It does not need to hide the system.&lt;/p&gt;

&lt;p&gt;That became one of the main product principles behind Quick I Ching:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Simplify the work, not the underlying model.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Domain modeling matters even in a small product
&lt;/h2&gt;

&lt;p&gt;Quick I Ching is not an enterprise-scale system.&lt;/p&gt;

&lt;p&gt;But building it reinforced something I usually associate with much larger software projects:&lt;/p&gt;

&lt;p&gt;good domain boundaries matter even when the product is small.&lt;/p&gt;

&lt;p&gt;If I had modeled a reading as only a hexagram number, almost every later feature involving changing lines, relating hexagrams, different methods, or reproducibility would have required reconstructing information that had already been discarded.&lt;/p&gt;

&lt;p&gt;Preserving the meaningful state made the rest of the product easier to reason about.&lt;/p&gt;

&lt;p&gt;It also made the implementation closer to the thing it was trying to represent.&lt;/p&gt;

&lt;p&gt;That is probably the main engineering lesson I took from building &lt;a href="https://www.quickiching.com/" rel="noopener noreferrer"&gt;Quick I Ching&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When digitizing a traditional system, simplify the interaction — not the rules that give the system its meaning.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>nextjs</category>
      <category>typescript</category>
      <category>product</category>
    </item>
  </channel>
</rss>
