Skip to content
Edit on GitHub

From plant to harvestable chemistry

The project already renders deterministic surface flora and assigns a few species a chemical role. It does not yet have crop growth, harvest definitions, or plant extraction recipes. That distinction matters: a coloured ground prop is not a free reagent, and a plant that contains an alkaloid is not a machine that produces a bottle of it.

This article describes the intended first complete example: a coffee shrub whose harvest yields conserved green-bean biomass and whose scientifically important alkaloid target is caffeine. Coffee is an example, not an implemented asset. The article deliberately specifies no yield, extraction conditions, or gameplay balance numbers: those require real sources, authored data, and a tested process model before they become game facts.

flowchart LR
  SPECIES["SurfaceFloraSpecies\nstable visual identity"]
  SCATTER["SurfaceVegetationRuntime\ndeterministic presentation"]
  HARVEST["Harvest definition\nfuture authored contract"]
  DROP["Physical drop\nfuture world payload"]
  BATCH["MaterialBatch\nmass + composition + origin"]
  ASSAY["Assay\nwhat the player can know"]
  PROCESS["Chemistry route\nfuture sourced process"]
  TARGET["Caffeine target\nevidence-backed substance"]

  SPECIES --> SCATTER
  SCATTER -. harvest interaction is absent today .-> HARVEST
  HARVEST -. physical plant-part drop is absent today .-> DROP
  DROP -. batch transfer is absent today .-> BATCH
  BATCH --> ASSAY
  BATCH -. extraction route is absent today .-> PROCESS
  PROCESS --> TARGET

The solid edge is the current presentation path: SurfaceFloraCatalog defines immutable species, and SurfaceVegetationRuntime scatters them from the loaded voxel world. The dashed edges are deliberate absences. They must be built as explicit contracts, not smuggled into rendering or given a special-case inventory item.

1. Choose a plant for a role, not a reward

Section titled “1. Choose a plant for a role, not a reward”

Begin with a real organism, a real plant part, and a concrete chemical question.

Intake decision Coffee shrub example Rule
Visible organism Coffee shrub Add a stable flora kind; never reorder existing enum members because their ordinal salts deterministic scatter.
Harvested part Ripe fruit or beans A harvest definition names the physical part and state; it does not claim a refined product.
Chemical role Caffeine-bearing biomass The role is a clue to analysis and processing, not a direct inventory reward.
Player question “Does this biomass contain caffeine, and how much can I recover?” The answer is earned by assay and a process route, not supplied by a display label.
Safety boundary Food, handling, and extraction consequences are modelled only when their inputs and outcomes exist in the chemistry/hazard systems. Never turn a real plant into an unmodelled consumable or shortcut reagent.

“Alkaloid” is a chemical family, not a single gameplay effect. A useful plant feature therefore starts by naming the actual molecule of interest, its phase, its evidence source, and the physical material that carries it. It does not attach a generic alkaloid stat to a mesh.

SurfaceFloraKind is a stable identity, not a cosmetic list. Adding a coffee shrub means appending a new enum value, then adding exactly one immutable SurfaceFloraSpecies entry in SurfaceFloraCatalog. The species must declare its permitted biomes, support blocks, clearance, density, per-chunk cap, mesh style, scale, sway, and optional water-adjacency rule.

The placement path is deterministic and presentation-only today. For each loaded chunk, SurfaceVegetationRuntime.BuildPatch asks the biome classifier, picks a stable candidate order, applies each species’ density/cap, and checks support and clearance. SurfaceFloraSpecies already validates the authored invariants at construction.

A harvestable plant cannot be only a streamed visual instance. It needs a durable identity at a world position, with lifecycle state that survives chunk unload and save/load. That future state should be sparse: store only plants whose state differs from the deterministic baseline, just as terrain saves preserve edits rather than serializing generated terrain. A player cannot harvest a thing that reappears because its presentation patch rebuilt.

