HACKER Q&A
📣 CBarkleyU

What is the most barebone back end solution?


Through sheer luck and even more stubborness I somehow ended up with a very small web game (in the realm of games like Wordle) in pure Typescript.

I want the state of the game to be shareable via following process: Player A presses save -> a JSON is saved onto my server -> A link is generated and shown to Player A -> Player A shares that link with Player B -> Player B clicks that link -> The game is loaded with the state of Player A

So the only interaction between front- and backend would be saving and loading that one JSON. My problem is: To me, the web might as well be magic, and I'm a bit overwhelmed with how I can get the ball rolling.

I think my options are:

A) Amazon Lambda + a S3 bucket (appeareantly this is somehow the cheapest and the most expensive option at the same time?)

B) Renting my own VPS and interacting with it through a REST API (I think I would need a managed server rather than a web hosting option, right?)

C) Something like Google Firebase/AWS Amplify

I feel like option B would be the old-school way of doing things and a good way for me to finally overcome my web-phobia, but do I really need to pay 50€/m to host a game that probably nobody every will play?


  👤 surprisetalk Accepted Answer ✓
You can generate your links with Cloudflare functions and save the links with Cloudflare KV. You can also serve the game with Cloudflare pages.

[1] https://developers.cloudflare.com/pages/platform/functions/

[2] https://developers.cloudflare.com/workers/learning/how-kv-wo...

[3] https://pages.cloudflare.com

Cloudflare offers generous free tiers, so you shouldn't have to pay anything.

I find Cloudflare's ecosystem much, much easier than all of the alternatives for simple projects. It's fast, the UIs are nice, the docs are great, and everything is usually deployable straight through GitHub and simple configs.


👤 dusted
Consider that for your use-case the state is likely to be small enough that you could simply serialize the state and base64 encode it, and add it to the url.

Other than that, I'd self-host it, either on a cheap VPS or just a rasperry pi in the closet, this way you avoid thinking about all the cloud stuff and won't be surprised by some massive bill because something went wrong, writing a backend in nodejs will feel very familiar to you if you've already used javascript or typescript before. For storing the state, it depends how much data you expect.. I'd see how far I could go with just keeping an object in memory and serializing that to a text-file.. or you could use sqlite with nodejs, then you don't need to administer a separate piece of software, it can simply be a nodejs module.


👤 lantry
I don't think you even need a backend. Just base64 encode the gamestate and include that in the url being shared. It will only work if the gamestate is small enough, but based on your description it sounds like that might be the case.

👤 monroewalker
I haven't used it before but Firebase/Supabase is probably the way to go if you just need to save and load data from the frontend. Fireship is an entertaining and instructive channel with some videos on it:

https://youtu.be/9kRgVxULbag

edit: to clarify, you don't need a server at all for what you're doing, just a database with an API, which (as I understand it) is what Firebase and Supabase offer. Firebase in 100 seconds by the Fireship channel: https://www.youtube.com/watch?v=vAoB4VbhRzM


👤 Lariscus
I would choose option B and use a really cheap <5€/m VPS with a sqlite database. Alternatively you could also use managed web hosting where you just upload you CGI scripts. This will probably cost around 5€ and is a bit more limited but they usually give you access to a proper database like postgresql and you don't have to do as much server administration yourself.

👤 srcreigh
The VPS option won’t be €50. I have a small vps for like $10/month.

Setup a VM. Install SQLite and caddy on it. Choose an async server framework Node or python quart or something.

Add a table to your SQLite, saved_games(id,json). Add two endpoints, save and load, save generates and Id saves json and returns a link, load returns the json. Make sure there’s an index on the id too.

Run your server, for example via Hypercorn if you’re using Quart or equivalent node prod setup.

Set up caddy to reverse proxy port 443 to your running instance. This gives you HTTPS

There you go. Quite simple and fast.

You could probably serve upwards of 1k QPS with this setup. That’s about 1/100th the qps of Google search.

You could try compressing the json before storing it too. Once you have some saves a dictionary compression would be really effective on a particular json format.


