<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Game Guide Lab]]></title><description><![CDATA[Game Guide Lab]]></description><link>https://game-guide-lab.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Wed, 28 Oct 2026 04:43:02 GMT</lastBuildDate><atom:link href="https://game-guide-lab.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Modeling Regional Game Event Schedules Without False Precision]]></title><description><![CDATA[Model regional game schedules with explicit time zones, evidence labels, local conversion, calibration, and clear live-state limits.]]></description><link>https://game-guide-lab.hashnode.dev/modeling-regional-game-event-schedules-without-false-precision</link><guid isPermaLink="true">https://game-guide-lab.hashnode.dev/modeling-regional-game-event-schedules-without-false-precision</guid><category><![CDATA[Game Development]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[technical writing]]></category><dc:creator><![CDATA[bingkun zhao]]></dc:creator><pubDate>Mon, 26 Oct 2026 06:35:28 GMT</pubDate><content:encoded><![CDATA[<p>Event timers fail quietly when they treat a wall-clock label as complete data. A schedule such as “every three hours from 02:00” still needs a service time zone, a source, a verification date, and a clear boundary between an expected opening and a live server state.</p>
<h2>What should a regional timer store?</h2>
<p>Start with a reference record rather than a list of rendered strings:</p>
<pre><code class="language-yaml">service: taiwan
utc_offset: +08:00
first_start: "02:00"
interval_hours: 3
entry_window_minutes: 15
evidence: official-guide
checked_at: 2026-10-07
</code></pre>
<p>A different service can reuse the same structure while carrying a different evidence label. Community references and player-observed custom clocks should remain visible as such instead of inheriting an “official” label from another region.</p>
<h2>How should local-time conversion work?</h2>
<p>Build each start as an absolute instant in the service offset, then format that instant with the browser's local time zone. This avoids manually maintaining one table for every region and keeps daylight-saving changes in the platform's time-zone implementation.</p>
<p>The local weekday should be rendered with the local time. Near midnight, the server date and the player's date can differ even though they refer to the same instant.</p>
<pre><code class="language-ts">function buildStarts(firstStart: Date, intervalHours: number, count: number) {
  return Array.from({ length: count }, (_, index) =&gt;
    new Date(firstStart.getTime() + index * intervalHours * 3_600_000)
  );
}
</code></pre>
<p>The countdown and daily table should consume the same generated starts. If they use separate hard-coded values, an update can fix one display while leaving the other wrong.</p>
<h2>What can the countdown actually claim?</h2>
<p>A schedule-based countdown can identify the next expected reference start. It cannot observe whether a portal is present, full, closed early, or changed during maintenance. During a documented entry window, the interface may show estimated time remaining, but that estimate must stay distinct from a live status signal.</p>
<p>This distinction changes the error handling. When the game disagrees with the timer, the game wins. The website should send the reader to troubleshooting guidance rather than insisting that a mathematically correct schedule proves a portal is available.</p>
<h2>Why include a custom calibration mode?</h2>
<p>When a service has no verified public anchor, asking the player for one observed opening is more honest than copying another region's clock. A custom mode can combine that observation with a UTC offset and repeat interval, save the preference locally, and generate shareable planning information without requesting a game login.</p>
<p>I implemented these ideas in <a href="https://aion2rifttimer.wiki/">AION 2 Rift Atlas</a>. Its Taiwan preset cites an official-guide reference, Korea remains labeled as a community reference, and Global/custom planning starts from the user's observed clock. That evidence model is the part worth reusing: the countdown is useful because its uncertainty is visible.</p>
]]></content:encoded></item><item><title><![CDATA[Building a Reproducible LLM API Cost Calculator]]></title><description><![CDATA[Build an auditable LLM API cost calculator with normalized channels, explicit workloads, source dates, validation, and visible exclusions.]]></description><link>https://game-guide-lab.hashnode.dev/building-a-reproducible-llm-api-cost-calculator</link><guid isPermaLink="true">https://game-guide-lab.hashnode.dev/building-a-reproducible-llm-api-cost-calculator</guid><category><![CDATA[technical writing]]></category><category><![CDATA[Artificial Intelligence]]></category><category><![CDATA[api]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[bingkun zhao]]></dc:creator><pubDate>Sun, 25 Oct 2026 22:57:37 GMT</pubDate><content:encoded><![CDATA[<p>An LLM API cost calculator is only trustworthy when the inputs are reproducible. The multiplication is easy; the difficult work is keeping model names, channels, cache rules, source dates, and excluded fees aligned while providers change their pricing pages.</p>
<p>The implementation I prefer starts with normalized price records and builds every comparison from that shared dataset.</p>
<h2>Normalize rates by model, channel, and token type</h2>
<p>One model may have an official provider route and an OpenRouter route. Store them independently:</p>
<pre><code class="language-yaml">model_id: example-model
channel: official
input_per_million: 2.50
cached_input_per_million: 0.25
output_per_million: 15.00
context_window: 1000000
source_url: https://provider.example/pricing
verified_at: 2026-10-26
</code></pre>
<p>The router version can use the same model ID with a different channel and source. This prevents a lower router rate from being mislabeled as the provider’s direct price.</p>
<h2>Represent the workload explicitly</h2>
<p>A reusable cost function should take workload values rather than a pre-computed token total:</p>
<pre><code class="language-ts">type Workload = {
  inputTokens: number;
  outputTokens: number;
  cacheReadShare: number;
  requestsPerMonth: number;
};
</code></pre>
<p>Split input tokens into fresh and cached portions, price each with the stored channel rates, add output cost, and multiply by the number of requests. If the channel has no verified cache-read rate, use the full input rate and label the assumption.</p>
<p>Keeping the workload separate also makes comparison URLs shareable. The URL can carry model choices and workload numbers while the server-rendered page explains that stored prices should be checked against their source dates before budgeting.</p>
<h2>Validate records at build time</h2>
<p>A static build can reject the most dangerous data errors:</p>
<ul>
<li>negative prices or context windows</li>
<li>a confirmed rate without a source URL</li>
<li>a verification date missing from a displayed price</li>
<li>duplicate model-and-channel records</li>
<li>a cached-input rate greater than the fresh-input rate without an explicit note</li>
<li>an “official” record sourced only from a third-party listing</li>
</ul>
<p>These checks do not prove a price is current, but they make the update process reviewable and stop malformed values from reaching every generated page.</p>
<h2>Show exclusions beside the estimate</h2>
<p>Token rates do not cover every bill. Tool calls, image or audio units, long-context tiers, batch discounts, taxes, credit-purchase fees, and BYOK rules can require separate logic. When they are outside the calculator, the page should say so near the result.</p>
<p>I applied this pipeline to <a href="https://llmapiprices.com/">LLM API Prices</a>, which keeps official direct and OpenRouter prices separate, links the source for each stored rate, and estimates fresh input, cached input, output, and monthly workload costs.</p>
<p>The result is a calculator that can be updated without rewriting every comparison page. More importantly, a reader can trace a number back to its channel, source, verification date, and workload assumptions before using it in an architecture decision.</p>
]]></content:encoded></item><item><title><![CDATA[Building a Static Content Pipeline for Live Game Banners]]></title><description><![CDATA[A practical static-site pipeline for live game banners using canonical phase data, evidence states, focused pages, and freshness checks.]]></description><link>https://game-guide-lab.hashnode.dev/building-a-static-content-pipeline-for-live-game-banners</link><guid isPermaLink="true">https://game-guide-lab.hashnode.dev/building-a-static-content-pipeline-for-live-game-banners</guid><category><![CDATA[technical writing]]></category><category><![CDATA[Game Development]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[static site]]></category><dc:creator><![CDATA[bingkun zhao]]></dc:creator><pubDate>Sun, 25 Oct 2026 22:19:14 GMT</pubDate><content:encoded><![CDATA[<p>A static site can track live game banners without turning every update into a hand-edited rewrite. The practical requirement is a small content pipeline that treats dates, source confidence, and page routing as structured inputs.</p>
<p>Wuthering Waves is a useful example because one phase can affect several user questions at once: the current character lineup, the weapon focus, the countdown, the next-banner checkpoint, rerun planning, and pity decisions. If each page stores its own copy of the same facts, they will drift.</p>
<h2>Build around a canonical phase record</h2>
<p>Start with one record for the live phase:</p>
<pre><code class="language-yaml">version: "3.7"
phase: 2
starts_at: 2026-10-22
ends_at: 2026-11-11
featured_characters:
  - Suoming
  - Lucilla
  - Lynae
