t27.aiРусский

The comb answers

You will learn

How the game shows that something happened to a task, and how often the map grows.

The game's comb has a cell for each issue, and before hive.t27 an accepted task, a lost lease and a cancel looked the same as no news. cell_effect gives each of the 10 event kinds its paint: a start white, an accepting review gold, a send-back amber, a lost lease red, a cancel grey. flash_alpha fades it over FLASH_MS, 1800 ms. A new cell rebuilds the scene, so cells_due places new cells in batches at most every 300 s.

Try it

Tap the review cell and switch the verdict; then find the moment the flash is gone.

Open the interactive lesson →

The comb answers: what an event does to a cell
The comb answers: what an event does to a cell ↗

Ten kinds of event reach the game. Pick one and the moment since: cell_effect colours the cell gold, amber, red, grey or white, flash_alpha fades it, and cells_due batches new cells.

specs/queen/hive.t27

// SPDX-License-Identifier: Apache-2.0
; specs/queen/hive.t27 -- how the game draws the swarm: where each ship flies, what an event does to
; a cell, how a ship leaves, and how often the map may grow
; Owner, 2026-10-08 (translated): the bees fly over the GitHub issue each is working on, in the game
; (https://app.t27.ai/game); the ships come from the same 3D kit as the comb. Epic #7718, slice 4.
; What the game did before this card (gHashTag/trinity QueenCombBabylon, measured that day):
; - a bee that left the feed vanished in the frame it left: a finished task had no ending on screen.
; - a bee on an issue with no cell yet waited at the hive's entrance, in the middle of the map, far
;   from the repository it works for.
; - every newly running issue the atlas did not hold added one cell, and a new cell rebuilt the whole
;   scene: one rebuild for most bees that started.
; - nothing on the map answered an event: an accepted task, a lost lease and a cancel looked the same
;   as no news.
; The event kinds are control.t27's EV_* (index of a per-kind table here). Bee states arrive as two
; flags rather than tasks.t27's numbers, so no number is restated. The game runs this card as wasm.
; ASCII only (L3).
; phi^2 + 1/phi^2 = 3 | TRINITY

module QueenHive;

pub const HIVE_KINDS : u8 = 10;

; --- 1. Where a ship flies ---------------------------------------------------------------------------

/// Where its issue's cell stands: on the map, waiting for the next batch (section 4), or nowhere this
/// map can show (a repository with no region, or a task that is not an issue).
pub const CELL_PLACED : u8 = 0;
pub const CELL_PENDING : u8 = 1;
pub const CELL_NONE : u8 = 2;

/// PARK: in a row at the hive's entrance. ORBIT: circling its issue's rim. HOVER: still at the rim,
/// heard from too long ago to be drawn working. PORTAL: at its repository's portal, until its cell is
/// placed. HOME: flying back to the entrance, its task over.
pub const SM_PARK : u8 = 0;
pub const SM_ORBIT : u8 = 1;
pub const SM_HOVER : u8 = 2;
pub const SM_PORTAL : u8 = 3;
pub const SM_HOME : u8 = 4;

/// `queued`: not claimed yet. `working`: heard from lately (tasks.t27 bee_state). `departing`: no
/// longer in the feed.
pub fn ship_mode(queued: bool, working: bool, cell: u8, departing: bool) -> u8 {
    if (departing) { return SM_HOME; }
    if (queued) { return SM_PARK; }
    if (cell == CELL_PENDING) { return SM_PORTAL; }
    if (cell != CELL_PLACED) { return SM_PARK; }
    if (working) { return SM_ORBIT; }
    return SM_HOVER;
}

; --- 2. How a ship leaves ----------------------------------------------------------------------------

/// A ship whose bee left the feed flies home and fades out over DEPART_MS, instead of vanishing.
pub const DEPART_MS : u32 = 2400;

pub fn ship_kept(ms_since_left: u32) -> bool {
    return ms_since_left < DEPART_MS;
}

/// Opacity in thousandths: whole while its bee is in the feed, then falling to nothing.
pub fn ship_alpha(departing: bool, ms_since_left: u32) -> u32 {
    if (departing == false) { return 1000; }
    if (ms_since_left >= DEPART_MS) { return 0; }
    return 1000 - (ms_since_left * 1000) / DEPART_MS;
}

; --- 3. What an event does to a cell -----------------------------------------------------------------

/// FX_ACCEPT gold, FX_SEND_BACK amber, FX_LOST red (the lease expired: the bee went silent and the
/// task was taken back), FX_CANCEL grey (a person stopped it), FX_START white at the cell the bee is
/// headed for. task.ended draws nothing on the cell: its ship flies home, which says it.
pub const FX_NONE : u8 = 0;
pub const FX_START : u8 = 1;
pub const FX_ACCEPT : u8 = 2;
pub const FX_SEND_BACK : u8 = 3;
pub const FX_LOST : u8 = 4;
pub const FX_CANCEL : u8 = 5;

/// Per kind (control.t27 EV_*): created START, lease.expired LOST, reviewed ACCEPT or SEND_BACK by
/// its verdict, cancel CANCEL; everything else nothing.
pub const FX_OF_KIND : [10]u8 = [1, 0, 0, 4, 0, 2, 0, 5, 0, 0];

/// `accepted`: a review's verdict was an acceptance. Only a review reads it.
pub fn cell_effect(kind: u8, accepted: bool) -> u8 {
    if (kind >= HIVE_KINDS) { return FX_NONE; }
    let fx : u8 = FX_OF_KIND[kind];
    if (fx == FX_ACCEPT and accepted == false) { return FX_SEND_BACK; }
    return fx;
}

/// A flash rises at once and fades over FLASH_MS; an event older than that is not drawn.
pub const FLASH_MS : u32 = 1800;

pub fn flash_alpha(ms_since: u32) -> u32 {
    if (ms_since >= FLASH_MS) { return 0; }
    return 1000 - (ms_since * 1000) / FLASH_MS;
}

; --- 4. How often the map may grow -------------------------------------------------------------------

/// A running issue the atlas does not hold needs a cell, and a cell is part of the built scene: adding
/// one rebuilds it. So new cells are placed in batches, at most one batch every CELL_BATCH_SECONDS --
/// the same period a board takes a whole snapshot (events.t27 SNAPSHOT_EVERY_SECONDS) -- and all of
/// them at once when the page first opens. Until its cell is placed, a bee waits at its repository's
/// portal (SM_PORTAL), so where it is going is already true.
pub const CELL_BATCH_SECONDS : u32 = 300;

pub fn cells_due(pending: u32, placed_before: bool, seconds_since_batch: u32) -> bool {
    if (pending == 0) { return false; }
    if (placed_before == false) { return true; }
    return seconds_since_batch >= CELL_BATCH_SECONDS;
}

test a_ship_flies_where_its_bee_is {
    // queued: at the entrance, wherever its cell stands
    assert ship_mode(true, false, CELL_PLACED, false) == SM_PARK;
    assert ship_mode(true, true, CELL_PENDING, false) == SM_PARK;
    // claimed, its cell placed: orbit while heard, hover when quiet
    assert ship_mode(false, true, CELL_PLACED, false) == SM_ORBIT;
    assert ship_mode(false, false, CELL_PLACED, false) == SM_HOVER;
    // its cell not placed yet: at its repository's portal, working or not
    assert ship_mode(false, true, CELL_PENDING, false) == SM_PORTAL;
    assert ship_mode(false, false, CELL_PENDING, false) == SM_PORTAL;
    // no cell this map can show: back at the entrance
    assert ship_mode(false, true, CELL_NONE, false) == SM_PARK;
    // gone from the feed: home, whatever it was
    assert ship_mode(false, true, CELL_PLACED, true) == SM_HOME;
    assert ship_mode(true, false, CELL_NONE, true) == SM_HOME;
}

test a_ship_leaves_by_flying_home {
    assert ship_kept(0) == true;
    assert ship_kept(DEPART_MS - 1) == true;
    assert ship_kept(DEPART_MS) == false;
    assert ship_alpha(false, 0) == 1000;
    assert ship_alpha(false, 99999) == 1000;
    assert ship_alpha(true, 0) == 1000;
    assert ship_alpha(true, 1200) == 500;
    assert ship_alpha(true, DEPART_MS - 1) == 1;
    assert ship_alpha(true, DEPART_MS) == 0;
    assert ship_alpha(true, 4000000000) == 0;
}

test an_event_lights_its_cell {
    assert cell_effect(0, false) == FX_START;
    assert cell_effect(1, true) == FX_NONE;
    assert cell_effect(2, false) == FX_NONE;
    assert cell_effect(3, false) == FX_LOST;
    assert cell_effect(4, true) == FX_NONE;
    assert cell_effect(5, true) == FX_ACCEPT;
    assert cell_effect(5, false) == FX_SEND_BACK;
    assert cell_effect(6, true) == FX_NONE;
    assert cell_effect(7, false) == FX_CANCEL;
    assert cell_effect(8, false) == FX_NONE;
    assert cell_effect(9, true) == FX_NONE;
    // only a review reads the verdict
    assert cell_effect(3, true) == FX_LOST;
    assert cell_effect(HIVE_KINDS, true) == FX_NONE;
}

test a_flash_fades {
    assert flash_alpha(0) == 1000;
    assert flash_alpha(900) == 500;
    assert flash_alpha(FLASH_MS - 1) == 1;
    assert flash_alpha(FLASH_MS) == 0;
    assert flash_alpha(4000000000) == 0;
}

test the_map_grows_in_batches {
    assert cells_due(0, false, 0) == false;
    assert cells_due(0, true, 99999) == false;
    // the first answer places every cell at once
    assert cells_due(3, false, 0) == true;
    // after that, one batch a period
    assert cells_due(1, true, CELL_BATCH_SECONDS - 1) == false;
    assert cells_due(1, true, CELL_BATCH_SECONDS) == true;
}

invariant one_row_per_kind {
    assert HIVE_KINDS == 10;
    assert FX_OF_KIND[5] == FX_ACCEPT;
    assert FLASH_MS < DEPART_MS * 2;
    assert CELL_BATCH_SECONDS == 300;
}

Open the lesson's spec in the player ↗

All lessons