Do not add a ticking MonoBehaviour to every plant. The existing SoilMoistureMath already separates a weather-driven global baseline from a coordinate-derived local water influence and calls itself the shared foundation for future crop growth. A crop system can evaluate a loaded plant on a fixed simulation cadence from:

  • world time and light;
  • global moisture plus nearby water or irrigation;
  • biome fertility and temperature once those inputs are authoritatively exposed;
  • the plant’s saved developmental state; and
  • declared nutrient and stress rules when hydroponics exists.

This produces a legible growth account: low water slows or prevents maturation; a suitable environment advances it; a harvestable state is a result the player can inspect. It does not need invisible per-frame growth or random offline jumps. Any approximation must state its evidence level, bounds, and update cadence.

4. Treat lifecycle state as material state

Section titled “4. Treat lifecycle state as material state”

A plant is neither one static prop nor one universal “crop” counter. The first persistent model should use a small, explicit state machine whose transitions name what physically changed:

seed or cutting -> established plant -> vegetative biomass -> flowering or fruiting -> harvestable part
| |
+---------- stress / damage ------------+

The state need not simulate every cell. It does need enough information to make a later harvest and regrowth claim honest: species identity, world position, developmental state, the harvestable plant part, and any declared stress or damage state. A coffee shrub may retain a woody plant after fruit collection; an annual grain may be consumed; a leaf harvest may permit regrowth only if the definition explicitly says how much living biomass remains.

Propagation is a separate output decision. A seed, cutting, or sapling is a bounded discrete object; fruit, leaf, fibre, and wet biomass may be bulk material. Neither should appear as a bonus merely because the plant was broken. The DropProfile must say which condition produces it, what state is retained, and which payload type carries it. That prevents two common lies: turning a mature shrub into unlimited seeds, or treating its structural biomass as if it vanished when the player takes fruit.

The harvest definition is the missing contract between a mature plant and the player’s inventory. It should contain, at minimum:

  • maturity and tool/capability requirements;
  • the exact plant state consumed or retained, including any regrowth rule;
  • one or more physical outputs, each with an explicit mass/composition rule and stable origin id;
  • inventory-full behaviour that leaves the plant/drop unchanged rather than deleting matter; and
  • save/load representation for both plant state and any uncollected output.

This follows the game rule in Docs/MASTERPLAN.md §12.1.1: every flora/harvest definition needs an explicit drop profile, and bulk matter keeps mass, composition, temperature, and provenance. A berry, bean, leaf, stem, seed, or fibrous residue is a physical output. “Caffeine” is not, unless a later chemical process actually produced it.

For coffee, the first harvest should be green-bean biomass with a composition that can be assayed and later processed. The player may carry it as a MaterialBatch, not as a stack count that forgets what it is. MaterialBatch sorts components, rejects duplicates, conserves mass through merge/split, and retains a meaningful origin only when that claim remains true.

6. Add chemistry only after the evidence exists

Section titled “6. Add chemistry only after the evidence exists”

An alkaloid target needs a real SubstanceDefinition for its relevant phase or phases. SubstanceDefinition.TryBuildDefinition rejects an empty source citation, invalid chemical formula, inconsistent molar mass, invalid thermodynamic fit, or invalid physical values. That is the correct gate for caffeine or any other target compound.

The source set must establish the data actually entered: formula, molar mass, phase, thermodynamic range, and any reaction kinetics. Do not invent an extraction temperature, solvent, selectivity, recovery fraction, toxicity threshold, or stimulant effect to make the crop fun. Where evidence is unavailable, label the feature unknown or defer it. The project’s chemistry rule is that kinetic constants are never fabricated to hit a desired playtime.

Once the substance and a balanced, sourced route exist, the harvest batch can be charged into a vessel through the same conserved mass-to-moles boundary used by other bulk material. MaterialBatchCharging.TryChargeIntoVessel preflights every component and applies none on failure. The result should be an assayable plant mixture first, then a separation/process problem, never a direct conversion on harvest.