next_status: pending_official_reveal
snapshot_date: 2026-10-23
</code></pre>
<p>The homepage, current-banner page, countdown, and schedule should all read from this record. A build-time validation step can reject impossible windows, missing snapshot dates, or a <code>confirmed</code> next phase with no supporting source.</p>
<h2>Generate focused pages instead of one large feed</h2>
<p>The same dataset can support several search intents without duplicating prose:</p>
<ol>
<li><strong>Current banner</strong> answers what is live and when it ends.</li>
<li><strong>Next banner</strong> states what is confirmed and what remains pending.</li>
<li><strong>Countdown</strong> turns the end timestamp into a deadline view.</li>
<li><strong>History</strong> retains completed phases for rerun research.</li>
<li><strong>Pity and pull advice</strong> explain planning rules without rewriting the lineup.</li>
</ol>
<p>Each page still needs original explanatory text, but shared facts come from the canonical phase record. The result is easier to audit because a date change propagates through the correct routes in one build.</p>
<h2>Keep watchlist signals out of confirmed fields</h2>
<p>Live-service content attracts leaks, old screenshots, and vague version mentions. Store these as separate signals:</p>
<pre><code class="language-json">{
  "kind": "version-mention",
  "status": "watchlist",
  "observedAt": "2026-10-23",
  "changesConfirmedLineup": false
}
</code></pre>
<p>The build can surface a watch page or an “official reveal pending” message while refusing to create an unsupported character lineup. Promotion from watchlist to confirmed should require an official notice, in-game Convene data, or another documented high-confidence source.</p>
<h2>Add freshness checks to the build</h2>
<p>A useful pipeline should fail loudly when the live record is stale. Checks can include:</p>
<ul>
<li>the current date is outside the stored banner window</li>
<li>the snapshot date is older than an allowed threshold</li>
<li>the homepage and schedule disagree on the phase number</li>
<li>a history entry overlaps the live phase</li>
<li>a confirmed record has no source URL</li>
</ul>
<p>These checks are small, but they catch the errors that matter most to a player making a limited-currency decision.</p>
<p>I applied this structure to <a href="https://wuwabanners.net/">WuWa Banners</a>, an independent tracker and guide hub for current and next banners, countdowns, history, rerun context, pity, and pull planning.</p>
<p>Static output is an advantage here. The current answer is present in crawlable HTML, the build is reproducible, and a dated snapshot makes the page’s freshness visible. The site can change often without hiding its uncertainty or depending on a client-rendered feed.</p>
]]></content:encoded></item><item><title><![CDATA[Designing a Puzzle Guide Around Observable Evidence]]></title><description><![CDATA[A practical data model for puzzle guides that preserves conflicting sources, matches visible clues, and keeps route progress in local browser storage.]]></description><link>https://game-guide-lab.hashnode.dev/designing-a-puzzle-guide-around-observable-evidence</link><guid isPermaLink="true">https://game-guide-lab.hashnode.dev/designing-a-puzzle-guide-around-observable-evidence</guid><category><![CDATA[technical writing]]></category><category><![CDATA[Game Development]]></category><category><![CDATA[user experience]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[bingkun zhao]]></dc:creator><pubDate>Sun, 25 Oct 2026 13:01:02 GMT</pubDate><content:encoded><![CDATA[<p>Game walkthroughs often begin as prose, but a route with repeated puzzle patterns quickly becomes a small information system. The Last Taxi in CONTROL Resonant is a useful example: players need to find seven cabs, recognize the signal changing around each encounter, complete three rounds, and remember which Thresholds are already closed.</p>
<p>The design problem is not just how to display seven locations. It is how to preserve source confidence, help players identify a puzzle from visible evidence, and store progress without pretending the guide is connected to the game.</p>
<h2>Model locations and puzzle rules separately</h2>
<p>A tempting schema stores one puzzle answer inside each district record. That is compact, but it assumes the encounter is permanently fixed to the zone.</p>
<p>A more resilient model has two collections:</p>
<pre><code class="language-text">Location
- zone
- landmark
- approach notes
- source status
- reported puzzle pattern

