From bbb5a5484a59af2cef770da1c9653d45880057d5 Mon Sep 17 00:00:00 2001 From: Neale Pickett Date: Mon, 11 Dec 2023 11:36:18 -0700 Subject: [PATCH] Development doc more approachable? --- docs/content-layout.png | Bin 0 -> 37967 bytes docs/development.md | 248 ++++++++++++++++++++++++++++------------ 2 files changed, 172 insertions(+), 76 deletions(-) create mode 100644 docs/content-layout.png diff --git a/docs/content-layout.png b/docs/content-layout.png new file mode 100644 index 0000000000000000000000000000000000000000..b88e40c9e12ae723e354129c9974701214e551ae GIT binary patch literal 37967 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 HB{Ts5U1Dhl literal 0 HcmV?d00001 diff --git a/docs/development.md b/docs/development.md index ccc789a..f737dec 100644 --- a/docs/development.md +++ b/docs/development.md @@ -1,105 +1,201 @@ -Developing Content -============================ +Developing Content: Structure +================ -The development server shows debugging for each puzzle, -and will compile puzzles on the fly. +![Content Layout](content-layout.png) -Use it along with a text editor and shell to create new puzzles and categories. +MOTH content is structured ot two levels: categories, and puzzles. +Category +------- -Set up some example puzzles ---------- +A category consists of one or more puzzles. +Each puzzle is named by its point value, +and each point value must be unique. +For instance, +you cannot have two 5-point puzzles in a category. -If you don't have puzzles of your own to start with, -you can copy the example puzzles that come with the source: +Scoring is usually calculated by summing the +*percentage of available points per category*. +This allows content developers to focus only on point values within a single category: +how points are assigned in other categories doesn't matter. - cp -r /path/to/src/moth/example-puzzles /srv/moth/puzzles - - -Run the server in development mode ---------------- - -These recipes run the server in the foreground, -so you can watch the access log and any error messages. - - -### Podman - - podman run --rm -it -p 8080:8080 -v /srv/moth/puzzles:/puzzles:ro ghcr.io/dirtbags/moth-devel - - -### Docker - - docker run --rm -it -p 8080:8080 -v /srv/moth/puzzles:/puzzles:ro ghcr.io/dirtbags/moth-devel - -### Native - -I assume you've built and installed the `moth` command from the source tree. - -If you don't know how to build Go packages, -please consider using Podman or Docker. -Building Go software is not a skill related to running MOTH or puzzle events, -unless you plan on hacking on the source code. - - mkdir -p /srv/moth/state - cp -r /path/to/src/moth/theme /srv/moth/theme - cd /srv/moth - moth -puzzles puzzles - - -Log In +Puzzle ----- -Point a browser to http://localhost:8080/ (or whatever host is running the server). -You will be logged in automatically. +A puzzle consists of a few static fields, +a main puzzle body, +and optionally attached files. + +At a minimum, +a puzzle must contain `puzzle.md`: +a +[CommonMark Markdown](https://spec.commonmark.org/dingus/) +file with metadata. + +Example: + +```markdown +--- +authors: + - Neale Pickett +answers: + - one of its legs are both the same + - One of its legs are both the same + - one of its legs are both the same. + - One of its legs are both the same. +--- + +This puzzle consists of a joke. + +What is the difference between a duck? +``` + +### Puzzle Metadata + +Puzzle metadata is the section of `puzzle.md` between `---`. +This section consists of [YAML](https://yaml.org/), +describing various metadata aspects of the puzzle. + +At a minimum, +each puzzle should contain: + +* authors: who created the puzzle +* answers: a list of answers that are considered "correct" + +Other metadata a puzzle can contain: + +* debug: information used only in development mode + * summary: text summarizing what this puzzle is about + * notes: any additional notes you think it's important to record + * hints: a list of hints that could aid an instructor +* objective: what the goal of this puzzle is +* ksas: a list of NICE KSAs covered by this puzzle +* success: criteria for success + * acceptable: criterion for acceptably succeeding at the task + * mastery: criterion for mastery of the task +* attachments: a list of files to attach to this puzzle (see below) + +### Body + +The body of a puzzle is interpreted as +[CommonMark Markdown](https://spec.commonmark.org/dingus/) +and rendered as HTML. + +You can inline attached images with the `![alt text](filename.jpg)` +Markdown construct, but they must be listed as attachments! + +### Attachments + +Any filenames listed under `attachments` in the metadata will be included +with the puzzle. -Browse the example puzzles ------------- +Developing Content: Source vs Mothballs +============================= + +As a developer, +you will begin by running MOTH in development mode. +In development mode, +MOTH will provide answers for each puzzle alongside the puzzle. + +In order to run in production mode, +each category must be "transpiled" into a "mothball". +This is done to reduce the amount of dynamic code running on a production server, +as a way of decreasing the attack surface of the server. + +To obtain a mothball, +simply click the "download" button on the puzzles list of a development server. +Mothballs have the file extension `.mb`. -The example puzzles are written to demonstrate various features of MOTH, -and serve as documentation of the puzzle format. +Setting Up Your Workstation +===================== + +You will need two things to develop content: +a MOTH server, +and a text editor. + +MOTH Server +----------- + +### Windows + +Windows users can unzip the zip file provided by the MOTH development team, +and run `moth-devel.bat`. +You can close this window whenever you're done developing. + +Once started, +open +http://localhost:8080/ +to connect to your development server. + +### Linux + +Linux users with Docker can run the following to get started + +```sh +mkdir -p puzzles +docker run --rm -it -p 8080:8080 -v $(pwd)/puzzles:/puzzles:ro ghcr.io/dirtbags/moth-devel +``` + +Hit Control-C to terminate MOTH. -Make your own puzzle category -------------------------- +Text Editor +--------- - cp -r /srv/moth/puzzles/example /srv/moth/puzzles/my-category +We like Visual Studio Code, +but any text editor will work: +you only need to edit the `puzzle.md` (Markdown) files. +Your First Category +================ -Edit the one point puzzle --------- +Open the `puzzles` directory/folder created where you launched the server. +Create a new directory/folder named `test-category`. +Within that directory/folder, +create a directory/folder named `1`. +And within `1`, +create a new file named `puzzle.md`. +Paste the following text into that file: - nano /srv/moth/puzzles/my-category/1/puzzle.md +```markdown +--- +authors: + - YOUR NAME HERE +answers: + - Elephant + - elephant +--- -I don't use nano, personally, -but if you're advanced enough to have an opinion about nano, -you're advanced enough to know how to use a different editor. +# Animal Time +Do you like animals? I do! +Can you guess my favorite animal? +``` -Read our advice ---------------- +Now, +open http://localhost:8080/ in a web browser. +You should see a "test-category" category, +with a single 1-point puzzle. +Click that puzzle, +and you should see your animal puzzle presented. + +The two answers we're accepting can be improved, +because some people might use the plural. +Edit `puzzle.md` to add two new answers: +`Elephants` and `elephants`. +Reload the web page, +and check the debug section to verify that all four answers are now accepted. + +Next Steps +========== The [Writing Puzzles](writing-puzzles.md) document has some tips on how we approach puzzle writing. There may be something in here that will help you out! - -Stop the server -------- - -You can hit Control-C in the terminal where you started the server, -and it will exit. - - -Mothballs -======= - -In the list of puzzle categories and puzzles, -there will be a button to download a mothball. - Once your category is set up the way you like it, download a mothball for it, -and you're ready to [get started](getting-started.md) +and you're ready for [getting started](getting-started.md) with the production server.