Repository navigation
Releases
v0.0.1-alpha.20
For the operator: no migration and no new setting.
Added
- After an answer in the DM's day, Telegram asks whether maply may message
the player. Someone who came from a group or a friend's link and never
pressed Start got no morning post and no evening result in the DM; a yes
brings both back. Asked once a week at most until allowed.
Changed
- The map tells more before you zoom in: borders of states, provinces and
oblasts as a dotted line, the larger regions' names, capitals and the
biggest cities with a dot, and the big rivers, from the flat map on.
Finding a US state no longer takes zooming in to the cities.
Fixed
- Crimea is drawn as part of Ukraine, as scoring always counted it. The
map's tiles drew Russia's claim as a country border across the isthmus;
it is now a region's border, and Russia's name for the region is not shown. - The panorama's wheel zooms without coasting, and double-click zoom stays
under the pointer instead of jumping to the centre, in the day's game and
in past days (#91 by megatocha).
Container image
ghcr.io/freshlabdev/maply@sha256:3060754b98d99246bc02ec531d120ced597be1b40db1b7b98646973785a4bacc
v0.0.1-alpha.19
For the operator: three migrations. 028 sets aside the days nobody
answered: on production it puts back days #6 to #9 (28 to 31 October), their
places return to the pool. 029 creates the profiles' usernames; at start
maply gives one to every player it already knows. 030 lets a party play a
streak, a game against the clock or a day from the archive.
Added
- Every player has one profile address,
/u/<username>, and a Share
button. The username is Telegram's when it is free, or one maply makes up
from the name; a player can type their own, and the old address leads to
the new one until someone takes the name. - Edit profile: a name and a photo of one's own show over Telegram's
everywhere in maply, the bot's posts and pictures too, until removed.
The photo is dragged and zoomed into a square in the app. - An account that signs in with Google alone is asked once for a name, a
username and a photo. - Rating, the first tab of the leaderboards: the daily game over the days
that are over everywhere. Over 30 days it counts a player's best 20, so a
missed day costs nothing; over 7 days and all time every day counts. Four
cards name the most active, the most accurate, the best day and the
longest streak. Leagues go by the average day from five days played:
Newcomer, Tourist, Traveler, Navigator, Cartographer. The table filters by
period, by circle (the world, your groups, the people you played with), by
league, and sorts by points, average, days or accuracy. - A day nobody answered is set aside: the site and the days list do not
show it, its answer is never revealed, and its place comes back after 30
days at the earliest. The group's morning post is edited to say nobody
answered, and no result is posted. - Streaks, games against the clock and days from the archive can be played
with friends. A streak with friends goes on until one player is left; the
clock's game shows how far each player is. The host can change the mode in
the lobby. - After every place a party shows everyone's pin, distance, points and
whether they got the country, and a final table at the end. - The profile shows your time zone: a dial with the time there, under your
username and in the settings. The list of zones gives each one's time now,
and when the phone keeps another zone's clock, a button sets that one.
The DM's posts and the site go by it; the bot's picker still works.
Changed
- A tap on a name opens the player's full profile: numbers, charts, pins
and history of the days over everywhere, without answer times. "Hide me"
closes it to everyone else, the player's groups included. - A site visitor who is not signed in sees no photos, and no link preview
carries one. - The public link
/p/…is gone: old links lead to the owner's profile.
The privacy page says what the profile shows, in all 16 languages. - The game picker shows the first three of all time on the chosen settings,
not of the last seven days. The leaderboards page keeps both periods. - The free play's boards move to the second tab of the leaderboards; free
play does not count towards the rating. - "With friends" keeps the mode and settings picked for the solo game.
- Leaving a game under way asks first: a timed game, a party and a
challenge. In Telegram closing the app mid-game asks too. - A day set aside does not break a streak.
Fixed
- In a DM and on the site the world's table and the world picture showed
dots instead of names until 06:00 Kyiv, when the day had closed in every
zone. Names now open at your own 20:00, for everyone whose groups have
had their 20:00 too; a player in a group that is still guessing stays
unnamed until that group's result. - The final job of a day is tried again when keeping the day fails, and at
start and every hour maply keeps the days over everywhere that were missed. - An account that holds two answers of one day, a Telegram one and a guest's
it took in after the day was over, is "you" on one row only: the earlier
answer, the one the days page shows. The day's page and the site's result
take its pin and numbers from that row; the other answer stays as everyone
sees it.
Container image
ghcr.io/freshlabdev/maply@sha256:f673722c06dc166588f64b3b39ce2801764363f8d816c86210f653d6a624d78f
v0.0.1-alpha.18
For the operator: migration 027 gives each kept photo an address; it runs by
itself at start and takes a moment.
Changed
- Players are shown the same way on every screen: the day's and the world's
tables, the days page, the leaderboards, the profiles and the games with
friends take the name, the photo and "Anonymous" from one place on the
server and draw the face one way. Telegram photos now show in a party
too: the lobby, the tables, the row of who has answered and the pins on
the map. - A photo is sent as a short link that the browser keeps, not inside every
answer: the result's polls are smaller and a face loads once.
Fixed
- Someone else's public profile showed the viewer's own photo on its card.
Container image
ghcr.io/freshlabdev/maply@sha256:617c4ffa329b034d24d44e3d46d8414279e3cad1d760735bb5fc650460a98f5d
v0.0.1-alpha.17
For the operator: no migrations and no new settings; the image replaces
alpha.16 as it is.
Added
- The site has an icon in the browser's tab and on a phone's home screen:
the bot's globe drawn flat, with the pin large enough to read at 16 px.
The privacy page has it too, and /favicon.ico answers.
Changed
- A Telegram player's photo is shown wherever their name is: the day's
table and the world's in the Mini App, the site's result, the days page,
the leaderboards and the mini profile, to anyone, not only inside a group
both are in. A player who hid themselves stays "Anonymous" with a plain
face, and before the chat's reveal the other rows still have neither name
nor photo. - Your own face is your Telegram photo: the profile button in the header,
your profile and your rows, in the Mini App and on the site signed in
with Telegram. It is asked of Telegram when the app opens, at most once a
day, so a new photo shows the next day. - Photos stay current: a page shows the kept ones at once and asks
Telegram in the background for the ones missing or a day old. Names were
already read from Telegram on every visit.
Fixed
- A double tap on the panorama zooms on a phone. The phone's browser sends
a mousedown of its own after the tap, and the panorama stopped the zoom
it had just started on it, at once or after a few degrees. A double click
with a mouse always worked.
Container image
ghcr.io/freshlabdev/maply@sha256:b3ddf1e4463802a80614881e1606476af65a750256514a53468db13a0fa97f16
v0.0.1-alpha.16
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/_SECRETandGOOGLE_CLIENT_ID/_SECRET, and
APP_URL;docs/sign-in.mdlists 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 isdailyfor every place already kept. - Free play needs its own pool. Load the free places after the deploy, when
019 has addedplace.pool, and put their pictures in the stack's image
directory first: a batch'splaces.sqlwithpool = 'free'and its
upload/folder. A rerun ofplaces.sqladds nothing. Until it is loaded,
free play draws only from closed days. - Migration 017 adds
place.thumb_yawand the tableday_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-yawswrites
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 onsite_guess (player, date)for a guest's profile. - Migration 020 adds
free_archive,free_challengeandfree_attempt, and
replaces the checks onfree_gameandfree_resultwith 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.TouchPersonrecords 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.Touchwould 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 freewritespool = 'free', no facts and one city name, the English one
where OSM has it.-avoidandMAPLY_AVOIDkeep 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.pydrops 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.pyturns the
reviewers' verdicts intoreviews.jsonwith 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.pygives 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 reviewchoose.py
reads.harvest.pypasses over a soft panorama, or one under 2048 px wide, for
another frame of the tile.
pool.pyplans in more countries, with rules for their troubled borders,
andMAPLY_CAPlimits the entries a country gets.maply-placeswritessharpen.csv, the input of-sharpen, next to
places.sql.maply-placesrefuses a batch whosereviews.jsonwas chosen for the
other pool,-pool freewithout-avoid, and an-avoidfile 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_resultexists. 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./daysopens 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/startopen
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 ...
v0.0.1-alpha.15
Fixes from a review of the whole project on 5 November: security, the
scheduler and the bot, the server's logic, the animations and the Mini App.
For the operator:
- Apply core migration 020 (
core.manual_language) before deploying. The
service now refuses to start without it and names the migration; before,
every launch of the Mini App from a group would have failed. - Migrations 014 to 016:
day_rankputs site answers after Telegram ones,
two partial indexes for unscored answers, and the tablesday_closedand
day_place, filled at once with every day already over. - The new
deploy/ws04/compose.yamlgoes to the host: the bot's container
is read-only with a 512 MB/tmp, without capabilities, limited to 2 GB
and 512 processes, and getsstop_grace_period: 90s. /healthzno longer answers through the Cloudflare tunnel; Docker and the
family's containers still reach it.
Security
- Every site answer ranks after every Telegram answer. A Telegram player sees
the place on answering, from the 07:00 post on, and every new browser is a
new site player: someone could answer at random in Telegram, then post
exact pins from fresh browsers and take the world's first place. - A result poll with a made-up
sinceshowed the place without tying the
person to the chat. They could then answer from a group whose reveal was
hours later. The tie now happens whatever the poll sends. - Per-address limits count an IPv6 address by its /64, the site's writes
share a cap of 120 a minute from everyone, and a name typed before any
answer no longer creates a site player. - A forged button press could delete the group's afternoon intrigue or a post
sent as text. maply acts only on a button the message really carries. - The app may be framed only by Telegram's web clients; the site sends HSTS,
API replies say nosniff, and two log lines no longer tie a Telegram id to a
time zone. Both Docker base images are pinned by digest. - Correction to alpha.14: a row's key differs per chat, but the rank and the
distance are the same in every view, so they still match one person's rows
for anyone who looks at a group and a DM at once.
Changed
- Opened from a group, the Mini App speaks the language the person picked by
hand in any bot of the family, such as Ukrainian chosen in vido, rather than
the group's. A group's language used to win for everyone in it, so a player
who had picked their own read the screen in the language another bot had
detected for the group. The Telegram app's language does not count as a
pick, so a group still reads as one for everyone who has not chosen. What a
player shares from the app stays in the group's language, like the bot's
posts and the card there. - A group that does not let maply send pictures still plays: the post and the
result go out as text with the same button. - In a forum,
/startanswers in its topic, not in General. An admin who
writes anonymously can open the group's settings, and any admin may press
that panel. - The morning animation is kept for two dates at once, since the east posts
the next day while the west still posts today, and one chat that forbids
animations no longer turns them off for every chat that day.
Fixed
- In a supergroup every poll of the result screen after the first load got a
server error since alpha.14, so the live table stopped updating. The query
that answers "nothing changed" typed the chat id as a 32-bit number, and a
supergroup's id does not fit. The API's integration tests now use real
supergroup ids. - A deploy around 20:00 could send a group its result twice: the stop cut off
the send in flight. The job in flight now finishes, and jobs taken but not
started go back to the queue. - An animation with its buttons went out in two requests, and a failed second
one sent the whole message again. They go in one. - A group upgraded to a supergroup lost maply. The supergroup now takes the
group's zone, post time, switches and the language picked in maply. - A group whose admin restricted maply (no GIFs, say) was marked as left.
- A person who opened the Mini App from a shared result but never started the
bot got a failed post every morning, retried five times. Their DM is now
left until they write to maply. - A group that removed maply and added it back the same morning, or a person
who blocked and unblocked it, got nothing that day. The post goes out on
the return. - Moving a chat's zone a date east before its reveal sent tomorrow's post
before today's result. Such a change waits until after the result. - The closed day's world line could stay "for now" for good when Telegram
failed that one edit, and was dropped when it did not fit the caption. A
failed edit is tried again, and the line names fewer people until it fits. - A query that broke the post's "who answered" line did it silently; it is
logged now, once per chat and error. Pressing the setting a panel already
shows is no longer logged as a failure. - Four reads took any database error for "nothing there", which repeated
yesterday's intrigue or shared the card instead of the animation. - The time the world closes names its zone.
- Animations: pins land before the podium with many players, chips show the
top 12, long names on the podium end in "…", an emoji with a skin tone or
a keycap after a letter is drawn from the emoji font, and a site winner in
Chinese, Japanese or Arabic reads "Guest", not "?". - An encoding gives up after 3 minutes instead of holding every post behind a
stalled ffmpeg, at most two encode at once, and ffmpeg's own message is
logged when it dies. A panic in one statistics picture costs that picture. - Statistics in Tokyo or Sydney show this morning's answer before UTC
midnight. The result card joins Tokyo and California across the Pacific. - Mini App: the loading screen no longer waits forever for the photo, a
failed start can be retried, the map recovers from a failed tile request,
lifting two fingers after a pinch no longer undoes the zoom, the countdown
follows the server's clock, sideways the panels start folded, and the days
sheet, the keyboard and screen readers behave.
Performance
- A result poll keeps the place it has read, finds unscored answers through
an index, and an open day's ranking and pins are read once per new answer
for every poll that counted the same. alpha.14 said an unchanged poll was
worked out before any table is read; it was not, and now it is cheap. - A day over in every zone keeps its places, so the profile and the days
page no longer rank every day there has been. - The days page keeps a closed day's place and ranking for ten minutes, and a
day's ranking sends at most 500 rows plus your own. - The place's picture is served as
.jpg, which Cloudflare caches, with a
per-address limit. - Statistics pictures are drawn ahead only for players who opened them in the
last week and leave the disk after 6 hours; the shaped-text cache is capped;
the afternoon intrigue is drawn once per picture and sent by file id.
Container image
ghcr.io/freshlabdev/maply@sha256:a0d8c7bee4f411cb9fa8ca9332251ad7c3cf1d12235dc15565d1733aa79adf2d
v0.0.1-alpha.14
Fixes from two reviews on 4 November: one name could take the whole
service down, several paths let a player see the place and still answer,
the world's names came out too early, and the site showed an
empty table to players who had answered. The Mini App and the texts changed
too.
For the operator:
- Migration 013 adds
chat_settings.zone_autoandleft_at,
chat_round.result_textandresult_world,site_guess.late, three
columns at the end of theday_scoreview and a new viewday_rank. - The deploy also needs the new
deploy/ws04/compose.yamlon the host: logs
move to the host's journal. - Rolling back to alpha.13 works on the migrated database. One difference:
alpha.13 does not knowzone_auto, so a DM zone stored automatically
counts there as picked by hand, and the phone's zone no longer replaces it.
Fixed
- A name starting with a skin tone, a joiner or a variation selector crashed
the whole service, bot, scheduler and API, every minute while profiles
were drawn. Such names are drawn now, and a panic while drawing, in a
request or in a job costs that one picture, request or job. - Moving a chat's zone west in the middle of the day could send the place
while answers in the new zone were still open. The result job checks the
reveal in the chat's current zone and moves itself to it. - A DM without a picked zone followed the language, so switching the
language after a group's reveal could reopen the day. The zone is stored
the first time it is used; the phone's zone may still replace it once. - The site told players who had answered that they had not: its world table
was empty. The table is filled, a guest without a name reads "Guest", and
an answer kept only in the browser shows as your row without a rank. - When the answer window closed on a pin that was placed but not sent, the
app said "Answer accepted". It now says answers are closed and removes the
pin. - In the world table every group's names opened at your chat's reveal.
Now only your group's do; everyone else's open when the day is over in
every zone. - The pin jumped to the top corner of the map for a moment when dropped.
- The mini globe grew with the pin's latitude: 1.4 times for Romania, almost
3 times for Tromsø. - The place and your pin could end up under the table. The camera follows
when the table grows; on short screens the margins shrink together and the
place card starts folded. The opening frame covers the place, your pin and
the answers near them, not every answer in the world. - Telegram asked whether to discard changes when closing the result screen.
- One hung request stopped the live table until the app was reopened.
Requests give up after 10 seconds; a server that keeps failing shows one
message and is asked less and less often, up to once a minute. - "Everyone answered, the pins are 0 km apart" came with one answer.
- The morning edit of a group's result rebuilt the whole caption with that
morning's members and language. It changes the world line only. - In UTC+3 in winter the morning look back at yesterday could come before
the last answers were scored. - A failing edit of the pinned post was retried every 5 seconds until the
evening. It backs off, waits as long as Telegram asks, and leaves a
deleted post alone. - A long fact could push the result caption over Telegram's limit.
- Two answers on the same spot made one marker.
- The bar tooltip stayed over someone else's row after a new answer moved
the table, "N more" counted five rows when the table was folded to one,
and the fold button showed when you had no row. - The site wrote "at 06:30, " with nothing after the comma for a browser in
a zone maply does not name. - A group that removed maply after its reveal stopped counting for its
members that day, so they could answer from a DM in a later zone after
seeing the place. Such a group now closes their day as before; one removed
before its reveal does not. - Someone who opened a group's result without answering could still answer
from a DM in a later zone. Opening a result now counts as being in that
group. - A site answer sent after the first reveal of the day, when the place was
already out in Telegram, could take first place in the world. It is still
scored, but it cannot be first. - The world picture in a group's result named the world's top three and
showed their faces before the day was over everywhere. Until then the
podium shows distances only. - Someone Telegram had restricted and who then left a group still counted
as its member. A refused membership check is kept for a minute, so a person
who has just joined gets in quickly. - A DM whose own day had ended at midnight lost the result of the day one of
the person's groups was still playing. The open app keeps its day. - Your place on the profile and in the world could differ on equal points:
the two broke ties in different orders. - For a place near the 180th meridian the line from your pin and the opening
frame went the long way round the world. - After a tap on a group of markers, the next update flew the map back.
- A reply cut off in the middle was taken as a result; it now counts as a
failed request and is asked again. Coming back to the app asks at once,
even after a run of failures. - A long tooltip over the bars ran off a narrow screen; it wraps now.
- A slow reply in the days sheet could replace a day opened after it.
- The days sheet did not take the focus. It does now, Escape closes it, and
the focus goes back to where it was; the folded answer button is out of
the tab order. - A database error while reading a chat's zone was taken for "no zone", and
one chat whose zone could not be stored stopped the day's planning for
every chat.
Changed
- Posts, teases, the home panel and the reply to a sent location name the
zone: "Results at 20:00 (Kyiv)". - A group's first post has two lines of rules in place of the look back at
yesterday. When maply may not pin, the request goes to the admins inside
that post instead of a fourth message. - The world place reads "so far" until the day is over in every zone.
- Numbers in the Mini App follow the language, as in the bot ("3,500" in
English, "3 500" in Russian and Polish); distances under a kilometre are in
metres. Arabic keeps Western digits in the bot and the app, as its places
and times already had. - In Arabic the Mini App reads right to left: the table, the plates over
the map and the arrows are mirrored. - Long button labels take two lines instead of losing their end.
- The name column in the table grows with the screen.
- Your own face shows your initial instead of repeating "you".
- The sheet with every answer opens on your row, marks where ranks skip,
and says "Top 200 of 1,229" when that is all it has. - The (i) card explains the group mark and points at its button.
- Markers on the back of the globe hide; long names on the map are cut.
- New texts for a server that is down, a server error, a bad request and a
group maply has left. Reworded: no photo today, the zone change refusal,
the DM settings hint, the world tease (it says "worldwide" now), the empty
waiting tease, the first toast after a pin, the rules in Chinese. The line
about your group under a DM result ("In “Team”: place 2 of 5") says
"place" in nine more languages, and Belarusian was read against Russian. - The bot's log goes to the host's journal and survives deploys.
- After the reveal, the result in the Mini App asks once a minute until the
day has closed everywhere, so the world's names appear without reopening
the app.
Security
- Bot posts call a site player "Guest": a name typed on the site is not
checked and could have said anything. - The site's endpoints that write take only JSON from maply's own pages, so
another site cannot post an answer or a name for a visitor. - A row's key depends on the chat it is shown in, so one person's rows cannot
be matched between a group, a DM and the site. - The client error log drops query strings, which could carry the Telegram
launch data, and takes at most 5 reports a minute from one address and 30
in all.
Performance
- A poll sends the version it has; when nothing changed the answer is a few
bytes, worked out from two counts before any table is read. Polls no
longer write to the shared core database. - The table draws only the rows that show, markers are not laid out while
the photo is in front, and the compass tape is rebuilt only when the
width changes.
Container image
ghcr.io/freshlabdev/maply@sha256:ef5d35a06b95a758733f6df8c2d9ccb778017ddf49cf10198a3a15d55339c7b5
v0.0.1-alpha.13
The table under the result is the day's world ranking, in a group and in a
DM, with a small mark on the group's own players. It folds to your own row,
and how the points add up sits behind a small (i). Migration 012 adds the
speed bonus to the day's ranking view; no table changes.
Changed
- The table under the map is the world's, in a group and in a DM alike:
every answer scored so far today, numbered by world place. The group's
own players carry a small group mark by the face; their answers are still
the ones on the map. Points include the speed bonus for everyone, so the
order matches the world place. - The table folds to your own row and remembers that. How the points add up
is a small (i) that opens a card over the map instead of pushing the table
down.
Fixed
- In your own row the empty rest of the bar no longer blends into the
highlighted band, so the bar reads as a whole.
Container image
ghcr.io/freshlabdev/maply@sha256:cb28816151fc9bcb4065e5553216af4fa65f578827f777e7a7f779997fd29849
v0.0.1-alpha.12
Group posts read more clearly: the pin lists every distance, the 20:00
result sets the world places apart, and the morning look back is a heading
and one fact a line. The result table shows the top five with every
player's bonuses, opens in full in its own window, and close answers group
on the map. The result animation names every pin and turns the globe to
answers on the far side. A DM time zone change can no longer reopen a day
already seen.
Changed
- Zooming the map stops where the hand stops. The app no longer finishes a
gesture on its own toward the globe or the flat map, and a pinch has no
zoom inertia. Far out, a wheel click or a trackpad swipe covers more zoom
than up close, so getting from the globe to a city takes fewer moves. - A shared result puts the distance and the points on lines of their own, in
bold, with labels, so neither is read as the other. - The Mini App opened from a group speaks the group's language, the one the
bot posts there in, instead of the language of the player's Telegram app.
What a player shares from it is in that language too. - The place plate on the result opens with the fact. Its button folds it
into a small tab and back; the step that showed the name without the fact
is gone. - World lines say "Place in the world: 3 of 120" instead of "Worldwide so
far", and the group's line puts the total first so it reads for everyone
in the list. The world's first place says "worldwide". - The group's pinned post lists every distance so far, closest first, not
only the best three, and catches up with new answers within about 20
seconds instead of a minute or more. - The group's 20:00 result sets the world apart: a bold heading with the
number of players, the members' places on the next line, and the world's
first place on a line of its own. Points in the table are bold. - The morning look back is a heading and one fact a line. A group no longer
gets its members' world places there, since its result already has them. - A DM's result shows the distance and the points on lines of their own,
like a shared result. - On equal points the closer pin ranks first, then the earlier answer, in
the group's table, the live table and the world ranking alike. Before,
the earlier answer came first in the world and the table could put a
closer pin below a farther one. - The result table under the map shows the top five, yours always among
them, and "N more" opens every answer in a window of its own, which keeps
up with new answers while it is open. Your row stands out on a lighter
band with bigger points; everyone else's bar shows the bonuses they
earned in muted colours, and the first three places are coloured. - On the map, answers too close to tell apart group into one marker: the
best of them with a count. A tap zooms in until the group comes apart. - The others' markers stay put when an answer comes in: a new answer adds
its own, and at the reveal the names fill the same markers. Before, every
new answer rebuilt them all, which made them flicker and could cut off a
pinch that started on one. - The colour legend and the "what if" line under the table moved behind an
(i) button: it explains the points for the distance, each bonus and the
speed bonus, and what the same distance would have made with more
bonuses. - The live plate shows only the place in the world; the "names at 20:00"
line with the blinking square is gone, since the header already counts
down to the names. - The result animation: every pin has a chip with the name and the distance,
and chips move to another side of their pin rather than cover each other.
When the group is spread over the world, the view centres on the place, a
pin round the globe stands where its line goes over the edge, and the
globe turns east and west to show those pins where they are. - Russian, Ukrainian and English texts were gone over: the bot's
description, the home message and the help said the place shows at 20:00,
when it shows right after the answer (fixed in every language); one word
for a miss, the world place said as such, Ukrainian compass letters that
no longer read as Russian, and plurals that agree with any number.
Fixed
- The map could stop working after "Walk there" on some phones: a frame
stamped slightly before the animation's start turned the camera's padding
negative, and MapLibre threw on every frame after that. - Errors inside Telegram's own script, which the browser reports only as
"Script error.", are no longer sent to the server log. - Changing a DM's time zone, from the settings or from the phone, could
move the day back before its reveal for somebody who had already seen the
place, and let them answer again. A zone that would reopen the day now
waits until tomorrow. - The others' points in the live table no longer include the speed bonus,
which gave away when they answered. - A pinch on the map no longer resets when Telegram resizes the view: the
camera waits until the finger is up and the map stands still. - An app reopened after answering no longer lets a tap move the sent pin
while the result loads, retries the result if it failed, and polls only
while Telegram shows the app. - A group result sent after the day closed everywhere carries the final
world line itself. - Long names no longer push the pinned post past Telegram's caption limit,
and yesterday's lines give way first. - The world's sample pins come in a fixed order rather than by answer time.
- /api/log takes only JSON, has a global limit as well as one per address,
and drops empty reports. - Sharing before the reveal scores a location answer first, so the line has
its points. - Toasts are announced by screen readers; unnamed rows and the collapse
button say what they are.
Container image
ghcr.io/freshlabdev/maply@sha256:d2a50eeb195943e74dd7e768c6329d9713ba8de022693cd7973ad4a477424e32
v0.0.1-alpha.11
Players in Telegram see the place and their score as soon as they answer,
and watch the group's other answers come in without names until 20:00.
Operators: no migration and nothing to do on deploy.
Breaking
- The anti-cheat rule changed: in Telegram an answer is scored the moment it
comes in, andPOST /api/guessreturns the result instead of
{"status":"accepted"}. Before the chat's reveal,/api/resultgives the
others' answers only as distance, score and a point, with no name, photo,
ID, bonus, speed or answer time, and answers403 not_answeredto anyone
who has not answered. The site still waits for the latest reveal and shows
no one else's answers before it.
Added
- The live screen after answering: the place, the person's distance and
score, the group's answers as unnamed rows and map points, their place in
the world so far and everyone's answers as grey dots. It refreshes every
five seconds while open, a new answer slides in, and the names appear at
the chat's reveal without reopening the app. - Sharing before the reveal sends a text line with the day, distance and
score, without the picture of the place. - The group's 20:00 result carries the members' places in the world so far.
When the day closes everywhere, the bot edits that line into the final
places and who came first in the world. The edit is not a new message. - A DM without a chosen zone takes the phone's zone, matched to the closest
zone in the picker with the same clock all year (Paris to Berlin, Riga to
Kyiv). A zone the person picked is never overwritten. - Errors in the Mini App are reported to the server log through
POST /api/log, at most five per session, without the launch data.
Changed
- The pinned post is laid out in blocks: who answered, in alphabetical order
so the names cannot be matched to the live rows, the three best distances
so far without names, and yesterday's summary in a quote. - The result table gives medals to the first three.
Fixed
- Changing the time zone in the middle of the day could open the result
before the answers were scored and show 0 points. - Emoji in names are drawn in the animations instead of a question mark, and
an avatar without a photo shows the whole emoji, flags included. - A long name no longer wraps onto a second line in the Mini App's result
table.
Container image
ghcr.io/freshlabdev/maply@sha256:86775eae7c1bb86c8b6bcb8485d19c9d8080003781403cd3a5a029cce34817c1