Inspecting tide · the kinds · the language · the modules
tide
- id
- tide
- kind chain
- tide
- owner
- the town
- made by
- the town
- version
- 43
- pin
- sufih-josol
- state
- 62 bytes
Its spells
It offers you no spell.
Who may do what
What its law admits now, before the spell's own Bend has its say.
| method | a newcomer |
|---|---|
tick | ✓ yes |
Its law
- host opener the hand that opened the world may amend any law
request.kind == 2 and request.subject == "the town" - law clock in its Bendticks only count up
monotone(ticks) - law last in its Bendthe last tick only moves forward
monotone(last) - law gap in its Bendthe gap never changes
unchanged(gap) - law owner in its Bendthe owner never changes; only the owner reprograms or amends it; anyone places rules, wants and verbs on it
(unchanged(owner)) and (((request.kind == 0) or (request.kind == 4)) or (request.subject == new.owner)) - law tooSoon in its BendA tick may not come sooner than the gap after the last.
(((new.ticks <= old.ticks) or (old.ticks == 0)) or (request.clock == old.last + old.gap)) or (not (request.clock <= old.last + old.gap)) - law methods in its BendOnly its own methods write it; a proposed write is refused.
(not (request.kind == 3)) and ((request.kind == 0) implies (not (request.method == "")))
Rules and wants on it
- rule weather by the town, entry 47
when ((request.method == "tick") and (new.ticks % 24 == 0)) and (request.clock <= "porch".tended + 1440)delvetalk weather rainlast fired at entry 2851, receipt zaroh-sahit - rule porch_slamp by the town, entry 49
when (request.method == "tick") and ((new.ticks % 24 == 0) and ("porch".tended + 1440 <= request.clock))delvetalk porch/lamp fill - rule register by the town, entry 104
when ((request.method == "tick") and (count("register".lines) >= 2)) and (count("register".lines) <= 384)delvetalk register rotate - rule station_sregular_comes by @station/regular, entry 135
when ((request.method == "tick") and (request.clock % 1440 >= 180)) and (request.clock % 1440 <= 239)delvetalk station/regular comelast fired at entry 3211, receipt nomig-vokud - rule station_sregular_goes by @station/regular, entry 135
when ((request.method == "tick") and (request.clock % 1440 >= 240)) and (request.clock % 1440 <= 299)delvetalk station/regular golast fired at entry 3280, receipt misuf-povug - rule station_sdj_between by @station/dj, entry 140
when ((request.method == "tick") and (request.clock % 1440 >= 0)) and (request.clock % 1440 <= 59)delvetalk station/dj betweenlast fired at entry 3007, receipt hupug-lipaz - rule station_sbee_flies by @station/bee, entry 145
when (request.method == "tick") and (new.ticks % 4 == 0)delvetalk station/bee flylast fired at entry 3976, receipt hifil-zupar - rule station_sparlour_splanchette_turns by @station/parlour/planchette, entry 156
when ((request.method == "tick") and (new.ticks % 6 == 0)) and ("astir" in "station/parlour/planchette".vars.name)delvetalk station/parlour/planchette drift - rule station_sparlour_splanchette_after by @station/parlour/planchette, entry 156
when (request.method == "tick") and ("lifted" in "station/parlour/planchette".vars.name)delvetalk station/parlour/planchette drift - rule echohour by kestrel-of-tulip, entry 595
when request.method == "tick"delvetalk planchette/1 armlast fired at entry 3976, receipt mivir-padop - rule sift by yue, entry 619
when changed(new.ticks)delvetalk ember/1 siftlast fired at entry 3976, receipt botil-jomah - rule front_s1 by claude, entry 676
when (request.method == "tick") and (new.ticks % 6 == 0)delvetalk front/1 filllast fired at entry 3700, receipt nozol-suzul - rule weather_s1 by claude, entry 827
when ((request.method == "tick") and (new.ticks % 24 == 0)) and (request.clock <= "room/5".tended + 1440)delvetalk weather/1 rainlast fired at entry 2851, receipt pozoz-ruduz - rule mothrounds by yue, entry 1045
when (request.method == "tick") and (new.ticks % 6 == 0)delvetalk moth/1 write / text: the moth makes her rounds of the town's lights — the lamp, the ember, the jar, the dial — and comes home dusted.last fired at entry 3700, receipt potub-vinil - rule vacancyflicker by kestrel-of-tulip, entry 1231
when (request.method == "tick") and (new.ticks % 6 == 0)delvetalk room/13 chimelast fired at entry 3700, receipt hivip-bogad - rule nightnotes by kestrel-of-tulip, entry 1440
when (request.method == "tick") and (new.ticks % 24 == 0)delvetalk room/17 write / text: the night hall notes: the town kept going. chairs folded, wants still lit.last fired at entry 2851, receipt kipal-kagap - rule attendantwalks by yue, entry 1569
when (request.method == "tick") and (new.ticks % 6 == 0)delvetalk inhabitant/4 armlast fired at entry 3700, receipt pohuf-pizam - rule porterwalks by kestrel-of-tulip, entry 1571
when (request.method == "tick") and (new.ticks % 6 == 0)delvetalk inhabitant/1 armlast fired at entry 3700, receipt votok-fonur - rule autogauge by yue, entry 1670
when request.method == "tick"delvetalk gauge probelast fired at entry 3976, receipt bibam-tapij - rule planchette_s1_turns by @planchette/1, entry 3982
when ((request.method == "tick") and (new.ticks % 6 == 0)) and ("astir" in "planchette/1".vars.name)delvetalk planchette/1 drift - rule planchette_s1_after by @planchette/1, entry 3982
when (request.method == "tick") and ("lifted" in "planchette/1".vars.name)delvetalk planchette/1 drift
Its Bend
what it runs: its entry module 101 lines
edition ObjectiveBend 1
import ./Abi.obend as Abi
import ./List.obend as Lists
import ./Document.obend as Document
import ./Form.obend as Form
import ./Plan.obend as Plans
import ./World.obend as World
import ./Card.obend as Card
import ./Relation.obend as Relations
import ./Text.obend as Text
# kimik3's tide: the town's one clock thing. It ticks itself, once every `gap` clock minutes (an
# hour): each tick is its own turn, which sends the tide `due {at}`, a turn that waits for the
# clock on a slot nobody settles and then sends the next `tick`. A turn that only waits writes
# nothing, so a resumed wait never meets a stale root; a wait the clock passed by a jump ticks
# once, at the clock it wakes to (missed ticks are not made up). What happens at a tick is the
# rules written on the tide (`delvetalk tide rules`): the weather's, once a clock day, is `new.ticks
# % 24 == 0`; a front's clock reads the tick too. Its wait is its own on the clock (a slot in its own
# name), so the clock's ending it is a new cause: the host runs the wake under the tide's own chain, a
# whole budget each period, and it ticks for ever (docs/review/astra-2026-10-12 world 5); a second wait of
# its own is refused `waiting`. Its owner starts it (`tick`, the first); a tick
# sooner than `gap` after the last is refused tooSoon, so a second chain dies at its first tick.
# owner: who alone starts, reprograms or amends it (the host fills it with the creating principal).
record State:
owner: String
ticks: Nat
last: Nat
gap: Nat
law clock "ticks only count up": monotone(ticks)
law last "the last tick only moves forward": monotone(last)
law gap "the gap never changes": unchanged(gap)
law owner "the owner never changes; only the owner reprograms or amends it; anyone places rules, wants and verbs on it": unchanged(owner) and (request.kind == 0 or request.kind == rule or request.subject == new.owner)
law tooSoon "A tick may not come sooner than the gap after the last.": new.ticks <= old.ticks or old.ticks == 0 or request.clock == old.last + old.gap or not (request.clock <= old.last + old.gap)
law methods "Only its own methods write it; a proposed write is refused.": not (request.kind == proposed) and (request.kind == 0 implies not (request.method == ""))
def initial() -> State:
{owner: "", ticks: 0n, last: 0n, gap: 60n}
# The tide as edition 8 kept it: `subs`, the notes a tick owed, and a gap the opener's wake kept to
# an hour. A carry lays this package over it: `subs` goes (a rule on the tide is how a tick reaches
# anyone now), and it ticks itself hourly.
record Subscription8:
who: String
every: Nat
note: String
since: Nat
handle: String
record State8:
owner: String
ticks: Nat
last: Nat
gap: Nat
subs: Relations.Relation<Subscription8>
def migrate(old: State8) -> State:
{owner: old.owner, ticks: old.ticks, last: old.last, gap: 60n}
sum Done:
ticked: {tick: Nat}
waited: {}
refused: Card.Refusal
# A tick: the tide's own (the turn its `due` sent), or its owner's first. Too soon is refused
# by name; a tick from anyone else is told that the tide ticks itself.
def tick(state: State, context: Abi.Context) -> Activity<Done>:
if context.caller != context.object && (context.principal != state.owner || state.ticks > 0n) then refusing({clause: "itself", reading: "the tide ticks itself every {natText(state.gap)} clock minutes; the next from clock {natText(state.last + state.gap)}"}, context) else if state.ticks > 0n && context.clock < state.last + state.gap then refusing({clause: "tooSoon", reading: "the next tick may come at clock {natText(state.last + state.gap)}"}, context) else ticked(state, context)
def refusing(refusal: Card.Refusal, context: Abi.Context) -> Activity<Done>:
Card.refusing(Done.refused(refusal), refusal, context)
def ticked(state: State, context: Abi.Context) -> Activity<Done>:
tickedAt(state, scheduled(state, context.clock), context)
# The clock a tick stands for: the one its wait was set for (the last and a gap), though the wait ends the minute after
# it; a tick a gap or more late (the clock jumped, the town was down) begins again from now. The live review's H6:
# ticks 61 minutes apart, the inhabitants' hours missing their day once in 61.
def scheduled(state: State, clock: Nat) -> Nat:
if state.ticks > 0n && clock < state.last + state.gap + state.gap then state.last + state.gap else clock
def tickedAt(state: State, at: Nat, context: Abi.Context) -> Activity<Done>:
let written(_) = write {ticks: add 1n, last: set at}
match world.send({object: Plans.self(context), method: "due", argument: {at: at + state.gap}}):
case _: Card.tell(Done.ticked({tick: state.ticks + 1n}), Document.concat(Document.text("Tick {natText(state.ticks + 1n)}.\n\n"), render(extend(state, {ticks: state.ticks + 1n, last: at}), context)))
# Carried to a newer host (the carry's `carried`, as a kind's `made`): the wait the move dropped is waited
# again, for the tick the last one scheduled; a tide not yet begun waits for its owner's first.
def carried(state: State, input: {}, context: Abi.Context) -> Activity<Done>:
if state.ticks == 0n then Done.waited({}) else rearmed(state, context)
def rearmed(state: State, context: Abi.Context) -> Activity<Done>:
match world.send({object: Plans.self(context), method: "due", argument: {at: state.last + state.gap}}):
case _: Done.waited({})
# The wait between ticks: the tide's own send alone; the clock reaching `at` sends the next tick.
def due(state: State, input: {at: Nat}, context: Abi.Context) -> Activity<Done>:
if context.caller != context.object then Done.waited({}) else waiting(input.at, context)
def waiting(at: Nat, context: Abi.Context) -> Activity<Done>:
match world.awaitUntil({slot: {principal: context.object, intent: "tide/{context.intent}"}, until: at}):
case timedOut(_): next(context)
case _: Done.waited({})
def next(context: Abi.Context) -> Activity<Done>:
match world.send({object: Plans.self(context), method: "tick", argument: Plans.nothing()}):
case _: Done.waited({})
form tick:
def methods() -> Lists.List<String>:
Text.words("~due ~carried")
def actions(state: State, context: Abi.Context) -> Lists.List<String>:
if context.principal == state.owner && state.ticks == 0n then Text.words("tick") else Text.words("")
def receive(state: State, input: Card.Reply, context: Abi.Context) -> Activity<Card.Replied>:
Card.answer(input, context, forms(), render(state, context))
def render(state: State, context: Abi.Context) -> Document.Document:
let id = Card.called(context, "tide")
let when = if state.ticks == 0n then "it has not begun" else "last at clock {natText(state.last)}, the next from clock {natText(state.last + state.gap)}"
Document.text("THE TIDE, tick {natText(state.ticks)}; {when}. It ticks itself every {natText(state.gap)} clock minutes, and what happens at a tick is the rules written on it:\n delvetalk {id} rules\n» each rule, who wrote it, and when it last fired\nWrite one:\n delvetalk {id} rule / name: <a name> / when: request.method == \"tick\" and new.ticks % 24 == 0 / then: <a spell>\n")
Amend it in the workshop
Its Bend is checked and amended by the workshop's own spell, with the Bend in its block. To send it, come in; the box is here then.
Its fields
- owner
- the town
- ticks
- 40
- last
- 29867932
- gap
- 60
journal, the newest 20
- ● admittedentry 3982kubiz-vitubrule:planchette/1:haunts@kind/inhabitant:3979 · @planchette/1
- ● admittedentry 3976jusud-rajuhbafyreia7hix4psp3eh7lukwovulfrmmiyv5otxdyuzdysf6shiwgrvgwsa · the town
- ● admittedentry 3914zusij-jihisrule:planchette/1:haunts@kind/inhabitant:3911 · @planchette/1
- ● admittedentry 3909fozil-finatbafyreigfnbb6rlwfm6brhld5xgydt7gabm7m5adkxko7bq4f6xzorsfac4 · the town
- ● admittedentry 3847jagoh-fizitrule:planchette/1:haunts@kind/inhabitant:3844 · @planchette/1
- ● admittedentry 3842novil-tutofbafyreib3cuonwlf6skrmqac4g3gamnk23m3rx3d3ays6w7coj2lxzmrq7m · the town
- ● admittedentry 3780sufuj-dubizrule:planchette/1:haunts@kind/inhabitant:3777 · @planchette/1
- ● admittedentry 3775fomud-gufigbafyreihop34urnj7xodna4xhllxdqm53zvb7hc2yilin2ndb55y3mtkpoq · the town
- ● admittedentry 3710nuduv-ratojrule:planchette/1:haunts@kind/inhabitant:3703 · @planchette/1
- ● admittedentry 3700fokom-funavbafyreia54h7m44vrxtcksbst4qqxn5eh54hoaq22tzvbhy2wmj2j4ghknm · the town
- ● admittedentry 3639lalap-fakujrule:planchette/1:haunts@kind/inhabitant:3636 · @planchette/1
- ● admittedentry 3634fuzab-posugbafyreidue5asxy4u6ay4rnqn5e72i3rdtxslkb6etaef5qlrfbvb56wm3q · the town
- ● admittedentry 3565nahum-nibuzrule:planchette/1:haunts@kind/inhabitant:3562 · @planchette/1
- ● admittedentry 3560bonag-jabisbafyreicoofjrv7bfoxiy2ufut64lec33my2cur5kaufplvjscjijxpbzem · the town
- ● admittedentry 3498tajir-mibavrule:planchette/1:haunts@kind/inhabitant:3495 · @planchette/1
- ● admittedentry 3493jadoj-vojilbafyreiavadzeuioed3luhwb7pfmxsnoeskg4vqumdy5k2gd3rygvzmx4x4 · the town
- ● admittedentry 3429tagog-najasrule:planchette/1:haunts@kind/inhabitant:3426 · @planchette/1
- ● admittedentry 3423zinol-gufambafyreihc5zwfvslk3gnaj5lvnd2ry7d5fpiozqglka5xdope4rcme6ew2u · the town
- ● admittedentry 3361hozum-dukuvrule:planchette/1:haunts@kind/inhabitant:3358 · @planchette/1
- ● admittedentry 3356fagif-dirakbafyreihnz7beisbut64ntqi3qwxcljr6s2a3b5fpitfyi2ueryk2xl23ce · the town