PuzzlePattern
- visible signal
- observation method
- confirmation signal
- common mistakes
</code></pre>
<p>The location tells the player where to look. The pattern tells the player what evidence to watch. A reported pairing can still appear as context, but the matching logic starts with the live clue.</p>
<p>For example, “overhead lamps flash in a repeating rhythm” should route to the streetlight pattern regardless of which district card the player opened first. The result explains how to observe a full cycle and use the green traffic light as confirmation. It does not return a hard-coded taxi number.</p>
<h2>Preserve conflicting source claims</h2>
<p>Several route descriptions agree on the district while disagreeing on the final approach. Flattening both into a single coordinate would make the data look clean at the cost of accuracy.</p>
<p>Instead, a location record can keep a stable landmark and an array of claims:</p>
<pre><code class="language-json">{
  "zone": "Unknown",
  "landmark": "Evac Building on the southern island",
  "claims": [
    { "direction": "west", "source": "source-a" },
    { "direction": "north", "source": "source-b" }
  ],
  "status": "sources-disagree"
}
</code></pre>
<p>The UI can then show the shared landmark first and the disputed bearing second. This is more useful than a generic warning because the player still gets an actionable anchor.</p>
<h2>Use local storage for a lightweight route log</h2>
<p>The checklist only needs seven booleans and a schema version:</p>
<pre><code class="language-json">{
  "version": 1,
  "completed": {
    "downtown": true,
    "central": false
  }
}
</code></pre>
<p>The interface writes the record only after the player marks a Threshold complete. A reset action clears the same key. No account, cloud database, or game API is required.</p>
<p>This architecture is intentionally modest. It supports the player’s session without implying synchronized game progress. The page should state that boundary directly: progress stays in this browser only.</p>
<h2>Make the first screen answer the current question</h2>
<p>The route page has three common entry states:</p>
<ol>
<li>“Where is the next taxi?”</li>
<li>“Which puzzle am I looking at?”</li>
<li>“Which locations have I already completed?”</li>
</ol>
<p>Those states map cleanly to three interface blocks: location cards, a clue matcher, and a route log. Long-form explanation remains available below them, but the tools answer the immediate question first.</p>
<p>I used this structure in <a href="https://controlresonantguide.app/">Resonant Field Guide</a>, an independent CONTROL Resonant guide covering the seven reported locations, six visible puzzle patterns, and a local completion log.</p>
<p>The general lesson applies beyond games. If a guide combines uncertain sources, repeated rules, and personal progress, separate those concerns in the data model. Store disagreement instead of erasing it, match on observable evidence, and keep local state within the boundary you can truthfully support.</p>
]]></content:encoded></item><item><title><![CDATA[Designing a Game Wiki Around Player Intent]]></title><description><![CDATA[A practical content model for organizing game guides by player goals, patch versions, evidence status, and the next useful test.]]></description><link>https://game-guide-lab.hashnode.dev/designing-a-game-wiki-around-player-intent</link><guid isPermaLink="true">https://game-guide-lab.hashnode.dev/designing-a-game-wiki-around-player-intent</guid><category><![CDATA[technical writing]]></category><category><![CDATA[Game Development]]></category><category><![CDATA[user experience]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[bingkun zhao]]></dc:creator><pubDate>Sun, 25 Oct 2026 06:30:11 GMT</pubDate><content:encoded><![CDATA[<p>A game wiki is easier to maintain when its information architecture starts with the player's next decision rather than with a list of content formats.</p>
<p>That sounds obvious, but many small guide sites begin with categories such as “articles,” “news,” and “database.” Those labels describe how the site stores content. They do not describe what a player is trying to do.</p>
<p>For Task Bar Hero Atlas, I used a decision-first structure built around four questions:</p>
<ol>
<li>What resource am I trying to farm?</li>
<li>What is stopping the current run?</li>
<li>Which route or build should I test next?</li>
<li>Is this information current for the game version I am playing?</li>
</ol>
<h2>Model the bottleneck before the recommendation</h2>
<p>An idle RPG build is not useful without a goal. Clear speed, boss damage, and survival can point to different Rune priorities even at the same stage.</p>
<p>That led to a small content model for route pages:</p>
<pre><code class="language-text">route
  goal
  progression_context
  patch_version
  evidence_status
  recommended_next_test
