Skip to content

v0.0.1-alpha.16

Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 06 Nov 12:24
· 39 commits to main since this release

For the operator:

  • Apply core migration 021 (core.touch_person) before deploying. The
    service refuses to start without it and names the migration.
  • Sign-in on the site needs keys from BotFather and Google Cloud, set as
    TELEGRAM_LOGIN_CLIENT_ID/_SECRET and GOOGLE_CLIENT_ID/_SECRET, and
    APP_URL; docs/sign-in.md lists the steps. Without them the site plays
    as before and its sign-in buttons are greyed out.
  • Migration 018 adds the site's accounts (account, session,
    link_ticket, site_player.account_id). Migration 019 adds free play
    (free_game, free_member, free_round, free_guess, free_result) and
    place.pool, which is daily for every place already kept.
  • Free play needs its own pool. Load the free places after the deploy, when
    019 has added place.pool, and put their pictures in the stack's image
    directory first: a batch's places.sql with pool = 'free' and its
    upload/ folder. A rerun of places.sql adds nothing. Until it is loaded,
    free play draws only from closed days.
  • Migration 017 adds place.thumb_yaw and the table day_thumb. After the
    deploy the service draws a strip for every day already kept, one at a
    time, in the background.
  • For the places already in the queue, maply-places -thumb-yaws writes
    thumb-yaws.sql, which sets the strip's direction only where none is set,
    with each strip beside it to look at first. It is optional: without it the
    service picks the direction itself when it draws the strip.
  • Migration 021 adds profile_setting (hide me, the public link) and an
    index on site_guess (player, date) for a guest's profile.
  • Migration 020 adds free_archive, free_challenge and free_attempt, and
    replaces the checks on free_game and free_result with named ones that
    allow the new modes. It runs in one transaction on tables the service
    already writes; nothing to do before or after.
  • Migration 024 lets a free game's result and a challenge's attempt belong
    to a site player as well as to a Telegram person (free_result.player,
    free_attempt.player), and adds the index the free game's leaderboards
    read. Nothing to do before or after.
  • Migration 026 only replaces the function of the trigger that keeps a
    place's pool, so a place any round names stays the day's; it reads and
    writes no row.