👤 7373737373
Rent a $5 cloud server, clone this repo here (https://github.com/void4/lazyweb/) and use json.dumps/loads(data) to (de)serialize the JSON data into a text field in the database

Edit: I've adapted my code example to your usecase here: https://github.com/void4/jsonserver/

You should probably set data size limits

Let me know if you need to know more, sounds like a fun project!


👤 sshine
Encrypted pastebin:

You encrypt and dump the JSON object to a site like https://hushfile.it/ — the download link has the decryption key as part of the URL:

https://hushfile.it/2f5998db28974#5KQPcgUzQdrQmjPHoXYcwxeiW3...

Now you don’t leak game state, and anyone with the link can access the game state and send a new game state back.


👤 tmsh
I’d do it all in the AWS console with Lambda and DynamoDB. Ask ChatGPT for some boilerplate with the v3 AWS SDK API.

There’s a few AWS-sponsored workshops. It’s pretty cheap for low/medium usage.

Amplify is a nice wrapper and will give you some level of authorization if you’d like (using AWS cognito underneath).

Like you say everyone will be biased towards what they know.

^ my tendency is to take detailed steps using the console so that it’s possible to reproduce. And avoid infrastructure as code until you really need it.


👤 rikelmens
Take a look at firebase storage, very easy to use: https://firebase.google.com/docs/storage/web/upload-files#we...

You can leave the bucket fully redable / writable by anyone, or limit who can do what.

Player A would upload the JSON to it and get the shareable URL: ================================================================== import { getStorage, ref, uploadString } from "firebase/storage"; const storage = getStorage(); const storageRef = ref(storage, 'some-child');

const state = '{foo:bar}'; uploadString(storageRef, state) .then((snapshot) => { console.log('Uploaded the state!'); return snapshot.ref.getDownloadURL(); }) .then((url) => { console.log(`Shareable state url: + ${url}`); }) ====================================================

And Player B would simply HTTP GET the shared URL.


👤 belmont_sup
If you ask barebones, that's going to get so many different answers here because everyone will have their own definition and bias. If I inherited a small game that needs a backend, I'd pick any of those backend-as-a-service options. Supabase and Firebase comes to mind.

If you pick Supabase, it's Postgres with a web api and sdk on top. Then, sure you can serialize all the game state as a jsonb record. You don't even need to deal with authentication if you don't care about isolating games.

Free tier until you make money somehow and then pay the 25/mo.


👤 xrayarx
You can always use google sheets, apparently: https://news.ycombinator.com/item?id=34865717

👤 leros
This sounds like the perfect use case for Firebase. You can achieve your goals with just a few lines of code in your Typescript app and it will be free unless your game gets really popular.

👤 tomjen3
I would agree with dusted about encoding the state of the game, but if you don't want that you don't need to pay 50 bucks a month for something that simple.

6-12 bucks will get you a more than powerful VPS, and Amazon S3 will be pretty cheap for this and allow you to set a policy that all storage expires after n-days, which will prevent this for exploding too much.

S3 is expensive for storage, but you are dealing with data at the kilobyte level, where it does not matter.


👤 didip
Everything in Golang and get a $5 Digital Ocean VPS.

👤 rozenmd
You could probably build on Cloudflare Workers + R2 to an extreme scale before you start being charged more than $5/mo

👤 jack_pp
B doesn't cost you 50$, you can get a VPS for <10$ a month. If you wrote it in typescript just read a tutorial for express and host it on a VPS, shouldn't take you more than a day or two. Now if it blows up that's a harder question to answer but that's a good problem to have

👤 machiaweliczny
Just use express server and session storage and voila. You can write prototype on repl.it

I would take a look at y.js if you are building shared state - https://github.com/yjs/yjs


👤 dagw
Lots of VPS companies will offer you a server for doing option B for less than 5€/month. That should be plenty for getting started and testing your idea. From there you can easily scale up if/when you need to.

👤 nathants
lambda + s3. add ec2 spot if you need it.

just make sure you understand how billing works. mostly it’s just egress bandwidth expensive, alarms and monitoring good. also 2fa is non optional.

do something like this:

https://github.com/nathants/aws-gocljs

or with less opinions:

https://github.com/nathants/libaws/tree/master/examples/simp...

welcome to cloud, glhf!


👤 graso
Just generate client-side a state.json for user A to download, then user A sends the file to user B and user B goes to your game and uploads the json

👤 bobalbrecht42
Just an S3 bucket. See http://rubeosity.com

👤 pabe
I'd try a ~$5 Hetzner cloud server with SurrealDB. SurrealDB offers GraphQL and REST endpoints, also SDKs.

👤 meltyness
Containers are always the answer, except I don't know if you can even get orchestration for cheaper than a t2.micro, and if your service and audience are small enough, might as well just run it on a micro.

👤 Frog0fWar
Google Sheets (no sarcasm)

👤 Thristle
use the browser local storage for it like any other web game. done.

👤 ashleyn
Rust + linode vps

👤 knorthfield
index.php