Towards #1715 and #1043.
This refactoring step is a prerequisite for #1719 to extricate references to the `CESK` module from the base `RobotR` definition.
In this PR:
* `Swarm.Game.CESK` is imported qualified to more easily track usages
* A new `RobotMachine` type family is added to parameterize the `_machine` field.
* `CESK` is a new parameter to `addTRobot`
Closes#1623.
Note that we still have to list both `vty-unix` and `vty-windows` in `stack.yaml` but that's OK; it just means they are both made available as extra dependencies, but only whichever is needed will actually be installed. In the codebase itself, we now get to avoid CPP on imports, and the code is quite a bit simpler.
Closes#1443.
Also added `-Wunused-packages` to clean up dependencies.
## Demo
This still works as usual:
stack run
Output editor keywords:
stack run swarm-docs -- editors --emacs
Towards #1415.
## Uses
This capability could be used to quickly iterate on DSL world descriptions, e.g. when tuning noise parameters.
## Implementation notes
* For the hard-coded ANSI terminal color names, I chose RGB triples that matched my own terminal settings. This means that a rendered PNG might not exactly match one's own terminal colors.
* `Blank` terrain corresponds to a transparent pixel.
* Implemented parse-time validation of `attr` references. Previously, referencing a nonexistent `attr` by an entity would fail silently at runtime.
* Normalization: strings like `"rock"` now only exist once; the string is shared via toplevel variable definitions
* Entities and terrain have TUI-independent color definitions from which VTY Attrs are derived, but all TUI user-interface colors are defined only as VTY Attrs.
## Demos
Each pixel in the output image correponds to one world cell. To enlarge, can use [imagemagick](https://legacy.imagemagick.org/Usage/resize/#scale):
stack run -- map data/scenarios/classic.yaml --seed 0 --png -w 300 -h 200 && convert output.png -scale 800% out2.png
![out2](https://github.com/swarm-game/swarm/assets/261693/51794b63-7d78-4738-b20a-8b4f4352f006)
stack run -- map data/scenarios/Challenges/bridge-building.yaml --png && convert output.png -scale 800% out2.png
![image](https://github.com/swarm-game/swarm/assets/261693/b04895a2-eb61-4499-a122-ae8444f7e4fb)
Closes#1436.
The schema `.json` files are now the authoritative source of truth for documentation.
Wrote a very simple parser for JsonSchema to extract the documentation from JSON.
Split the README.md into [static](c314cc50a1/data/scenarios/README.md) and [auto-generated](c314cc50a1/data/scenarios/doc-fragments/SCHEMA.md) parts.
Added a custom `"footers"` key to schema files to support inclusion of other markdown files for each object description.
# Schema doc regeneration
./scripts/regenerate-schema-docs.sh
* generate Web API endpoint docs in CLI - `swarm generate endpoints`
* use default port in API docs using `renderCurlBasePath`
* fix code rendering in Web API so that the tree nodes try to fit one line
* try adding some API samples
* hand craft `ToJSON Robot` instance to match `FromJSONE` more closely
* default values are skipped
* inventory and devices are shortened to names and counts
Closes#353
Also adds a new top-level command to render a scenario map to the console.
Most of the work for this feature entailed identifying the subset of `GameState` that is actually needed for rendering the world, so that the required information can be retrieved from just the `Scenario` rather than having to instantiate an entire `GameState`.
# Potential follow-ups
- [ ] There is some noticeable lag when using the up/down arrow to navigate to any of the largely "procedurally generated" scenarios, e.g. `classic` or `creative`. May want to do caching of some kind. The other "challenge scenarios" render without perceptible delay.
- [ ] The heuristic for choosing the view center could be improved, possibly by defining new "hints" as part of the scenario schema.
- [ ] Rendering to the console could be augmented with color.
- [ ] Could render to other image formats like PNG or SVG
- [ ] account for a user-selected seed in the scenario launch parameters dialog
# Demos
## Scenario selection preview
![image](https://github.com/swarm-game/swarm/assets/261693/7c54c6bb-fb02-461f-98a1-06eccbbfc450)
## Command-line map rendering
```
~/github/swarm$ scripts/play.sh map data/scenarios/Challenges/ice-cream.yaml
OO
▒▒▒ ▒▒▒▒ OOOO
┌─┐▒┌──┐ MMMM
│B V6│ \ZZ/
└──────┘ \/
```
and
```
stack run -- map data/scenarios/Challenges/hackman.yaml
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▒••••••••••▒••••••••••▒
▒o▒▒▒•▒▒▒▒•▒•▒▒▒▒•▒▒▒o▒
▒•▒▒▒•▒▒▒▒•▒•▒▒▒▒•▒▒▒•▒
▒•••••••••••••••••••••▒
▒•▒▒▒•▒•▒▒▒▒▒▒▒•▒•▒▒▒•▒
▒•••••▒••••▒••••▒•••••▒
▒▒▒▒▒•▒▒▒▒ ▒ ▒▒▒▒•▒▒▒▒▒
▒•▒ ▒•▒
▒▒▒▒▒•▒ ┌──=──┐ ▒•▒▒▒▒▒
• │ │ •
▒▒▒▒▒•▒ └─────┘ ▒•▒▒▒▒▒
▒•▒ ▒•▒
▒▒▒▒▒•▒ ▒▒▒▒▒▒▒ ▒•▒▒▒▒▒
▒••••••••••▒••••••••••▒
▒•▒▒▒•▒▒▒▒•▒•▒▒▒▒•▒▒▒•▒
▒o••▒•••••••••••••▒••o▒
▒▒▒•▒•▒•▒▒▒▒▒▒▒•▒•▒•▒▒▒
▒•••••▒••••▒••••▒•••••▒
▒•▒▒▒▒▒▒▒▒•▒•▒▒▒▒▒▒▒▒•▒
▒•••••••••••••••••••••▒
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
```
* add option `--width` to `format` CLI
* if width is not specified use terminal width
* if terminal width is unknown, use default (100)
This should help with testing (not so) long layouts like in #1473.
When supplying initial code with `--run` or `--autoplay`, a lot can happen in the first few moments of play such that it can be a tricky feat to smash CTRL+z fast enough to slow down the game to observe.
Now, one can pass e.g. `--speed 0` to begin the game at 1 tick per second:
scripts/play.sh --scenario data/scenarios/Challenges/maypole.yaml --autoplay --speed 0
Ability to code your own input handler routines. Closes#102 . Fixes#1210 .
* Adds a new type `key` to represent keypresses
* Adds a primitive function `key : text -> key` which can handle usual letters, numbers, etc. as well as special keys like `"Down"` etc, as well as modifier key prefixes like `key "A-C-Del"`. `swarm generate keys` generates a list of all recognized special key names.
* New command `installKeyHandler : text -> (key -> cmd unit) -> cmd unit` which sets the "current key handler". The `text` value is a hint line to display in the secondary key hints menu while the handler is running. The global shortcut `M-k` toggles the currently installed handler.
* Add a `keyboard` device to provide these commands, as well as a `key` entity (the recipe for a `keyboard` is 16 `key`s + 1 `board`).
* Add a few examples in the `examples` folder.
* Add an installed `keyboard` to the `building-bridges` challenge.
May be able to reduce likelihood of #1086 by having a autogenerated table of the commands and the tutorials they are introduced in.
This work is related to #1106 in that robot commands should be given distinct markup (backticks).
## Demo
scripts/play.sh generate pedagogy
**Updated:** See [rendered output](https://gist.github.com/kostmo/d4af3a6814e65fc6d455fd34b41552d3).
## New tests
scripts/run-tests.sh --test-arguments '--pattern "Pedagogical soundness"'
Note that the test for `crash.yaml` is currently failing because the `Give` command (and some others) are utilized in this tutorial without having been mentioned in the description or in earlier tutorials.
Additionally, the "bug" described in [this comment](https://github.com/swarm-game/swarm/issues/1089#issuecomment-1418497686) **should** be caught by these tests (i.e. fail the tests) since the embedded `solution` code in the YAML file utilizes the `give` command. That is, if it currently weren't for [this issue](https://github.com/swarm-game/swarm/pull/1186/files#r1152789153).
This PR introduces an `--autoplay` flag that causes the solution stored in the `solutions` field of a scenario file (which was selected on the command line via the `--scenario` option) to be automatically run when the game starts, identically to the `--run` option.
The purpose is to:
1. more easily showcase scenarios to the community
2. facilitate a quick a sanity check that the solution text in the yaml file is correct
# Test procedure
stack run -- --scenario data/scenarios/Tutorials/conditionals.yaml --autoplay
This has the same effect as manually copying the solution stored in `conditionals.yaml` to `myfile.sw`, and then running:
stack run -- --scenario data/scenarios/Tutorials/conditionals.yaml --run myfile.sw
<a href="https://asciinema.org/a/mGB5VDKhsLLPdrItZWi3qsHUV" target="_blank"><img src="https://asciinema.org/a/mGB5VDKhsLLPdrItZWi3qsHUV.svg" width="640" /></a>
It is probably safer to have Template Haskell GitInfo in Main and not depend on it in Swarm modules.
Depending on how the build system and TH interact we were either recompiling too often or not often enough.
- if the git info was evaluated once and not again after making a commit, then it was not up to date
- if the git info was reevaluated on every commit then we would needlessly recompile dependent modules
I believe it was only the former, but this helps even in that case (any code change recompiles Main).
- when `datadir` is not available, try using the XDG data directory
This way the game can be installed as an executable and data files unpacked to `~/.local/share/swarm/data`.
Notice that the XDG data folder is `~/.local/share/swarm`; inside it is the unpacked `data`.
The alternative approach is to use the environment variable `swarm_datadir` and set that to the unpacked data folder.
That works (even after this change) but is not very beginner friendly.
Ideally, we would like to set this in Cabal when building executable, for example to `/usr/share/swarm/<version>`.
Reading through haskell/cabal#5997, it looks like that is not supported.
- query GitHub Releases for a new version
- add `swarm version` command
- show the version notification in the main menu
- add a new app-wide logging queue
- show the app-wide logs in the main menu as Messages
- catch and show the web API failure in the Messages
- closes#66
- closes#627
This change introduce a new web API for the game.
The initial goal is to expose the internal state using the
`/robots` and `/robot/$id` endpoint to query the json representation
of the robots.
A new command line argument is added:
- When `--port 0` is set, the web service is disabled.
- When `--web port` is set, the game won't start if the web service fail to bind the port.
- Otherwise, when `--web` is not set, the service may start on 5357 if the port is available.
Example usage:
```
swarm --web 5357
curl localhost:5357/robots | jq
```
Future improvement may include:
- Ability to load program to the base (to send command from external text editor)
- Serve a html interface for alternative visualization
- add `generate` subparser to the executable
- create a generator for a Graphviz entity dependencies graph
- part of #344
You can interactively test this with:
```bash
$ cabal run swarm:swarm -- generate recipes \
| sed -n '/^digraph/,$p' > docs/recipes.dot
$ xdot docs/recipes.dot
```
Generalize challenges + various modes to all be "scenarios" which are described by `.yaml` files in `data/scenarios`.
- Both challenges and classic/creative modes are now subsumed under the more general notion of "scenarios".
- A scenario describes how to set up the world etc. when starting a game; all scenarios are stored in a `.yaml` file in `data/scenarios`.
- "New game" menu item now lets the user choose a scenario.
- Some small improvements to the way seeds are handled.
See #296. This will enable #35 and #25 .
Fixes#82.
Right now it only works in classic mode. It wouldn't be too hard to
make it work with challenge mode as well, but that would require some
more careful thinking about whether every challenge is required to
have a 'base' and how we identify which robot that is, so that we run
the given file on the right robot.
- adds CLI option `--seed` and propagates it to `testWorld2` (Closes#14)
- moves the base in the tree shade (Closes#90)
- makes the `random` command depend on initial seed (Closes#13)
This change improves the user experience when editing swarm code outside of the REPL with:
- CLI for a `format` command to quickly parse and type check a file.
- Basic LSP server to provide IDE feedback on save, e.g. visual squiggly for errors.
- Initial emacs mode.
Fixes#82#110