</code></pre>
<p>The last field is deliberate. A guide should leave the player with something they can compare. “Try this route on the same stage and watch whether the run fails earlier or later” is more actionable than an unsupported “S-tier” label.</p>
<h2>Keep tools small and local</h2>
<p>The homepage includes a chest timer, but the tool does not pretend to know a server-side chest state. It is a simple local reminder for the player's own session.</p>
<p>That boundary is useful in product design. A local timer can be reliable without collecting account data or inventing live game telemetry. The page states what the tool does, gives quick presets, and links to the deeper chest notes for context.</p>
<p>The same pattern works for the Rune helper. It asks for the player's current goal, returns a first priority to test, and sends the user to the detailed Rune desk for the reasoning. The small interaction handles routing; the reference page handles evidence.</p>
<h2>Attach version context to every volatile claim</h2>
<p>Patch-sensitive content should carry its own version and confidence state. For example:</p>
<ul>
<li>an official release note can confirm that a feature exists;</li>
<li>a repeated player test can support an observation;</li>
<li>a roadmap can describe a plan;</li>
<li>none of these automatically proves an absolute drop rate or a universal best build.</li>
</ul>
<p>This separation prevents a common maintenance failure: a future announcement gets copied into a current guide, then survives after the release changes.</p>
<h2>Build the homepage as a routing layer</h2>
<p>The resulting homepage is not a compressed copy of every guide. It is a routing layer with three fast paths: find a farm, pick a build, or check a drop. It also shows the tracked patch, the current coverage boundary, and the tools that can be used immediately.</p>
<p>You can see the working structure at <a href="https://taskbarheroatlas.com/">Task Bar Hero Atlas</a>. The project is an independent guide for Task Bar Hero, currently tracking Ver 1.3.0, with 20 public pages covering Rune routes, builds, farming, stages, drops, pets, patch notes, and local tools.</p>
<p>For a small knowledge site, this structure keeps both readers and maintainers oriented: the player starts from a decision, and every volatile answer carries the context needed to revisit it later.</p>
]]></content:encoded></item><item><title><![CDATA[A Small Data QA Pipeline for 156 Game Walkthrough Pages]]></title><description><![CDATA[A practical content model for checking game identity, level numbers, source videos, duplicates, and mismatched walkthrough pages.]]></description><link>https://game-guide-lab.hashnode.dev/a-small-data-qa-pipeline-for-156-game-walkthrough-pages</link><guid isPermaLink="true">https://game-guide-lab.hashnode.dev/a-small-data-qa-pipeline-for-156-game-walkthrough-pages</guid><category><![CDATA[data-quality]]></category><category><![CDATA[Testing]]></category><category><![CDATA[Game Development]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[bingkun zhao]]></dc:creator><pubDate>Sat, 24 Oct 2026 17:43:44 GMT</pubDate><content:encoded><![CDATA[<p>A library of 156 walkthrough pages can fail in quiet ways. One wrong video ID, a duplicated level, or a guide mapped to a similarly named game may stay online for months because every individual page still renders correctly.</p>
<p>The fix is to treat content verification like a small data-quality pipeline.</p>
<h2>Define a minimal walkthrough record</h2>
<p>Each walkthrough should have a stable set of fields:</p>
<pre><code class="language-ts">type Walkthrough = {
  gameId: string;
  levelNumber: number;
  sourceUrl: string;
  sourceVideoId: string;
  visibleSourceTitle: string;
  checkedAt: string;
  boardNotes?: string;
};
</code></pre>
<p><code>gameId</code> matters because generic titles are ambiguous. A web game and a mobile app may both be called Fish Sort Puzzle while using different boards and level numbering.</p>
<h2>Run collection-level checks</h2>
<p>Page-level validation is not enough. The full collection should also satisfy rules such as:</p>
<ul>
<li>one record per <code>(gameId, levelNumber)</code> pair;</li>
<li>one intended source video per level;</li>
<li>level numbers within the supported range;</li>
<li>no empty source titles or video IDs;</li>
<li>no accidental gaps unless the missing levels are documented;</li>
<li>all canonical URLs generated from the same route rule.</li>
</ul>
<p>A duplicate check catches copy-and-paste mistakes. A range check catches a page labeled 170 that still points to Level 169. A gap report gives editors a concrete work queue instead of relying on memory.</p>
<h2>Keep source evidence separate from strategy</h2>
<p>Source metadata and editorial advice change at different speeds. The video mapping may remain valid while the written strategy improves. Event rewards or economy values may change with a game update.</p>
<p>Keeping those layers separate makes reviews smaller:</p>
<ol>
<li>Verify identity and source mapping.</li>
<li>Describe the opening board and the important blockers.</li>
<li>Add strategy notes and checkpoints.</li>
<li>Date any version-sensitive facts.</li>
</ol>
<p>This structure also makes corrections safer because a source fix does not require rewriting unrelated strategy content.</p>
<h2>Give readers a mismatch test</h2>
<p>A verified mapping still needs a human-readable check. Before following a walkthrough, the player should compare the opening board:</p>
<ul>
<li>Does the number of containers match?</li>
<li>Are the same colors visible at the top?</li>
<li>Are blocked or hidden stacks in the same positions?</li>
<li>Is the walkthrough for the same app, not merely the same title?</li>
</ul>
<p>If those signals differ, the user should stop. Replaying an incompatible solution is more frustrating than being told that the board has not been mapped yet.</p>
<h2>Publish the distinction prominently</h2>
<p>The homepage, level pages, and download page should all repeat the source boundary in plain language. Structured metadata is useful for maintenance, but users need the distinction before they invest time in a guide.</p>
<p>I applied this model to <a href="https://fishsortpuzzle.app/">Fish Sort Wiki</a>. The site offers a YIGOT browser game and a separate library of 156 mobile walkthroughs mapped to the Shycheese version by visible title and video ID. It also keeps downloads on official store links rather than hosting APK files.</p>
<p>For any large guide library, the strongest quality feature is not page count. It is the ability to prove that each page belongs to the correct product, version, level, and source.</p>
]]></content:encoded></item><item><title><![CDATA[A Practical Content Model for Versioned Game Guides]]></title><description><![CDATA[A practical model for versioned game guides that tracks evidence, freshness, and uncertainty without rewriting every page.]]></description><link>https://game-guide-lab.hashnode.dev/a-practical-content-model-for-versioned-game-guides</link><guid isPermaLink="true">https://game-guide-lab.hashnode.dev/a-practical-content-model-for-versioned-game-guides</guid><category><![CDATA[technical writing]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[SEO]]></category><category><![CDATA[Game Development]]></category><dc:creator><![CDATA[bingkun zhao]]></dc:creator><pubDate>Sat, 24 Oct 2026 07:07:15 GMT</pubDate><content:encoded><![CDATA[<p>Documentation for a live or Early Access game behaves more like versioned software documentation than a traditional magazine article. Mechanics change, official wording evolves, and community discoveries arrive before they can be reproduced. If a guide stores all of that as undifferentiated prose, maintenance becomes guesswork.</p>
<p>While building an independent Fatal Frontier 1869 guide, I adopted a small content model that separates the claim, its evidence, and its lifespan.</p>
<h2>Start with the claim, not the page</h2>
<p>A page is a presentation. The maintainable unit is the claim behind it. For each update-sensitive statement, record:</p>
<pre><code class="language-ts">type EvidenceState = "official" | "observed" | "reported" | "unknown";

