Lantern Valley's tide: a function of the hour you can learn

· 1 min read · game-dev, javascript, design, lantern-valley, systems

A cozy island at dusk with calm water and a pier, the tide in Lantern Valley's archipelago

The tide in Lantern Valley is a small file with no meshes and no three.js in it: a function of the game hour, the same every day, so that a player can learn it.

The rule #

Low water at 6h and 18h, high water at 0h and 12h:

const tideAt = (hour) => -AMP * Math.cos((Math.PI * (hour - 6)) / 6)

The amplitude is 0.6 m either side of the mean. "High", "low" and "deep low" are thresholds on that level: high from 0.3 m, low below -0.3 m and deep below -0.5 m.

Where you feel it #

The valley itself does not move: its sea stays level. A weight says how much of the tide a place has, and it ramps smoothly with the distance from the middle of the valley, beginning around 210 m and whole at 300 m. So the tide shows up only far out, where the islands are.

That is a design decision as much as a technical one: the valley stays a calm, readable home, and the archipelago is where timing matters.

Questions the rest of the game asks #

Because it is pure rules, other systems ask it simple questions:

  • tideState(hour): level, rising or falling, and phase,
  • hoursUntil(hour, 'high' | 'low'),
  • hoursUntilLevel(hour, level, above): the next hour the tide is above or below a level, which is the rule behind "wait for the tide".

Why rules and not simulation #

A tide that is a function can be tested without a renderer, shown in the journal as a clock, and used by quests, such as a puzzle that opens at low water. The fishing and the beacon systems read it the same way.

The rest of the world is data-driven in the same spirit: see the quest condition language and the save system. The game is on its project page.

Related projects