Commit Graph

55 Commits

Author SHA1 Message Date
Karl Ostmo
b8d37a9364
extract doc generator to separate executable (#1671)
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
2023-12-04 03:45:07 +00:00
Karl Ostmo
37cae2ac15
Implement entity tags and commands (#1635)
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`.
2023-11-20 00:01:46 +00:00
Karl Ostmo
bd2de6c9b0
structure recognition enhancements (#1618)
* 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.
2023-11-14 18:08:02 +00:00
Karl Ostmo
d63e7d81ef
Structure browser and recognizer (#1579)
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
2023-11-08 06:44:27 +00:00
Karl Ostmo
93bbbe3dd0
ping command (#1541)
Closes #1535
# Demo

    scripts/play.sh -i scenarios/Testing/1535-ping/1535-in-range.yaml --autoplay
2023-09-24 07:49:48 +00:00
Karl Ostmo
e06e04f622
Pathfinding command (#1523)
Closes #836

# Tests
    scripts/run-tests.sh  --test-arguments '--pattern "Pathfinding"'

# Demo

    scripts/play.sh -i data/scenarios/Testing/836-pathfinding/836-automatic-waypoint-navigation.yaml --autoplay
2023-09-19 06:21:03 +00:00
Gagan Chandan
c150b05fb0
Add syntax highlighting and LSP configuration for Vim/Neovim (#1518)
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.
2023-09-13 22:11:29 +00:00
Karl Ostmo
f21a64f60c
Include VS Code workspace settings in repo (#1478)
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.
2023-08-28 19:48:29 +00:00
Ondřej Šebek
7cd7bde746
Publish VSCode extension under swarm-game everywhere (#1477)
* 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
2023-08-28 18:20:31 +00:00
Karl Ostmo
bfc0c143b8
Validate scenarios against json schema (#1475)
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.
2023-08-28 02:34:03 +00:00
Ondřej Šebek
9eeaf71c08
Add changelog for VSCode plugin 0.0.9 (#1447)
* add entry to CHANGELOG for new plugin version
* bump plugin version number
2023-08-23 09:34:18 +00:00
Karl Ostmo
da6ad0c874
combustion (#1432)
Closes #1355

# Demo

    scripts/play.sh -i data/scenarios/Testing/1355-combustion.yaml --autoplay

![image](https://github.com/swarm-game/swarm/assets/261693/eda5d1c7-35fa-4fce-865d-a87c83923c61)
2023-08-21 02:23:52 +00:00
Karl Ostmo
e8ea33927b
Implement 'backup' command (#1400)
Closes #1399.

## Demo

    scripts/play.sh --scenario data/scenarios/Testing/1399-backup-command.yaml --autoplay
2023-08-01 19:43:46 +00:00
Karl Ostmo
cfb1e92666
waypoints and portals (#1356) 2023-07-11 18:58:32 -07:00
Karl Ostmo
a30b6ed0c9
planar direction sum type (#1358)
Simplifies some existing and planned code.
2023-07-10 15:15:34 +00:00
Karl Ostmo
67871a59d2
Density command (#1296)
Closes #1295
2023-06-01 16:28:10 +00:00
Karl Ostmo
4bcf1b9317
'use' command (#1287)
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
2023-05-30 17:47:14 +00:00
Brent Yorgey
2487737d1d
halt command (#1256)
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.
2023-05-19 13:06:20 +00:00
Karl Ostmo
da7190a0b4
Implement push command (#1235)
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.
2023-04-29 20:57:55 +00:00
Karl Ostmo
2dddea136e
unrestricted variant of atomic (#1231)
Closes #1227.

Demo:

    scripts/play.sh --scenario data/scenarios/Challenges/word-search.yaml --autoplay
2023-04-29 16:23:51 +00:00
Karl Ostmo
ffafb8bfa6
implement stride command (#1219)
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.
2023-04-25 17:35:33 +00:00
Brent Yorgey
599225f4d6
Key input handler (#1214)
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.
2023-04-25 16:39:59 +00:00
Karl Ostmo
1795e12f21
scout command (#1209)
Closes #1207

This PR also involves some refactoring that simplifies more return values in `Step.hs` with `asValue`.
2023-04-18 20:35:38 +00:00
Karl Ostmo
2e6207e4aa
Implement 'watch' and 'surveil' (#1201)
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
2023-04-16 21:53:58 +00:00
Karl Ostmo
dc90996db1
resonate command (#1204)
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.
2023-04-09 04:13:11 +00:00
Karl Ostmo
9e2f8b2961
sniff/chirp commands (#1181)
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.
2023-03-29 05:51:53 +00:00
Karl Ostmo
39de6b9638
Implement 'detect' command (#1170)
Closes #1140
2023-03-20 23:36:44 +00:00
Karl Ostmo
cd67ec32ca
let-in syntax highlighting (#1162)
Currently, the syntax highlighter matches any word prefixed with `in`, e.g. `inL` or `inner` is matched.  This PR adds a word boundary to the regex.
2023-03-17 17:27:30 +00:00
Chris Casinghino
4e921403a5
Fix broken link to emacs mode (#1160)
The link to the emacs mode in `editors/README.md` was broken.
2023-03-15 12:35:13 +00:00
Brent Yorgey
f2fa93e33f
The great install/equip switch (#989)
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.
2023-01-10 11:42:10 +00:00
Brent Yorgey
dd28529d61
Add isempty : cmd bool to check whether current cell has an entity (#968)
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`.
2023-01-06 21:15:26 +00:00
Brent Yorgey
d62d8c55e9
New heading command (#955)
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.
2023-01-04 19:02:49 +00:00
Karl Ostmo
ff2fae19fa
Nested sum type for directions (#949)
Code simplification, improved type safety (see [this comment](https://github.com/swarm-game/swarm/pull/876#discussion_r1029843033)).

This technique may also simplify the implementation of `CReverse` (see #950) if we choose to do so.
2023-01-03 19:07:18 +00:00
Brent Yorgey
926cede91a
Meeting other robots (#920)
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`.
2022-12-22 20:36:11 +00:00
Karl Ostmo
e07b2c7e5b
implement Equip/Unequip (#887)
See [comment](https://github.com/swarm-game/swarm/issues/883#issuecomment-1340347523) on #883
2022-12-14 20:27:29 +00:00
Brent Yorgey
95680d7121
Add generic construction and elimination functions for text type (#861)
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.
2022-12-14 16:46:29 +00:00
Brian Wignall
10af601ca3
Fix typos (#850)
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).
2022-11-11 15:00:55 +00:00
Brent Yorgey
e3ab68c3de
update editors syntax with unit type (#814) 2022-11-01 12:24:41 -05:00
Ondřej Šebek
33fb9b23c9
Update editors with void and tweak VSCode coloring (#812) 2022-11-01 17:25:50 +01:00
Ondřej Šebek
e1b4733f66 Bump VSCode plugin version 2022-10-06 23:18:10 +02:00
Ondřej Šebek
5fad2d9a91 VSCode 0.0.7 release 2022-10-06 23:11:41 +02:00
Ondřej Šebek
73a8784aba
Add split and text length functions (#720)
- add `split: int -> text -> (text * text)`
- add `chars: text -> int`
- test using property tests
2022-10-06 11:23:15 +00:00
Ondřej Šebek
1b3e622655
Add swap command (#685)
- closes #684
- closes #680
2022-09-17 11:21:26 +00:00
Ondřej Šebek
c290ecc149
Fix VSCode highlighting (#667)
- 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
2022-09-08 21:06:26 +00:00
Brent Yorgey
b3651e2e9a
Add cotton, strings, and nets (#658)
* 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.
2022-09-04 20:38:14 +00:00
Ondřej Šebek
c3471fb01e
Improve say, add listen command and F5 messages (#565)
- 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
2022-08-03 21:27:37 +00:00
Ondřej Šebek
5f541fff91
Update editors (#581)
- 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
2022-07-25 00:16:23 +02:00
Brent Yorgey
4a21185e8f
Add time command and UI clock (#567)
Add `time` capability and related things:
- Add a new constant `time : cmd int`
- Make `clock` device provide `time` capability
- If the focused robot has a `clock` device installed (`base` has one by default in classic mode), display hexadecimal time in bottom left of the world panel.
- Add binary, octal, and hexadecimal integer literal syntax to the language.
- Make 16 ticks/s the default speed
    - The old default, 8 ticks/s, was annoyingly slow
    - Now you can simply type in `0x` followed by all the digits in the clock display, followed by a single trailing 0, to get the `time` in ticks

#402 discussed the possibility of having the `wait` command also require the `time` capability.  This breaks a number of tests which rely on the `wait` command.  I can fix the tests of course, but I'd like some feedback on whether requiring a `clock` in order to `wait` is a good idea.

Closes #402.
Closes #559.
2022-07-20 02:06:49 +00:00
Brent Yorgey
00b4e55115
New atomic syntax for blocks to be executed atomically (#553)
Provide a new `atomic` construct; when a robot is executing `atomic c` it is guaranteed that no other robots will execute any commands while the robot is executing `c`.  Maybe this isn't all that plausible physically, but I guess we can imagine that the base is in communication with all robots and implements some kind of global lock mechanism.

- Closes #479. `grabif`, `harvestif`, and `placeif` can all be implemented simply in terms of `atomic`.  For example:

    ```
    def grabif : string -> cmd bool = \thing.
      atomic (
        b <- ishere thing;
        if b {grab; return true} {return false}
      )
    end
    ```

    ```
    def placeif : string -> cmd bool = \thing.
      atomic (
        res <- scan down;
        if (res == inl ()) {place thing; return true} {return false}
      )
    end
    ```

- The argument to an `atomic` block must have type `cmd a` for some type `a`.
- `atomic` blocks have some restrictions to ensure they can't run for a long time:
    - No `def`, `let`, or lambdas are allowed
    - Variables can only be referenced if they are bound locally or have a "simple type" (= sums and products of base types; no `cmd`, `delay`, or function types)
    - Taken together, these ensure that computations can't be duplicated, and any variables referenced must contain simple data values which have already been evaluated, which means that an argument to `atomic` will have an execution time no more than linear in its length.
- `atomic` blocks also can't be nested, just because that seems weird and I don't know what the purpose would be
- `atomic` blocks may contain at most one "external" command which normally requires a tick to execute.  Allowing *e.g.* multiple `move` commands in an `atomic` block would be problematic: it would either mean that robots could use `atomic` blocks as a way to execute faster than normal, or that we would have to freeze other robots for multiple ticks while some robot executed its atomic block.  But typically, we want to do some kind of sensing command (which is an internal command that doesn't require a tick) + some external command.
- Relatedly, also refactored the notion of external/internal commands so that information is now stored in the `ConstInfo` record.  This means from now on we will be required to declare whether each new constant is internal or external; we hadn't been keeping up with the old definition of `takesTick` at all.
- Add the `rubber band` device which allows doing `atomic`, and make a recipe for it (`rubber` + `strange loop`).
    - This is a fairly simple recipe, but being able to do `atomic` early can be helpful for setting up automatic resource production pipelines.
2022-07-17 03:24:12 +00:00
Brent Yorgey
eb205e61a9
Add require directive (#533)
Add new special syntactic forms `require <string literal>` to require a device to be installed, and `require <int literal> <string literal>` to require a certain number of a given entity in the inventory.

- Replace `Set Capability` with a new `Requirements` type which records various types of requirement.
- Refactor requirements checking into a new function `checkRequirements` which also does device set minimization (#508).  
- `reprogram` will now install extra devices or transfer extra inventory as necessary.
- Add a bunch of tests.
- Add new `installed` command, similar to `has`, which checks whether a given device is installed.

Closes #201.
Closes #508.
2022-07-05 22:36:06 +00:00