> For the complete documentation index, see [llms.txt](https://codifi-fdm.gitbook.io/codifi-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://codifi-fdm.gitbook.io/codifi-docs/cross-platform-features/ripple/what-ripple-can-do.md).

# What Ripple Can Do

Ripple is the formula engine behind Codifi. It fills Fields in, hides Fields that do not apply, rolls numbers up from child Records, measures geometry, and numbers things across a Project.

This page is the tour. It shows what Ripple is capable of, with a small worked example of each, so you can recognize the shape of a problem Ripple can solve. The [Operations Reference](/codifi-docs/cross-platform-features/ripple/reference.md) has the exhaustive list.

Everything here works the same on web and on mobile. A formula written in the Composition Builder runs on an iPad in the field with no extra work.

{% hint style="danger" %}
**The one rule that catches everyone.** To refer to the Record a formula is running on, use `{"var": ""}` with an **empty string**. Not `{"var": "current"}`. The second one looks reasonable, appears in a lot of hand-written formulas, and silently returns nothing.
{% endhint %}

***

## Reading Another Field on the Same Record

The simplest thing Ripple does is look sideways. A Field can be computed from other Fields on the same Record.

```json
{ "*": [
    { "getFieldByLabel": [{ "var": "" }, "Length"] },
    { "getFieldByLabel": [{ "var": "" }, "Width"] }
] }
```

Useful for anything derived: area from dimensions, a total from parts, a formatted label built out of several Fields.

***

## Reading Up and Down the Hierarchy

Records in Codifi are related, and Ripple can walk those relationships in both directions.

**Upward**, to inherit context from a parent. A Level inheriting its Unit's designation, or any Record picking up the Project name, so the crew does not retype what the system already knows.

```json
{ "getFieldByLabel": [{ "parent": [{ "var": "" }] }, "Unit Number"] }
```

**Downward**, to summarize children. Counting how many Shovel Tests under a Transect were positive, totaling artifact counts across every Level in a Unit, or reporting how many children exist at all.

```json
{ "countChildrenWhere": [
    { "var": "" },
    "<recordTypeId>",
    "Result",
    "Positive"
] }
```

{% hint style="warning" %}
**Key roll-ups off the Record Type id, not its label.** `recordTypeName` returns the display label, which changes the moment somebody renames an Archetype. Roll-ups keyed to the id keep working.
{% endhint %}

***

## Measuring Geometry

Ripple can read the shape attached to a Record and compute from it. Area, perimeter, length, centroid, and whether one thing falls inside another.

```json
{ "polygonAreaUtmPlanar": [{ "var": "" }] }
```

The UTM planar operators are the ones to reach for when the number has to match what a GIS analyst reports. They project into UTM before measuring, the same way ArcGIS does, so acreage agrees with the shapefile rather than differing by a fraction of a percent. That matters for SHPO submissions and anything contractual.

See [Spatial Formulas](/codifi-docs/cross-platform-features/ripple/spatial-formulas.md) for the full set.

***

## Showing and Hiding Fields and Sections

A visibility formula returns true or false and controls whether something appears at all. This is how a form stays short: crews see the Fields relevant to what they are recording and nothing else.

```json
{ "==": [
    { "getFieldByLabel": [{ "var": "" }, "Feature Present"] },
    "Yes"
] }
```

Point that at a Section and the whole block of Fields appears only when it applies.

{% hint style="info" %}
**Hidden Fields still compute.** Hiding a Field does not stop its value formula running, and it does not clear the value it already holds. A Field that becomes hidden keeps whatever was last in it, which will still be there in exports and reports. If a value should go away when its Section is hidden, clear it deliberately.
{% endhint %}

See [Conditional Visibility](/codifi-docs/cross-platform-features/conditional-visibility.md).

***

## Numbering Things Across a Project

New in v3.3. Ripple can now count across an entire Project rather than only within one Record and its relatives.

Give a set of Fields a **sequence group** in the Composition, and every Field instance in that group takes a position in one shared run. Ask for its position with `sequenceNext`:

```json
{ "cat": ["PD-", { "sequenceNext": ["pd-numbers"] }] }
```

Two properties make this usable for real numbering rather than just counting:

**Repeater rows are included.** A Unit with six Levels in a repeater contributes six entries, not one. Project-wide scans previously saw only the first row.

**Positions are permanent.** If a Record is deleted later, it keeps its slot. The next Record takes the number after it rather than reusing the gap.

### Worked example: PD numbers

Archaeologists label everything they excavate with a sequential Provenience Designation. The number is written in permanent marker on a bag before it exists in any database, and it is the join key to field notes, photographs, and a lab catalog decades later.

That is why permanence matters. If PD 8 is voided, the office does not renumber everything after it, because PD 9 is already inked on a bag in a warehouse. They move the voided one to the end of the run. Sequence positions behave the same way, so what Codifi shows agrees with the physical bags.

{% hint style="warning" %}
**Ripple proposes, a person commits.** For hand-assigned numbering, use `sequenceNext` to suggest the next number, not to write it as a live value. A computed number that shifts after a later sync would put the database quietly at odds with a label in a box. Treat the suggestion as a default the recorder confirms.
{% endhint %}

***

## Pattern Fields

A pattern Field builds a value out of parts: a sequence number, a date, the recorder's initials, literal text. Record auto-numbering is the most common use.

Pattern formulas differ from value formulas in one important way. A value formula fills a Field that is **empty**. A pattern formula runs when the Field **already has a value**, which is what lets it reformat and maintain a name as the Record changes.

See [Record Auto-Numbering](/codifi-docs/mobile-app/mobile-project-settings/record-auto-numbering.md).

***

## Prefill That Can Be Overridden

Sometimes you want Ripple to supply a starting value that a person is then free to change. The `overrideOnInit` flag does that: the formula runs once to seed the Field, and after that the recorder owns it.

`overrideOnInit` and pattern formulas are **mutually exclusive**. A Field is one or the other, never both.

***

## Where Formulas Run, and When

Ripple runs in three places, and they are not always in step.

| Where      | When it runs                                                         |
| ---------- | -------------------------------------------------------------------- |
| **Mobile** | Locally on the device, immediately as you type. Works fully offline. |
| **Web**    | In the browser as you edit.                                          |
| **Server** | After a sync, queued per Project.                                    |

The engine follows one principle: **share actions, compute consequences**. Only the original edit travels between devices. Each platform recomputes the results itself from the data it holds.

{% hint style="info" %}
**Server evaluation is asynchronous.** After a sync, server-side results can take a short while to appear. If a rolled-up value on the web looks stale immediately after a crew syncs, give the queue a moment before treating it as wrong.
{% endhint %}

***

## Related

* [Value Formulas](/codifi-docs/cross-platform-features/ripple/value-formulas.md)
* [Visibility Formulas](/codifi-docs/cross-platform-features/ripple/visibility-formulas.md)
* [Spatial Formulas](/codifi-docs/cross-platform-features/ripple/spatial-formulas.md)
* [Aggregation Formulas](/codifi-docs/cross-platform-features/ripple/aggregation-formulas.md)
* [Real-World Examples](/codifi-docs/cross-platform-features/ripple/examples.md)
* [Operations Reference](/codifi-docs/cross-platform-features/ripple/reference.md)
