From 4bf167df5d0abee939bf3ebfa925c4fe22cd0502 Mon Sep 17 00:00:00 2001
From: Marcin Chrzanowski
-I just published Hex Curler, a tiny dungeon crawler, based on Jeff Moore's
-Hex.
-
-You can play it by running the following in a bash shell:
-
-
-c=x; while [ $c ]; do clear; curl -c k -b k hex.m-chrzan.xyz/$c; read c; done
-
-
-This was an exercise in minimalism. The game server is implemented in less than
-a thousand lines of Ruby code. It is completely stateless, requiring no
-database. The front end "client" is a single line of bash, less than 80
-characters long. The only dependency is curl
, a CLI tool already
-available on most Unix-like systems.
-
-The source code is available on -my GitLab. -
- --The whole concept arose from two ideas I had: - -
curl
and a simple web server could be used to create a
- simple remote CLI program.
- Engine
and a
-skeleton Sinatra app.
-
-
-
-To create a new "curling" system, you extend Engine
and implement
-four methods:
-
-
step
: performs a single step of the state-transition
- function.
- message
: outputs a message related to the most recent
- step
.
- hash_to_state
and state_to_hash
: these are
- just overhead glue methods. They should deserialize and serialize
- between your engine's internal state and a Ruby Hash
.
- secret
which is a string that is used to
-validate that a submitted cookie represents a valid state. More on this later.
-
-
--The Sinatra skeleton instantiates an engine with the received cookie, -runs a step, sends back the new state in the returned cookie, and responds with -the engine's message. The code for it fits in half of a browser window: - -
-require 'sinatra' -require 'sinatra/cookies' - -# exposes `Hex`, which extends `Engine`, implementing a simple dungeon crawler -require './hex_engine' - -def secret - # get secret from environment - ENV['HEX_SECRET'] -end - -get '/:command' do |command| - # `new` uses `hash_to_state` to initialize the engine's state - engine = Hex.new cookies.to_h - engine.step command - # `state_h` uses `state_to_hash` to serialize the engine's new state - engine.state_h.each_pair do |key, value| - cookies[key] = value - end - engine.message -end -- - -
-Hex Curler is hosted online but has no session management, no database. It's an -O(1) space webapp. -
- --As mentioned before, the game's state is stored in a cookie. The server need -only know the contents of that cookie to return a new state back to the user. -
- -
-To prevent a user from tampering with the cookie, for example by increasing
-their health to a ridiculous number, becoming invulnerable to enemies in Hex,
-the cookie also contains a checksum
field. This checksum is the
-hash of the state together with an appended secret only known by the game
-server. The server will refuse to respond to requests whose cookie does not have
-a valid checksum.
-
-This introduces some interesting possibilities. For example, let's say Alice -wants to boast to her friends about how she just beat Hex, ended with 100 HP -remaining, and had upgraded her magic armor to level 5. Her friend Bob doesn't -just have to take her word for it, or trust a screenshot that could have easily -been photoshopped. -
- --Alice can send Bob her state cookie. If a request to the game server with it -succeeds, Bob can be assured that he has cryptographic proof of Alice's -claims. -
-- cgit v1.2.3