mirror of https://github.com/dirtbags/moth.git
175 lines
5.0 KiB
Markdown
175 lines
5.0 KiB
Markdown
Overview of MOTH
|
|
================
|
|
|
|
Monarch Of The Hill (MOTH) is a framework for running puzzle-based events for teams.
|
|
Each team is assigned a token which they use to identify themselves.
|
|
|
|
Teams are presented with a number of *categories*,
|
|
each containing a sequence of *puzzles* of increasing point value.
|
|
|
|
When the event starts, only the lowest-point puzzle in each category is available.
|
|
As soon as any team enters the correct solution to the puzzle,
|
|
the next puzzle is opened up for all teams.
|
|
|
|
A scoreboard tracks team rankings,
|
|
indicating score within each category,
|
|
and overall ranking.
|
|
|
|
|
|
State Directory
|
|
===============
|
|
|
|
The state directory is written to by the server to preserve state.
|
|
At no point is anything only in memory:
|
|
if it's not on the filesystem,
|
|
mothd doesn't think it exists.
|
|
|
|
The state directory is also used to communicate actions to mothd.
|
|
|
|
|
|
`initialized`
|
|
-------------
|
|
|
|
Remove this file to reset the state. This will blow away team assignments and the points log.
|
|
|
|
|
|
`disabled`
|
|
----------
|
|
|
|
Create this file to pause collection of points and other maintenance.
|
|
Contestants can still submit answers,
|
|
but they won't show up on the scoreboard until you remove this file.
|
|
|
|
This file does not normally exist.
|
|
|
|
|
|
`until`
|
|
-------
|
|
|
|
Put an RFC3337 date/time stamp in here to have the server pause itself at a given time.
|
|
Remember that time zones exist!
|
|
I recommend always using Zulu time.
|
|
|
|
This file does not normally exist.
|
|
|
|
|
|
`teamids.txt`
|
|
-------------
|
|
|
|
A list of valid Team IDs, one per line.
|
|
It defaults to all 4-digit natural numbers,
|
|
but you can put whatever you want in here.
|
|
|
|
|
|
`points.log`
|
|
------------
|
|
|
|
The log of awarded points:
|
|
|
|
EpochTime TeamId Category Points
|
|
|
|
Do not write to this file, unless you have disabled the contest. You will lose points!
|
|
|
|
|
|
`points.tmp`
|
|
------------
|
|
|
|
Drop points logs here.
|
|
Filenames can be anything.
|
|
|
|
When the file is complete and written out,
|
|
move it into `points.new`,
|
|
where a non-disabled event's maintenance loop will eventually move it into the main log.
|
|
|
|
`points.new`
|
|
------------
|
|
|
|
Complete points logs should be atomically moved here.
|
|
This is to avoid needing locks.
|
|
[Read about Maildir](https://en.wikipedia.org/wiki/Maildir)
|
|
if you care about the technical reasons we do things this way.
|
|
|
|
|
|
Mothball Directory
|
|
==================
|
|
|
|
Put a mothball in this directory to open that category.
|
|
Remove a mothball to disable that category.
|
|
|
|
Overwriting a mothball with a newer version will be noticed by the server within one maintenance interval
|
|
(20 seconds by default).
|
|
Be sure to use the same compilation seed in the development server if you compile a new version!
|
|
|
|
Removing a category does not remove points that have been scored in the category.
|
|
|
|
|
|
Resources Directory
|
|
===================
|
|
|
|
|
|
Making it look better
|
|
-------------------
|
|
|
|
`mothd` provides some built-in HTML for rendering a complete contest,
|
|
but it's rather bland.
|
|
You can override everything by dropping a new file into the `resources` directory:
|
|
|
|
* `basic.css` is used by the default HTML to pretty things up
|
|
* `index.html` is the landing page, which asks to register a team
|
|
* `puzzle.html` renders a puzzle from JSON
|
|
* `puzzle-list.html` renders the list of active puzzles from JSON
|
|
* `scoreboard.html` renders the current scoreboard from JSON
|
|
* Any other file in the `resources` directory will be served up, too.
|
|
|
|
If you don't want to read through the source code, I don't blame you.
|
|
Run a `mothd` server and pull the various static resources into your `resources` directory,
|
|
and then you can start hacking away at them.
|
|
|
|
|
|
Making it look totally different
|
|
---------------------
|
|
|
|
Every handler can serve its answers up in JSON format,
|
|
just add `application/json` to the `Accept` header of your request.
|
|
|
|
This means you could completely ignore the file structure in the previous section,
|
|
and write something like a web app that only loads static resources at startup.
|
|
|
|
|
|
Changing scoring
|
|
--------------
|
|
|
|
Scoring is determined client-side in the scoreboard,
|
|
from the points log.
|
|
You can hack in whatever algorithm you like,
|
|
and provide your own scoreboard(s).
|
|
|
|
If you do hack in a new algorithm,
|
|
please be a dear and email it to us.
|
|
We'd love to see it!
|
|
|
|
|
|
|
|
How Scores are Calculated by Default
|
|
------------------------------------
|
|
|
|
The per-category score for team `t` is computed as:
|
|
|
|
* Let `m` be the sum of all points in currently-visible puzzles in this category
|
|
* Let `s` be the sum of all points team `t` has won in this category
|
|
* Team `t`'s score is `s`/`m`
|
|
|
|
Therefore, the maximum number of points a team can have in a category is 1.0.
|
|
Put another way, a team's per-category score is the percentage of points they've made so far in that category.
|
|
|
|
The total score for team `t` is the sum of all per-category points.
|
|
|
|
Therefore, the maximum number of points a team can have in a 7-category event is 7.0.
|
|
|
|
This point system has proven both easy to explain (if not immediately obvious),
|
|
and acceptable by participants.
|
|
Because we don't award extra points for quick responses,
|
|
teams always feel like they have the possibility to catch up if they are skilled enough.
|
|
|
|
|