Added

  • Store.TouchPerson records a person in core without a chat or presence,
    for a person met outside the bot's chats: a website sign-in with Telegram
    or a guest who joins a game with friends from a link. Touch would count
    them as talking to maply in a DM, which closes their answer window by the
    DM's zone and puts them on the morning DM post.

  • The curation scripts prepare the free game's pool. maply-places -pool free writes pool = 'free', no facts and one city name, the English one
    where OSM has it. -avoid and MAPLY_AVOID keep a batch 10 km from every
    place and candidate of the other pool, so a free place never becomes a
    place of the day and the free game never shows the spot of a future one.

  • scripts/curation/screen.py drops frames near or inside an OSM military
    area and in the parts of a country left out, and draws review sheets of the
    whole panorama instead of the 120° the game opens on. choose.py turns the
    reviewers' verdicts into reviews.json with at most 15 places a country
    and 500 in all, counted over every batch it is given, and writes a report
    of them.

  • scripts/curation/faces.py gives every prepared place a sheet for faces
    alone, at twice the detail of the review sheets, close to what the game
    shows after -sharpen, and turns the verdicts into a review choose.py
    reads.

  • harvest.py passes over a soft panorama, or one under 2048 px wide, for
    another frame of the tile.
    pool.py plans in more countries, with rules for their troubled borders,
    and MAPLY_CAP limits the entries a country gets.

  • maply-places writes sharpen.csv, the input of -sharpen, next to
    places.sql.

  • maply-places refuses a batch whose reviews.json was chosen for the
    other pool, -pool free without -avoid, and an -avoid file it reads no
    place from, so a slip of a flag cannot put free places in the queue of days
    or leave the pools free to overlap. The scripts refuse such a file too and
    say how many places they keep clear of.

  • The player's profile in the Mini App, behind the name's letter at the end of
    the header and at /me: points, the 30-day average, streaks, the typical
    miss, the share of countries and cities found, the best day and world place,
    and the average percentile over the days that are over everywhere, in tiles
    that fill their rows at every width, the month's season among them. Three
    charts drawn in SVG (points over 30 days with the median, misses by
    distance, continents), the passport: one map of the world with the
    countries found in gold and one's own pins over them, a pin opening its
    closed day, then the history by day and the free play numbers once
    free_result exists. A site guest gets the same from the cookie,
    closed days only, with a note to sign in.

  • A tap on a name in the world's tables opens a mini profile: days, streak,
    the 30-day average, best world place, countries, and from free play the
    average per place and duels. Inside a shared group it adds the photo and
    "closer than you on 14 of 22 shared days", counted over the days that
    group has seen the result of. Names carry an opaque handle, never an id.

  • "Hide me" in the profile: for everyone outside the person's own groups
    the world's tables, the site's result, the days page, the free play's
    leaderboards and the bot's world lines show "Anonymous" with a plain
    avatar instead of the name and photo, and the mini profile does not
    open. The person's groups keep the name.

  • The month's season: the sum of a player's 20 best days. The 07:00 post of
    the 1st names the champion inside yesterday's look back, a group's own in
    a group and the world's in a DM with the person's place; no new message.
    The profile shows the place in the month so far, in the world and in the
    group it was opened from.

  • A public link to the profile, off until the player turns it on: /p/…
    opens their numbers over the days over everywhere for anyone with the
    link, without pins, history or photo, and asks search engines to stay
    away. "New link" ends the old one, and "Hide me" closes the page while
    it is on. The link's preview is the profile picture without the pins.

  • The profile on the site follows the account. Signed in with Telegram it
    is the Telegram player's, with every day, the season and the settings, as
    in the bot; with Google alone it holds the account's site days from every
    browser it has taken in, one answer a day. A Telegram player's profile
    also counts the days their account's guest played on the site before the
    sign-in, where there is no Telegram answer, once the day is over
    everywhere and only an answer given before the day's first reveal. The site's header keeps one
    button: the account's menu opens the profile, and a guest's sign-in
    dialog has "My profile without signing in".

  • In Telegram, Back goes to the page before, as it does in a browser: a day
    opened from the profile comes back to the profile, where it was.

  • Leaderboards of free play (GET /api/top, web/app/leaders.js): Country
    streak, Against the clock, Blitz and Classic, a table for each timer and
    length, over the last 7 days or all time. One row a player with their
    best, and an equal result ranks whoever reached it first. Only games with
    a timer count, and not an attempt at a challenge, whose places the friend
    who made it could have told. Names, "Hide me" and the mini profile work
    as in the world's tables. An account with Google alone has a row of its
    own under its site name; an account with Telegram is its person, the
    games its site players finished before the link included. The profile's
    free play tab shows the player's place on each board they are on and
    opens that board, and it counts the same games: a site account without
    Telegram now has the tab too. On a phone in a browser the page has its own
    Back before the title, to the page before or to the menu; in Telegram Back
    is Telegram's, and a computer has the header. Each row has a face, as in
    the day's table: the letter, or the Telegram photo when the Mini App was
    opened from a group and the player is in it, as in the mini profile;
    "Anonymous" has the plain face and never a photo. The first three of the
    last 7 days on a mode's screen have the same faces.

  • The app's screens have addresses: the server answers /days, /days/<day>,
    /me, /play, /party/<code> and /p/<id> with the app, and the app opens
    the screen the address names. /days opens the days and /days/<n> (or
    the day's date) a closed day, so a day can be linked and Back in the browser closes it. An
    address without a screen shows the menu. In Telegram the address changes
    without adding history, so Back stays Telegram's.

  • A menu at /. The day comes first and largest, with its picture: Play,
    the answer sent and the clock to the result, or the player's own score and
    world place. Beside it are the free game's modes, Classic, Blitz, Country
    streak, Against the clock, the archive and With friends, in the day's
    green with "no place in the world" over them, and under them the days,
    the leaderboards and the profile. The day itself is at /today. A post's
    button opens the day as before; the bot's menu button and /start open
    the menu, and so does the logo. A phone gets the menu in one column.
    Each card but the day's carries its sign in the logo's halftone dots, in
    the field's light green: Classic the globe itself, a bolt, a flame, an
    hourglass, an archive box, two pins, a calendar, a cup and a person. Now
    and then one light runs over all of them at once, and a card lights its
    sign up under the pointer or the focus. The cards' arrows are gone.

  • Sign-in on the site with Telegram or Google, through our server by OpenID
    Connect with PKCE. Signed in with Telegram, the site is the bot's player:
    one answer a day across both, the DM's deadline with the speed bonus, the
    place right after answering and the names at the usual time. Signed in with
    Google, the site's game keeps its answers and name across browsers. The
    browser's guest answers join the account, after a question when the account
    already existed.

  • An accounts page: link and unlink Telegram and Google, sign out here or on
    every device, delete the account. Two accounts merge when one's sign-in is
    linked to the other; a closed day is never rewritten. A guest's answer
    that an account with Telegram takes in after the person's deadline stays
    a site row, marked late, and the bot takes no other answer that day. In
    the Mini App,
    linking Google opens the phone's browser with a five-minute ticket that
    names the Telegram account before going to Google; a Google that has an
    account of its own is linked from the site instead, so a ticket never
    merges.

  • /privacy says what maply keeps, what other players see and how to delete
    the account, in the sixteen languages: the day's game, free play and its
    leaderboards, "Hide me", games with friends and challenges, and the public
    link. To have the answers erased as well, it links the developer's
    Telegram.

  • The site's menu picks the interface language. Signed in with Telegram it is
    the language core keeps for every bot of the family, with "Follow
    Telegram"; otherwise the browser keeps it.

  • The days are a diary: every day back to the first, a month at a time, each
    with its strip of street, its flag and city, the world's numbers and the
    viewer's place, "no answer" on a day they skipped. A day still open
    somewhere shows its puzzle where the day has begun, how many have answered
    and when it closes, and nothing about its place. On a screen 1024 pixels
    wide or more the list and the day stand side by side.

  • A closed day's page, /days/<n>: the strip, the place, the author and the
    fact, the viewer's result, the world's four numbers, everyone's misses on
    one scale, the map of the pins and the table, with arrows to the days
    before and after.

  • A link to /days/<n> previews in a chat or a feed with a 1200×630 picture
    of the day's street, its place and numbers, drawn in the reader's language
    (in English for a script the faces lack). Only a day over in every zone
    and kept has one; the picture is served at /og/day/<n>-<lang>.jpg.

  • The country flags come from country-flag-icons 1.6.20, served by the
    service.

  • Free play, outside the day's ranking, at /play: from the menu and the
    DM's /start panel. Alone it is a Classic of 3, 5 or 10
    places on 60, 90 or 120 s or no timer, a Blitz on 30 s, or a Country streak
    on 30 or 60 s that goes on while the country is right. Each mode has its
    own screen, opened from its card in the menu: only its settings, on the
    last game's where they fit, the player's record and place on the
    settings' leaderboard, and the first three of the last 7 days. A game
    shows each place after the answer and ends with the record for those
    settings. Back goes one step up, and the settings, the archive and the
    lobby lead to the menu; in Telegram only Telegram's Back is shown. With friends, up to eight play the same places
    at once: the host sets the time and the number of places, the bot prepares
    an invitation the player sends to any chat, a ribbon shows who has
    answered, and the final offers a rematch on the same settings. The speed
    bonus, up to +200, counts the share of the time left, so it is the same on
    every timer. The bot writes nothing about free play in groups. A free
    place never becomes a day's place, and its picture goes out only once the
    place has started, under the round's own address. It looks as the day's
    game does: the same header, panorama and globe, with the place, its clock
    and the points where the day has its number and countdown. On the site any
    account keeps records and plays with friends, one with Telegram as the
    person and one with Google alone as its own player; a guest plays alone
    without records and is asked to sign in for them.

  • The app has a computer's layout. From 1024 px wide and 600 px high the
    panorama fills the screen and the map opens beside it as a panel, on hover, a
    click or M, in three sizes; after answering the map fills the screen and the
    score, the world's table and the buttons are in a sidebar. A header links
    Play (the menu), Days and Leaderboards, with the profile or Sign in at its
    end. The menu, the days, the profile and the leaderboards are pages up to
    1440 px wide, in columns where numbers and tables do not wrap. On a tablet
    the phone's layout gets a bigger globe and centred buttons. The phone's
    layout is unchanged apart from the menu.

  • Keys: the arrows or WASD turn the panorama, + and − zoom it, Space drops a pin
    on the focused map, Enter answers, Esc folds the map, ? lists the keys. Hints
    follow the pointer, so a mouse is no longer told to use a finger.

  • Telegram Desktop can switch the app to full screen from its header, and the
    computer's layout follows.

  • Free play gets three more ways to play. "Against the clock": three minutes
    for as many countries as one can find, with skipping and no speed bonus,
    and a record of its own. The archive: every day over in every zone, by the
    clock as well as by the final job's row, that the player has not answered
    or seen, one place each with no timer, and where the answer would have
    stood in that day's table. Each day says how many played it and the
    world's typical miss, as a target, and a day already played shows its
    points. A challenge: after a classic game on a timer,
    friends play its places in the same order in their own time, once each,
    and the challenge's table shows the sums and marks the places someone had
    seen before. A player there is the person with every site player their
    account holds: a day answered as a guest before signing in is answered,
    and a challenge taken before Telegram was linked is taken. Challenges
    need an account, as parties do; a site guest plays the archive.

Changed

  • The panorama and the globe moved out of the day's game into pano.js and
    globe.js, each with a small API that the free game and the profile can
    reuse. The game looks and behaves as before; a double click no longer zooms
    the panorama by itself.
  • The days page reads a page of thirty days in one query instead of about
    sixty, and pages back by a cursor to the first day.
  • A day's row no longer shows the group's numbers beside the world's.
  • A DM post's button opens /today. A post sent before this version opens
    the app at /, which is now the menu, one tap from the day, and so does
    the Play button under a forwarded result. In Telegram,
    Back on the page the app opened with goes to the menu, and the menu has
    none, so Telegram closes the app from there.
  • The free play card at the top of the days is gone: the menu leads there.
  • The days and the profile open in place, as the menu and the leaderboards
    do, instead of sliding up from the bottom over the day's game.
  • A page's back is one arrow instead of a cross. A step inside a page (a day
    to the list, a mini profile or the world's table to what it opened over)
    keeps it in a browser. The way out of the days, the profile or a public
    profile is not drawn on a computer, where the header leads out. In
    Telegram its own Back button does both, as in the free game, so a screen
    never has two ways back.
  • The day's clock and table in the header show on the day's screen only, no
    longer over the days, the profile, a mini profile or the world's table.

Fixed

  • A day takes only a 360° panorama. The queue let an approved flat photo
    become a day; prod had 42 of them, now rejected by hand.

  • The final world job keeps a day as over in every zone only once the
    latest reveal has passed, whenever the job runs. A job moved by hand or a
    clock that jumped would have put a day still in play into the free
    game's archive; it now goes back to the queue for its time.

  • maply-places wrote a heading of 359.96° as 360.0, which the schema
    refuses, and the whole places.sql failed to load. It is written as 0.0.

  • pool.py leaves out the west coast of Sinai and the Russian strip east of
    occupied Luhansk, which its rules let through, and a plan no longer dies
    or spins when every country is used up. screen.py checks a frame outside
    every outline by its plan's country instead of letting it pass.

  • The result's pin, target and the others' marks stood off their points, up
    to 40 px from the dashed line on a computer, after the map opened straight
    on a city. They are set again once the camera stops.

  • A click or a double click on the computer's map panel while it was opening
    left the globe small in the panel's corner. Once the camera stops, the
    globe comes back to the middle at its size, closer if the player zoomed in.

Security

  • The site took any zone the browser named. One east of every chat's, such
    as UTC+14, closed and scored a guest's answer before any chat's reveal. A
    zone outside the span of the zones a chat may pick now plays in the nearer
    of them: Honolulu in Los Angeles, Auckland in Sydney.
  • The guest's cookie is __Host-maply_player, which another site under the
    same parent domain cannot set. A browser that has the old maply_player
    keeps its guest and gets the new cookie on its next visit; after that an
    old one is ignored.

Container image

ghcr.io/freshlabdev/maply@sha256:be8cf20a64cd5a596b6e4f1b6d92d644c43feef3a74f41174874d4c419e3e345