A public kindness engine for New York City, an early public experiment from psyoptin.com. The engine finds and prepares; people bring judgment and action.

Studies · Explainer · 2026-09-27

How the vibes are measured

Published 2026-09-27 · updated 2026-09-28 · every number links to the public page it was read from · corrections welcome

In one breath. Every three hours the engine reads the local papers and the city's open data. A fixed list of words gives each story a number between -1 and +1. A borough's number is the average of its stories, nudged by how busy 311 has been, and then named with an emotion word: Lifted, Hopeful, Even, Weighed down or Raw. Since September 28 it also reads what people post in public about each borough, and how busy the streets are. Posts are counted and scored, never quoted, never kept.

What it is, and what it is not

The reading on the board is the mood of each borough right now, read from two places: its local news, and what people post in public about it. It is not a poll: nobody is asked anything, and nothing private is read. It is not a forecast, and it is not weather; the real forecast comes from the National Weather Service and is shown separately. Every name on the scale is an emotion word so it cannot be mistaken for a temperature.

It is also not a language model deciding how the city feels. It is arithmetic over a word list, which is slower to fool and easy to explain. What follows is the whole method, in order, with the exact numbers the engine uses. The only things kept back are the full word list and its weights, so nobody can write a headline to the list.

The people's pulse (added September 28)

News alone reads what reporters chose to print. So the engine now also reads what people themselves post in public about each borough:

Every post is scored with the same word list as the news, in memory, and then dropped. What is kept is a count and a mood per borough, nothing else: never a post, a name, a handle, a photo, a face or anyone's location. Posts that are off topic (a sitcom called Brooklyn Nine-Nine, a band called Queens of the Stone Age), not in English, or only a link are skipped.

How much the people count. The people's mood is blended with the news mood, and it counts for more as more people post: with 30 posts it carries a quarter of the reading, and with 60 or more it carries half. With fewer than 8 posts it is left out.

Rally energy. Protests, marches and vigils often follow a big event within hours. When three or more public posts about a borough mention one, the borough is marked Rally energy, so anyone going out knows.

Streets. The city's live traffic speeds (NYC DOT open data, a few hours behind) are compared with each borough's own normal speed, which the engine learns slowly over time. Much slower than normal reads Busy or Packed; much faster reads Quiet. This says how busy a borough is, not how it feels, so it never changes the mood score.

Left out on purpose: Reddit (it refuses programs), TikTok and Instagram (no public way for a program to read them), anything private, and cameras pointed at people.

When the map flashes

A borough surges when its reading jumps by 0.25 or more since the last run, when more than a third of at least ten public posts carry strong feeling, or when it has rally energy. A surging borough flashes a loud color for its leading emotion: gold for joy, amber for gratitude and pride, red for anger, violet for fear, blue for sadness, cyan for surprise and rally energy.

The four steps (the news)

1
Read. Every three hours the engine pulls the latest headlines and summaries from local papers (Gothamist, amNY, THE CITY, Brooklyn Paper, QNS, Bronx Times, SILive and others) and from the city's open data. Each story is tagged to a borough: the borough papers tag their own, and city-wide stories are tagged by the place names in them. A story with no borough in it counts for the city but for no borough.
2
Score each story. A dictionary of a few hundred words carries a weight from about -4 to +4. Rescued is +2.2, volunteers +2, celebrates +2.5, free +1.4; eviction is -2.4, hurt -2.2, delays -1.5. The engine walks the story word by word and adds up the weights it finds, with three adjustments:
  • Boosters. A word like very or extremely just before a scored word pushes it a little further in its own direction.
  • Negations. Not, never, no and the like within three words flip the sign and keep three quarters of the strength. "Not hurt" reads as good news, slightly softer than "safe".
  • Exclamation marks add a small push in the word's direction.
The total is then squashed into the range -1 to +1, so a long story full of strong words cannot outshout a short one. Alongside the number, eight emotion word families (gratitude, pride, joy, surprise, anger, fear, sadness, disgust) are counted; the family with the most hits is the story's dominant emotion.
3
Add up the borough. The borough's stories are averaged, with stories that had more scored words counting a little more (a story with four or more scored words counts double a story with none). Then two corrections:
  • The news baseline. Local news runs negative on an ordinary day, because crime and complaints are what gets reported. So an ordinary day is re-centred: a fixed +0.2 is added to every borough and to the city, which puts "an ordinary mix of news" at Even instead of Weighed down.
  • The 311 nudge. If the borough's 311 requests in the last full day are more than 25% above its seven-day average, 0.1 is taken off. If they are more than 25% below, 0.05 is added. It is a small nudge on purpose: 311 is a measure of how much people are asking the city for, not of mood.
The result is rounded to one decimal place and held between -1 and +1.
4
Name it. The number becomes a word on a five-step scale:
ReadingScoreWhat it means
✦Lifted0.3 and upgratitude and pride outweigh the rest
◆Hopeful0.1 and upmore good news than bad
◈Even-0.1 and upan ordinary mix
◇Weighed down-0.3 and upworry or loss is leading
▼Rawbelow -0.3anger or fear is leading
Two readings get a truer name when a particular emotion leads: Weighed down becomes On edge when fear leads and Grieving when sadness leads; Raw becomes Frightened when fear leads and Grieving when sadness leads.

The rest of the card

A worked example

Four made-up headlines, scored by the engine's real word list:

"Volunteers rescued a dog from the Gowanus Canal; the dog was not hurt" → +0.83 · 3 scored words (volunteers +2, rescued +2.2, hurt -2.2 flipped by "not") · gratitude leads
"Rent hikes leave Bronx tenants facing eviction as landlord ignores repairs" → -0.76 · 4 scored words · sadness leads
"Queens library celebrates 100 years with a free block party this weekend" → +0.71 · 2 scored words · pride leads
"Subway delays again after signal problems on the A line" → -0.60 · 2 scored words · no emotion family hit

Average of the four (weighted by scored words): +0.02 · plus the news baseline +0.2 · = 0.2 → Hopeful ◆, top emotion gratitude

Notice that the second headline has words the list does not carry (ignores, repairs). A word the list does not know scores nothing. That is the honest limit of the method and the reason the number is a reading, not a verdict.

What the reading cannot do

Where to check

The readings are on the board with each borough's stories-read count. The weekly report averages the daily readings across the week. The source list and their health are on how it works. The engine's rule that the scale uses emotion words and never temperature words, and that the real forecast is shown separately, is written in the same place.

Written to the studies standard. If a figure here does not match the page it links to, the page is right and this study is wrong: write to us and it gets corrected in place, with a note.

Ask the engine

It answers from a fixed list first; anything else goes to a language model that reads only the engine's public record and can neither act nor send. If you are in trouble it points you to real people first.