type GuideClaim = {
  statement: string;
  state: EvidenceState;
  sourceUrl?: string;
  checkedAt?: string;
  checkedBuild?: string;
  reviewTrigger?: "patch" | "terms-change" | "manual";
};
</code></pre>
<p>This is a conceptual model rather than a required stack. It works in a CMS, Markdown front matter, JSON, or a relational database. The important part is that evidence state is explicit.</p>
<h2>Give unknowns a first-class state</h2>
<p>Many content systems allow published or draft, but not “the question is valid and the answer is unknown.” That gap encourages accidental fabrication.</p>
<p>An unknown record lets the public page say exactly what is missing. It also creates a useful research queue: look for an official source, reproduce the behavior, or keep the answer marked as unresolved.</p>
<h2>Attach review triggers</h2>
<p>Dates alone do not explain why a statement should be checked again. I use review triggers:</p>
<ul>
<li><strong>patch</strong> for mechanics and numeric values;</li>
<li><strong>terms-change</strong> for eligibility, purchases, withdrawals, or other real-value rules;</li>
<li><strong>manual</strong> for durable explanations that change only when the whole system is redesigned.</li>
</ul>
<p>This reduces unnecessary rewrites. A new patch can invalidate a movement threshold while leaving the first-run decision framework intact.</p>
<h2>Render evidence close to the answer</h2>
<p>A source list at the bottom is useful, but it does not show which citation supports which sentence. The page should place a small evidence label, date, or source link near a volatile claim. The interface can stay quiet; the relationship just has to remain visible.</p>
<p>For search pages, I still lead with a concise answer. The evidence and limitations follow immediately, so a search snippet or AI extraction is less likely to detach a number from its conditions.</p>
<h2>Organize routes by intent</h2>
<p>The navigation should reflect real tasks rather than the internal database:</p>
<ul>
<li>first expedition;</li>
<li>supplies and survival;</li>
<li>Pioneers and game systems;</li>
<li>extraction;</li>
<li>gold, costs, and current official rules;</li>
<li>evidence and update status.</li>
</ul>
<p>One claim may appear in several routes. Keeping it structured makes those appearances consistent while allowing each page to explain the decision in its own context.</p>
<h2>A concrete example</h2>
<p>The approach is visible in the independent <a href="https://fatalfrontier1869.wiki/">Fatal Frontier 1869 Wiki</a>. The site covers beginner routes and systems while keeping official statements, repeatable observations, player reports, and unresolved details distinct. It is an unofficial project and is not affiliated with the game's developer.</p>
<p>The broader pattern applies to any fast-moving knowledge base: store certainty and freshness with the content, render them near the answer, and let update events target the smallest affected unit. That turns maintenance from a full-site rewrite into a bounded review.</p>
]]></content:encoded></item></channel></rss>