Adds type synonym declarations to the language, like so:
```
tydef Maybe a = Unit + a end
def lookdown : Cmd (Maybe Text) = scan down end
> lookdown
it2 : Maybe Text = inl ()
```
`tydef` behaves very similarly to `def` except that it defines a new (parameterized) type instead of a new term.
Note that higher-kinded types are not yet supported; for example we cannot say `tydef Foo f = Unit + f Int` (in fact this would be a syntax error since type variables cannot be at the head of an application). However there is nothing stopping us from adding that in the future; I just wanted to keep things simple for now.
If you know of any scenario code that would be a good candidate for using type synonyms, let me know --- it would be nice to update a few scenarios as a better stress test of type synonyms before merging this.
Closes#153.
Closes#1533
# Demo
```
scripts/test/run-tests.sh --test-options '--pattern "sow"'
```
or
```
scripts/play.sh -i data/scenarios/Testing/1533-sow-command.yaml --autoplay
```
![Screenshot from 2024-05-03 19-12-08](https://github.com/swarm-game/swarm/assets/261693/52df7de4-c158-4973-b109-5337e38c35f1)
## Other changes
* Introduced the `ChildInheritance` type to specify how the `Display` attribute is inherited by built child robots.
* Introduce the `mature` property of `growth`. For example, it doesn't make much sense to plant an `acorn` and call the resulting, fully-grown plant also an `acorn`. Instead, an `acorn` matures into an `oak`.
Measures the volume of an enclosed space.
A useful alternative to the `path` command for goal checking.
## Demo
scripts/play.sh -i data/scenarios/Testing/1747-volume-command.yaml --autoplay --speed 2
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
Closes#1631
## Design
* Entities have a new property: a `Set` of textual tags.
* Two new commands are introduced:
* `HasTag` checks whether a single entity has a given tag
* `TagMembers` allows cycling through all members with a given tag
* `TagMembers` may be considered more powerful than `HasTag`, so has its own separate capability (`CTagmembers`).
* A map is computed at scenario initialization to facilitate `TagMembers` lookups.
* Tag names are highlighted in yellow in markdown.
## Demo
scripts/play.sh -i scenarios/Testing/1631-tags.yaml --autoplay
## Other changes
* Incidentally, changed `knownEntities` from a list to a `Set` so that `Set.member` can be used instead of `elem`.
* Highlight occurrences of structures in markdown in red
* Add a new `blueprint` entity to provide `floorplan` and `structure` commands
* new `floorplan` command to get the dimensions of a structure
* structure location is southwest instead of northwest corner
* handle structures with "holes" for statically-recognized structures and when modifying interior cells post-recognition
Each of these is its own commit for reviewability's sake.
Closes#1575
Implements structure recognition.
## Features
* Structure browsing dialog (`F6`) that becomes available if a scenario declares any recognizable structures
* Automatically recognizes statically-placed structures upon scenario initialization, accounting for occlusion by other entity/structure placement
* New `structure` command for querying location of recognized structures (primarily intended for system robots and goal checking)
* Efficiently recognizes structures immediately upon completion
* Accounts for removal of structures
* Several new integration tests
* Structured web-interface log to help understand/debug the recognition process
* Re-uses much of the functionality built previously for defining structures (#1332)
Other changes:
* Improved validation for static structure placement (ensure valid structure names instead of failing silently)
* Moved a few functions (`getNeighborLocs`, `zoomWorld`, `entityAt`, `robotWithID`, `robotWithName`) out of `Step.Util` and into `State` so that recognizer initialization, which becomes a field in `GameState`, could use them
* split `scenarioToGameState` into pure and non-pure functions
## Optimizations
Scenarios that do not make use of structure recognition are entirely unaffected, performance-wise.
Some optimizations include:
* Structure definitions must "opt-in" to participate in automatic recognition
* Aho-Corasick automatons optimized by:
* only initiate structure search if a placed entity exists on a participating structure template
* initializing different automatons for each type of "placed entity"
* pruning inapplicable row candidates for 2-D search
The row-level structure recognition cache described in #1575 was not implemented; it's probably not worth the complexity cost.
# UI Demo
scripts/play.sh -i scenarios/Testing/1575-structure-recognizer/1575-browse-structures.yaml --autoplay
1. Press `F6` for Structure Browser dialog
2. View http://localhost:5357/recognize/log and http://localhost:5357/recognize/found
![image](https://github.com/swarm-game/swarm/assets/261693/e32d3572-7e53-42d6-84cd-393c57a8aeac)
# Future improvements
* Refactor `State.hs` so that the new helper functions can live elsewhere
* Support non-rectangular recognizable structures
* Allow flip/rotate of recognizable structures
* Structure ownership by robots
* Consolidate code between the Goals and Structures modal dialogs, and the Achievements browser
* Enforce minimum/maximum dimensions for structure definitions
This adds two files. The first is the syntax file responsible for basic highlighting. The highlight categories are based roughly on those seen in the Emacs file ([swarm-mode.el](https://github.com/swarm-game/swarm/blob/main/editors/emacs/swarm-mode.el)). The second is the file for configuring the language server. Since it is based on Neovim's native LSP client, it only works with Neovim and not Vim.
`README.md` in the `editor` folder has also been updated to include instructions for setting these up.
This saves a step in the development setup process.
Note that the settings file is included in the toplevel `.gitignore`, so any changes on top of this one will not result in a "dirty" repo.
* move the VSCode extension under "swarm-game" organisation
* add Open VSX Registry to "Deploy Extension" GitHub Action
* bump version, so it gets pushed once tagged
* closes#1453
Closes#1428
Since the authoritative validation of scenario files is actually performed by virtue of `swarm` parsing them, this CI job actually exists to ensure the JSON Schema descriptions are accurate. This is important for two purposes:
* Documentation is generated from the JSON Schema files (#1436)
* JSON Schema has integration with VS Code and other IDEs
# Testing
Verified that the schema checker action does indeed work by intentionally pushing an invalid scenario file in f789f81.
Towards #1007
The `use` command adopts the same return type as `drill`:
use : text -> dir -> cmd (unit + text)
## Demo
scripts/play.sh --scenario data/scenarios/Testing/1007-use-command.yaml --autoplay
Closes#392 . Adds a command `halt : actor -> cmd unit` which halts the given robot if it is within a distance of 1 (no distance limit for system robots or in creative mode). `halt self` works too. Privileged robots (i.e. system robots, or when in creative mode) can halt any other robot. Unprivileged robots cannot halt system robots.
Closes#1234
A `"dozer blade"` is defined locally to provide `push` capability. To decouple this PR from bikeshedding, will defer the definition of a global entity that offers `push` capability to another PR.
Closes#1218
scripts/play.sh --scenario data/scenarios/Testing/1218-stride-command.yaml --autoplay
I decided to implement this command with the same exception behaviors as the `move` command.
If any obstructions exist on the path, then an exception is thrown and no movement is made.
The implications of this are:
1. With `try`, one can learn in `O(1)` time whether any obstructions exist along a line of up to 64 units long
2. One can learn in `O(log N)` time the exact distance of the nearest obstruction along that line.
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.
Closes#687
## Demo
scripts/play.sh --scenario data/scenarios/Testing/687-watch-command.yaml --autoplay
or use `run` instead of `--autoplay`, and monitor the state:
curl -s http://localhost:5357/robot/0 | jq ._watchedLocations
Towards #1171
The `resonate` command counts entities of a given type within a rectangle.
This PR also fixes a bug in `detect` when the rectangle coords are non-ascending.
towards #1171
## New tests
Unit tests:
scripts/run-tests.sh --test-arguments '--pattern "Relative direction"'
Integration tests for `sniff` and `chirp` demonstrate how to home in on an item using distance and orientation, respectively.
## Efficiency
For the sake of execution time, I have capped the max "diameter" (`N`) of both commands to `200` cells. In the worst case (the entity is not present), `O(N^2)` cells are inspected, which manifests as a perceptible delay when the command is run. I came across the `getElemsInArea` function that seems to suggest that an `O(N * log N)` search may be possible. Is that the case?
Otherwise we may be able to add some new data structures to the game state for efficient entity location querying.
Closes#907.
- Add a recipe for `welder` device (which provides `equip`/`unequip`)
- Recipe = 2 `copper wire` + 1 `copper pipe` + 1 `iron plate` + 1 `I/O cable` (transitively requires `furnace` + 1.5 ` copper ore` + 0.5 `iron ore` + 3.5 `log` + 1 `LaTeX`).
- This recipe was suggested by @noahyor. It requires a bit of wood, a bit of copper, a bit of rubber, and a bit of iron, so a nice mid-game recipe (you need to already have a drill, but not much else).
- Get rid of the `install` command
- Update all "install" references to "equip"
- Start `base` with a `welder` in classic mode, and in `world101` and `farming` tutorials.
- The `base` used to be able to install stuff on itself with `install base`, so this is just preserving the capabilities the base already had.
- Require a `welder` as catalyst for making `tank treads`
- No particular reason, just seemed like fun.
As I've been playing around in classic mode I've found it a bit annoying/unbalanced that although you can use `ishere : text -> cmd bool` to check for the presence of a *specific* entity, the only way to check whether a cell is empty is to write something like
```
def is_empty : cmd bool =
s <- scan down;
return (s == inl ())
end
```
However, this requires having a `comparator` and an `ADT calculator` --- the latter in particular is quite difficult to construct. So, I propose adding a primitive `isempty : cmd bool`. Note this doesn't make `scan` useless --- it's more powerful still since it lets you find out the name of anything (even stuff not in the current cell).
An alternative might be to get rid of `ishere` as well (since it can also be programmed in terms of `scan`), but tons of obvious early-game automation (*e.g.* harvesting a tree plantation) depends on being able to have conditionals based on the presence or absence of certain entities, and it would be unreasonable to have that depend on making an `ADT calculator`.
The `scanner` now provides quite a few commands; I think that's OK but chime in if you think we ought to split it into multiple devices. I think it makes sense to have `scan`, `ishere`, and `isempty` all provided by `scanner` since it's just providing several interfaces to the same "service", one general and several simpler but easier-to-use versions. If we split anything out it could make sense to split out `blocked` (`laser range finder`, perhaps?) and/or `upload`.
Define a new command `heading : cmd dir` which returns the robot's current heading (or `down` if it doesn't have one, or if the heading is some weird vector).
My immediate motivation is that I want to be able to define `excursion : cmd unit -> cmd unit` which executes the given command and then returns to the same location and orientation as before. The `heading` command is one of the last missing pieces of machinery necessary to be able to implement this.
Closes#306. Closes#931.
- Renamed `robot` type to `actor` in anticipation of meeting other things besides robots.
- `meet : cmd (unit + actor)` returns an arbitrary actor within Manhattan distance 1, if any.
- `meetAll : (b -> actor -> cmd b) -> b -> cmd b` will run on every nearby actor.
- Added `antenna` device to provide the commands.
- Added "make a friend" challenge that requires the use of `meet`.
Following the discussion on #847. In theory, any functions involving `text` can be implemented using `toChar`, `++`, `charAt`, and `chars`.
Note that building a length-n `text` value by repeatedly using `++` with singletons created via `toChar` takes $O(n^2)$ time. This could be relevant if e.g. implementing something like `mapText` to convert every character to uppercase. Hopefully this will be infrequent and not too bad for small `text` values. For more performant creation of large `text` values we can wait for #98.
All changes should be non-semantic (e.g., only in code comments).
I am brand new to Swarm, apologies if I misinterpreted something (thinking particularly of "entites") as a typo that is not; happy to revert those if so.
Code itself is not changed, so `ignoredEntites` remains, though I expect it should be `ignoredEntities` (with an "i" added).
- bump extension version to 0.0.6
- fix highlighting
- do not let an "empty decimal" (`[0-9]*`) match every time. 😉
- add snapshot test
- add VSCode GitHub Action to build and test
- add VSCode GitHub Action to release the extension
- it is triggered when pushing a tag `swarm-language-vscode-*`
- closes#609
* Add a `cotton` entity that grows in some of the places there used to be flowers
* 4 `cotton` make one `string`, with a `small motor` catalyst. Currently, `string` serves no purpose except being an ingredient for `net`, but I imagine we can find other fun things to do with `string`s.
* 256 `string` make one `net`.
* A `net` is a device that enables the `try` command.
This is intentionally a bit on the harder side to construct. You need to set up some good automation to be able to crank out the nets if you want to be able to use `try` on your robots.
Closes#132.
- use `LogEntry` for said messages
- add fields to log entries for sorting
- add a messages panel that also shows logs (logger required)
- colour messages (also in logger)
- logs bold, message colour per robot and exceptions red
- show message time
- test notifications for new messages
- add `listen` command and capability
- add a hearing aid device that provides the capability
- move the F-key modal hints to the top left world corner
- close#513
- close#512
- close#577
- update the highlighting for `require` in editors
- bump VSCode plugin version to 0.0.5
- update VSCode plugin changelog
- update the VSCode plugin image link
- copy LICENSE to the VSCode folder (`vsce` was complaining about it)
- rename the team in LICENSE file to Swarm
- closes#548