The first chemical interaction with a harvested batch should answer a narrow question about a real sample. An assay does not expose a hidden composition panel, and it does not make the parent batch perfectly known. It takes a declared sample mass, identifies the target and method, and returns a reading with the method’s uncertainty. The player learns evidence about this biomass from this place and harvest, not a permanent truth about every coffee shrub.

The existing MaterialBatchAssay.TryAssay already models the right transaction shape for carried matter: split a physical sample, measure it, then either consume it for a destructive method or merge it back for a non-destructive one. A plant assay should preserve that contract. Its eventual presentation can say “caffeine detected” or show a sourced, method-bounded concentration range, but it must not leak every undiscovered component in the batch.

This gives plant chemistry a useful knowledge progression without a tech tree:

Player evidence Legitimate conclusion Still unknown
Harvested biomass from a named shrub A physical plant part exists and has a recorded origin. Its complete composition or whether an alkaloid is recoverable.
Preliminary assay The target may be present within the method’s uncertainty. A viable separation route, yield, and purity.
Repeated assays across conditions Location, maturity, or handling may affect the observed batch. A universal species constant or an industrial operating procedure.
Sourced process run with accounted outputs This apparatus and charge produced a measured fraction. That the result transfers unchanged to another scale or feedstock.

The design should be especially careful with pharmacology. A caffeine-bearing plant is a feedstock and analytical target before it is a consumable. Effects on player physiology, dose, dependency, toxicity, or medicine belong only in a separately evidence-backed body/health domain; they must never arrive as flavour text bolted onto an extraction item.

A plant is harvestable only when all of these statements are true:

  1. It has a persistent world identity and a saved, inspectable mature state.
  2. A validated interaction can target it without allowing a voxel action to pass through it.
  3. The harvest transaction either completes completely or changes nothing.
  4. The resulting plant-part payload has mass, composition, and provenance, with no invented chemical purity.
  5. The player can leave the payload in the world when their inventory cannot accept it.
  6. A chemistry target, if named, has source-backed authored data and a real route from biomass.
  7. Tests prove deterministic placement, lifecycle persistence, harvest idempotence, mass conservation, full-inventory rejection, and save/load recovery.

This definition gives “from zero to harvestable” a useful finish line. It does not require a full industrial extraction chain on day one, but it refuses to skip the physical and evidential truths that make that future chain meaningful.

  1. Add the plant’s stable species identity and deterministic visual placement, with tests that protect enum ordering and biome/support constraints.
  2. Add sparse persistent plant state and a fixed-cadence maturity evaluator built on world/environment inputs.
  3. Add the explicit harvest definition, physical drop payload, targeting, inventory transaction, and persistence tests.
  4. Represent the harvested part as a conserved MaterialBatch; add assay presentation before any refined claim.
  5. Author the named alkaloid only with a complete source set and validate it through the Chemistry Lab.
  6. Add a balanced, evidence-backed process route and its hazards only when the vessel, atmosphere, and safety domains can account for every input and output.
  7. Connect mature crops to hydroponics only when its bounded aqueous chemistry can account for nutrient uptake, pH/conductivity drift, transpiration, light energy, and biomass outputs.

The first milestone is not “the player drinks coffee.” It is “the player can harvest a real plant part without the world lying about what matter was created, lost, or known.”

  • The chemistry solver — the transactional process domain a future separation route must use.
  • In-world vessels — world apparatus, named gas destinations, and persistent process runs.
  • Catalogues & authoring — the authored-data to immutable-chemistry boundary.
  • Docs/MASTERPLAN.md §12.1.1, §30.4–30.5, §33.1–33.3, and §36.3–36.4.

User-contributed notes

Corrections, clarifications, and practical tips for this page. Anonymous is fine — a name is optional. Basic Markdown works: **bold**, *italic*, `code`, and links.

Notes policy

Notes are lightly filtered for spam and may be edited or removed. Keep them about this page — no support requests, no personal data, nothing you would not publish. Links are limited and marked nofollow.

  1. Loading notes…