m-chrzan.xyz
aboutsummaryrefslogtreecommitdiff
path: root/src/blog/hex-curler.html
diff options
context:
space:
mode:
Diffstat (limited to 'src/blog/hex-curler.html')
-rw-r--r--src/blog/hex-curler.html136
1 files changed, 0 insertions, 136 deletions
diff --git a/src/blog/hex-curler.html b/src/blog/hex-curler.html
deleted file mode 100644
index 8f5f1c6..0000000
--- a/src/blog/hex-curler.html
+++ /dev/null
@@ -1,136 +0,0 @@
-title: "Hex Curler: A Minimalist Webgame"
-date: August 29, 2019
----
-<p>
-I just published Hex Curler, a tiny dungeon crawler, based on Jeff Moore's
-<a href='http://www.1km1kt.net/rpg/hex'>Hex</a>.
-</p>
-
-<p>
-You can play it by running the following in a bash shell:
-
-<pre>
-c=x; while [ $c ]; do clear; curl -c k -b k hex.m-chrzan.xyz/$c; read c; done
-</pre>
-</p>
-
-<p>
-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 <code>curl</code>, a CLI tool already
-available on most Unix-like systems.
-</p>
-
-<p>
-The source code is available <a href='https://gitlab.com/m-chrzan/hex-curler'>on
-my GitLab</a>.
-</p>
-
-<h3>Let's get curling</h3>
-<p>
-The whole concept arose from two ideas I had:
-
-<ul>
- <li>
- <code>curl</code> and a simple web server could be used to create a
- simple remote CLI program.
- </li>
- <li>
- For a webapp that implements a simple state-transition system (like a
- simple game), one could forget about session management and a database,
- and just store the state client-side in a cookie.
- </li>
-</ul>
-
-I abstracted these ideas away into a Ruby class called <code>Engine</code> and a
-skeleton Sinatra app.
-</p>
-
-<p>
-To create a new "curling" system, you extend <code>Engine</code> and implement
-four methods:
-
-<ul>
- <li>
- <code>step</code>: performs a single step of the state-transition
- function.
- </li>
- <li>
- <code>message</code>: outputs a message related to the most recent
- <code>step</code>.
- </li>
- <li>
- <code>hash_to_state</code> and <code>state_to_hash</code>: these are
- just overhead glue methods. They should deserialize and serialize
- between your engine's internal state and a Ruby <code>Hash</code>.
- </li>
-</ul>
-
-You also need to define a <code>secret</code> which is a string that is used to
-validate that a submitted cookie represents a valid state. More on this later.
-</p>
-
-<p>
-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:
-
-<pre>
-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
-</pre>
-</p>
-
-<h3><em>O</em>(1) space webapp</h3>
-<p>
-Hex Curler is hosted online but has no session management, no database. It's an
-<em>O</em>(1) space webapp.
-</p>
-
-<p>
-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.
-</p>
-
-<p>
-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 <code>checksum</code> 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.
-</p>
-
-<p>
-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.
-</p>
-
-<p>
-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.
-</p>