The part that isn't in your browser
What a server is, why this version needs one, and where shared things like leaderboards are kept.
Most of the game still runs on your computer, inside your browser. But this version does things your browser can't do alone: it looks up thousands of bands on the Internet Archive, keeps leaderboards that everyone shares, and remembers which hashtag means which tour. For that it needs a computer in the middle that every player can reach: a server.
Concept: "client and server". The client is the program on your device (the game in your browser). A server is a shared computer, always on, that many clients talk to over the internet. Anything that must be shared between people, like a leaderboard everyone sees, needs a server.
One small server program
The whole server is one Python program. When it starts, one function builds every page and every answer the game can ask for:
172def create_app(data_dir: Path, store=None) -> Flask: 173 """Build the Flask app, reading and writing its caches under ``data_dir``. 174 175 ``data_dir`` is a parameter (not a hardcoded path) so a test can point a 176 throwaway instance at a temp directory seeded with cache fixtures and drive 177 the whole flow offline, exactly as the live app runs against ``DATA_DIR``. 178 ``store`` holds the shared state (leaderboards, tags, run tickets); it 179 defaults to Redis when configured, else files under ``data_dir``. 180 """ 181 app = Flask("terrapin_trail", static_folder=None) 182 store = store if store is not None else make_store(data_dir) 183 184 # ------------------------------------------------------------ helpers 185 def band_name_for(collection: str) -> str:
Concept: "route". A route is one address the server answers, like
/play(the game) or/api/bands(the list of bands). Each route is a small function: a request comes in, an answer goes out.
Where shared things are kept
Shared things (scores, tags, share counts) have to be kept somewhere every copy of the server can see. When the game runs on Vercel, that's a database called Redis. In the workspace it's plain files. The rest of the code doesn't care which:
231def make_store(data_dir: Path): 232 url = redis_url_from_env() 233 if url: 234 return RedisStore(url) 235 return FileStore(data_dir / "store")
Concept: "interface". An interface is a promise about what something can do ('add a score', 'get the top 50') without saying how. Two different storage systems keep the same promise here, so the rest of the program can use either one.
- The client is the game on your device; the server is the shared computer behind it.
- The server is one Python program whose routes answer each kind of request.
- Shared data goes through one interface, kept in Redis on Vercel and in files in the workspace.