Commit Graph

1175 Commits

Author SHA1 Message Date
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
96eda89d61
render scenario description as markdown (#1521)
![image](https://github.com/swarm-game/swarm/assets/261693/ff735f42-fc67-4734-99e3-15e4df27116c)
2023-09-12 17:08:20 +00:00
Karl Ostmo
bb31126c75
Decompose GameState into sub-records (#1510)
Towards #872

Previously, the `GameState` record had `41` toplevel members.  It now has `22`.   Logical grouping of the fields makes it easier to peruse the code and paves the way to split `State.hs` into smaller modules.  Some functions now may even be able to operate exclusively on subsets of the game state, rather than having to pass in `GameState` as a whole.

There is potential to go even farther, by extracting view-related and robot-related members to their own records, but I figured I'd pursue this refactoring incrementally.
2023-09-11 18:25:45 +00:00
Brent Yorgey
41c94f1dc1
Grant RobotIntoWater achievement (#1504)
Towards #1435.  Some refactoring, + grant `RobotIntoWater` achievement when a robot dies in the water.
2023-09-11 14:49:54 +00:00
Karl Ostmo
0c311b4323
Replace/quarantine uses of head and NE.fromList functions (#1503)
Towards #1494

* Totally eliminates partial `head`
* introduces an hlint rule to ban unsafe use of `head`
* restricts use of the partial `fromList` from `NonEmpty`
2023-09-10 12:03:56 +00:00
Karl Ostmo
b014062370
Add footer to goals dialog (#1509)
# Before
![Screenshot from 2023-09-09 19-47-34](https://github.com/swarm-game/swarm/assets/261693/2aac5717-8cb0-44da-a8dc-17bfa36f297c)

# After
![Screenshot from 2023-09-09 19-58-32](https://github.com/swarm-game/swarm/assets/261693/da4b303e-9715-48ef-8b87-2f0f2a7682dd)
2023-09-10 11:50:37 +00:00
Brent Yorgey
db15c05f9f Revert "add Achievements directory to Testing/00-ORDER.txt"
This reverts commit e37eb6d5f8.

Accidentally pushed this to `main` instead of the `robot-into-water` branch.
2023-09-10 01:02:25 -05:00
Brent Yorgey
e37eb6d5f8 add Achievements directory to Testing/00-ORDER.txt 2023-09-10 00:50:19 -05:00
Karl Ostmo
318b9394fa
Support markdown in achievement descriptions (#1508)
# Before

![Screenshot from 2023-09-09 19-36-21](https://github.com/swarm-game/swarm/assets/261693/b126642a-1fdc-4eaf-9b17-53a5554a6ea9)

# After

![Screenshot from 2023-09-09 19-37-34](https://github.com/swarm-game/swarm/assets/261693/472e084c-51d8-49d9-9996-41f976617dfc)
2023-09-10 04:57:40 +00:00
Karl Ostmo
f9a1c31c7f
Fix build error regarding 'tasty' bounds (#1505)
[Build error](https://github.com/swarm-game/swarm/actions/runs/6133922036/job/16646223425?pr=1503) was:
```
Test/Tasty/QuickCheck.hs:30:43: error:
    Module ‘Test.Tasty.Runners’ does not export ‘emptyProgress’
   |
30 | import Test.Tasty.Runners (formatMessage, emptyProgress)
   |                                           ^^^^^^^^^^^^^
Error: cabal-3.10.1.0: Failed to build tasty-quickcheck-0.10.3. See the build log above for details.
```
2023-09-10 01:04:28 +00:00
Brent Yorgey
096251d9cb
generalize variables bound by <- (#1501)
Closes #351.

I sat down with @ccasin today to look at #351. He convinced me that it is actually fine to return `forall a. a -> a` as the type of `r` in `r <- return (\i.i)`, even though `return (\i.i)` has type `forall a. cmd (a -> a)` and we can never have a type `cmd (forall a. a -> a)`. Basically, in a Hindley-Milner-style system it is always safe to generalize at any time.

The real problem --- which I was very close to discovering in https://github.com/swarm-game/swarm/issues/351#issuecomment-1146274801 --- is simply that we need to generalize the type of variables bound by `<-`.  However, we need to make sure to do so before putting that variable in the context, which I apparently failed to do when I tried fixing this before.
2023-09-09 17:36:43 +00:00
Karl Ostmo
ae70790278
Use NonEmpty to eliminate some partial functions (#1499)
As title.
2023-09-09 15:00:28 +00:00
Karl Ostmo
25f6fdefbd
add more markup to scenario descriptions (#1500)
![Screenshot from 2023-09-08 20-09-32](https://github.com/swarm-game/swarm/assets/261693/1831ff2a-d62a-48e1-908b-e613d4e69cf1)
2023-09-09 14:23:28 +00:00
Brent Yorgey
8ffd05665b
Add solution for world101 tutorial (#1498)
Closes #1450.

## Demo

    scripts/play.sh -i data/scenarios/Tutorials/world101.yaml --autoplay
2023-09-09 05:55:58 +00:00
Brent Yorgey
008f0628be
Use raw (unelaborated) AST for pretty-printing in Markdown (#1497)
Fixes #1496.
2023-09-08 14:37:08 +00:00
Karl Ostmo
98ebf74cfe
more documentation tweaks (#1493)
Also:
* adds a script to view locally-generated Haddocks.
* Describes module organization as per https://github.com/swarm-game/swarm/pull/1069#issue-1565024308 in the toplevel cabal package description
2023-09-07 07:00:44 +00:00
Karl Ostmo
1aa92d01ea
Robot activity counts in F2 menu (#1484)
Towards #1341.

    scripts/play.sh -i data/scenarios/Testing/1341-command-count.yaml --autoplay --speed 1

![image](https://github.com/swarm-game/swarm/assets/261693/f658bb9c-6bb8-494c-b204-6d5bb0106b92)
2023-09-07 06:00:07 +00:00
Brent Yorgey
deef46ea15
Some documentation improvements + refactoring (#1488)
Some idle documentation improvements done on a plane.
2023-09-05 14:28:34 +00:00
Brent Yorgey
1024d2df1e
Print REPL errors inline and get rid of error popup (#1487)
Closes #1461.  Errors which used to be displayed in a pop-up window (parse errors, type errors) are now displayed inline in the REPL window instead.

- Get rid of the pop-up error dialog
- Also fix a bug introduced in #1481 where the REPL history would not be properly cleared when first starting a new scenario, because the old cache was still being used
2023-09-05 03:44:02 +00:00
Brent Yorgey
15dd824c6a
Improvements to scrolling (#1481)
- Add scrollbars on both the inventory and info panels
- Get rid of `. . .` at top and bottom of info panel, since we now have scrollbar as a visual indicator when there is more content
- Allow scrolling the REPL history (closes #60)
    - PgUp/PgDown can be used to scroll (Shift+PgUp/Dn were not recognized on my system)
    - Hitting any other key causes the view to jump back to the very bottom
    - A computation finishing + printing an output also causes the view to jump to the bottom
    - The REPL history is cached so that it only gets re-rendered whenever a new history entry (i.e. input or output) is added; this is needed since the history could get quite large.
- Also, fix the height of the key hint menus to 2 lines, even when the panel-specific menu (second line) is blank, so the world panel does not keep resizing as we move the focus between panels.

Thanks to @jtdaugherty for releasing `brick-1.10` with a new ability to specify blank space to the side of scrollbars; see https://github.com/jtdaugherty/brick/discussions/484 .

Also towards #1461 .
2023-09-03 04:51:01 +00:00
Karl Ostmo
56febd9e41
Show robot IDs (#1482)
Closes #1437

![Screenshot from 2023-08-30 13-04-29](https://github.com/swarm-game/swarm/assets/261693/d8a6dadf-e930-4ce6-861f-56ee8e54208e)
2023-08-30 20:23:21 +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
2fe7181fc4
Allow specific format width (#1476)
* 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.
2023-08-28 19:11:26 +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
09f8aee9fc
Make CLI format format (#1459)
- closes #1185
2023-08-26 17:47:17 +00:00
Ondřej Šebek
10663779a7
Move traversable documentation to derived instance (#1472)
This should render the documentation in haddock according to this blog:
https://kowainik.github.io/posts/haddock-tips#what-can-be-documented

It does not for me (maybe it will in release?), but at least it's where it belongs.
2023-08-26 17:31:30 +00:00
Ondřej Šebek
64fe02892b
Fix lambda precedence (#1470)
- give lambdas lower precedence (9) then application (10)
- closes #1468

Before (with #1459):
```
❯ cabal run swarm -O0 -- format <(echo '\\m. case m (\\x. x + 1) (\\y. y * 2)')
\m. case m \x. x + 1 \y. y * 2
```

After:
```
❯ cabal run swarm -O0 -- format <(echo '\\m. case m (\\x. x + 1) (\\y. y * 2)')
\m. case m (\x. x + 1) (\y. y * 2)
```
2023-08-26 17:18:13 +00:00
Ondřej Šebek
61df42e7b9
Test runtime log does not contain errors (#1457)
- closes #1449
2023-08-26 13:29:05 +00:00
Ondřej Šebek
98a6b75ea1
Make pretty Terms format prettier (#1464)
- improve layout of terms:
  - break lines on binds, unless it fits on one line
  - lambdas go on same line, but the body _can_ go to next line
  - def and let can have long body on next line (indented for def)
  - parens and braces have body indented if it does not fit on line
- closes #11

Example using `--format` from #1459:

```
> cabal run swarm -O0 -- format scenarios/Challenges/_blender/patrol-clockwise.sw                          
def forever = \c. c; force forever c end;
def encircle = \lDir. \rDir.
  turn lDir;
  b <- blocked;
  if b {turn rDir} {wait 1};
  fwBlocked <- blocked;
  if fwBlocked {turn rDir} {move}
end;
def patrolCW = force forever (force encircle right left) end;
force patrolCW
```
2023-08-25 21:08:32 +00:00
Ondřej Šebek
e57c60ba9a
Erase the erase function (#1460)
* simplify the `erase` function using the `Functor` instance
2023-08-24 21:11:26 +00:00
Brent Yorgey
d0783bc832
fix PrettyPrec Entry instance (#1463)
Closes #1462.

To demonstrate, *e.g.* temporarily remove `names.txt`.  Without this patch, you will get an error message saying `The 0 is missing!`.  With this patch, it now correctly says `The file is missing!`.
2023-08-24 18:56:04 +00:00
Ondřej Šebek
8ed5b92edc
Add robot ownership to integration test suite (#1451)
- followup to #1431
- remove the warning seen in #1449
2023-08-23 13:03:10 +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
Ondřej Šebek
8a1743382d
Normalise versions for comparison (#1448)
* make sure that `0.4` and `0.4.0.0` are the same

This fixes the issue worked around by 5c509d2 for future releases.
2023-08-23 09:33:35 +00:00
Brent Yorgey
5c509d23d6
Update metadata after publishing latest blog post (#1445)
Should have included this in #1444 .
2023-08-22 17:51:30 +00:00
Brent Yorgey
fb7d2eaeb9
0.4 release blog post (#1444)
Blog post highlighting cool features in the newest release.

Also fix the version number in the .cabal file from 0.4 to 0.4.0.0. It's too late for the release (it always reports there is a new version available since 0.4.0.0 does not match 0.4) but oh well.
2023-08-22 12:35:05 -05:00
Karl Ostmo
6345de17d1
various documentation improvements (#1439)
formatting, licenses, adding info
2023-08-21 19:55:26 +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
Brent Yorgey
0bed202e82
Add a pull request template (#1434)
Adds a pull request template with some reminders for anyone opening a pull request.   They are phrased as reminders, not a checklist, since I don't want to make this a barrier to contributions.

Closes #1429.
2023-08-20 19:43:27 +00:00
Karl Ostmo
6f8716f3ea
system robots should build system robots (#1431)
Closes #1430.

# Demo

    scripts/play.sh -i data/scenarios/Testing/1430-built-robot-ownership.yaml

Before, pressing `F2` would show two robots: the `base` and the system-built robot.
Now, only the `base` is shown, as the built robot is properly classified as another system robot.
2023-08-18 19:30:38 +00:00
Brent Yorgey
e5e8ea5dac
0.4 release (#1321)
Closes #1316 .
2023-08-18 02:35:43 +00:00
Brent Yorgey
888ee44d18
World description DSL (#1376)
DSL for programming worlds, towards #1320 and #29 (and, indirectly, toward #50, since the world DSL should make a nice target for world saves) .  Eventually this should be able to recreate all the world description/building features we have, though there is still a long way to go.  But currently we can at least recreate the "classic" procedurally-generated world.  I think this is a solid foundation we can merge as a first step, and then work on adding more features in subsequent PRs.  Below are some notes that should help in reviewing.  Note that the large number of files changed is due in large part to the elimination of the `default` field in scenario descriptions; see the "changed files" section below for an overview of the important/interesting changes.

Issues split off from this one: #1394 #1395 #1396 #1397 

Major changes
============

- New `data/worlds` subdirectory
    - All `.world` files are parsed at load time and saved in a `WorldMap` which gets threaded through, similar to `EntityMap` (perhaps we should think about passing around a single record instead)
- Standard "classic" world
    - Used to be `testWorld2`, defined in Haskell code; now it is defined via the DSL in `worlds/classic.world`.  This should make it much easier to experiment with variations.
    - We can now automatically extract entities mentioned in a world DSL term with `extractEntities`.  There used to be an explicit list in `testWorld2Entities`, used to check pedagogy, generate documentation, etc., but it turns out it had (predictably) gotten out of date!  This can't happen anymore.
    - It is now referenced in several tutorials (backstory, farming, world101, speedruns, etc.)
- The `default` field of world descriptions is no more: one can use `dsl` to just specify a constant
    - Note in `Swarm.Game.State`, `dslWF` and `arrayWF` are combined using the `Monoid` instance to create `wf`.
- `Erasable`
    - It used to be the case that if some kind of default terrain + entity was specified (e.g. stone + water), any `map` would completely override the default.  However, we want to move towards combining everything with a `Monoid` instance.  But by default this means the default entity would show through anywhere the `map` did not specify an entity.  So we need a way to explicitly "erase" an entity from a lower layer.
    - If `e` is a `Semigroup`, then `Maybe e` is a `Monoid` where `Nothing` acts as an identity element.  Likewise, `Erasable e` is a `Monoid` but adds two new elements: `ENothing` to be an identity, and `EErase` to be an *annihilator*.  i.e. combining with `EErase` is like multiplying by zero.
    - We can now specify `erase` as an entity to override entity underneath.
    - There are several Haskell files with only changes related to `Erasable`, relating to e.g. the world editor, `PCells`, etc.; I'm not 100% sure I've always done the right thing here.

DSL overview
===========

- Integer, float, and Boolean literals.  Note that `3` is *always* an `int`, and `3.0` is a `float`.  It makes things much easier to not have to deal with `3` possibly being either `int` or `float`, though it does make things slightly more annoying for programmers.
- Standard boolean, arithmetic, and comparison operators
- `if ... then ... else ...`
- `<>` operator for combining via `Semigroup` instance
- Cell literals are enclosed in curly braces.  Unlike the previous awkward world description syntax with one, two, or three-element lists denoting terrain, terrain + entity, or terrain + entity + robot, there can now be any number of elements in any order.
    - `{foo}` will be resolved as either terrain, an entity, or a robot, whichever is successful.  So if the names are unambiguous one can just write `{tree}` or `{stone}`.
    - It is possible to explicitly indicate the type of cell value with syntax like `{entity: tree}` or `{terrain: stone}`.
    - Multiple items separated by commas is syntax sugar for combining with `<>`.  e.g. `{tree, entity: boulder, stone} = {tree} <> {entity: boulder} <> {stone}`.
- Ability to refer to the `seed`
- Refer to the current `x` or `y` coordinates or the `hash` of the current coordinates
- `let`-expressions for multiple variables: `let x1 = e1, x2 = e2, ... in ...`
- `overlay [e1, e2, ...]` layers `e1` on the bottom, `e2` on top of that, etc., using the `Semigroup` instance for world functions
- `"foo"` imports the DSL term in `worlds/foo.world`
- `perlin` function to generate perlin noise
- `mask` function to mask with a condition

Changed files
===========

- `Swarm.Util`: moved the `acquire` function here and gave it a more descriptive name.
- `Swarm.Doc.Gen`: can now extract mentioned entities directly.
- `Swarm.Game.Failure`: added new failure modes
- `Swarm.Game.Scenario.Topography.WorldDescription`: get rid of `defaultTerrain` field, add `worldProg` for DSL.
- `Swarm.Game.State`: see comment.
- `Swarm.Game.World`: a bit of reorganization.  Added a bunch of modules under this.
    - `Swarm.Game.World.Coords`: moved some code here from `Swarm.Game.World`.
    - `Swarm.Game.World.Gen`: moved some things here from `Swarm.Game.WorldGen` (also deleted a bunch of irrelevant code), and also added the `extractEntities` function to get all entities mentioned by a DSL term.
    - `Swarm.Game.World.Syntax`: raw, untyped syntax for world DSL terms.
    - `Swarm.Game.World.Parse`: parser for world DSL terms. Fairly standard.
    - `Swarm.Game.World.Typecheck`: takes raw, untyped terms produced by the parser and both typechecks and elaborates them into a simpler core language.  An interesting feature is that the core language is *type-indexed*, so that the Haskell type system is actually ensuring that our typechecker is correct; every typechecked world DSL term value has a type which is indexed by a Haskell type corresponding to the type of the underlying DSL term.  For example, `{entity: tree}` would have a type like `TTerm [] (World CellVall)` etc.  Once terms make it through the typechecker, there cannot possibly be any bugs in the rest of the pipeline which would result in a crash, because the Haskell type system.  (There could of course be *semantic* bugs.)  Understanding exactly how the typechecker works is not too important.  Of interest may be the `resolveCell` function, which determines how we decide what `Cell` is represented by a cell expression in curly braces.
    - `Swarm.Game.World.Abstract`: compile elaborated, typechecked world DSL terms down into an extremely simple core language with only constants and function application.  This gives us very fast evaluation of world DSL terms.  Understanding this module is not really necessary but there is a link to a blog post for those who are interested in how it works.
    - `Swarm.Game.World.Compile`: a further processing/compilation step after `Swarm.Game.World.Abstract`.  Currently we don't actually use this, since it doesn't seem like it makes a big efficiency difference.
    - `Swarm.Game.World.Interpret`: interpreter for abstracted world DSL terms.
    - `Swarm.Game.World.Eval`: just puts together the pieces of the pipeline to evaluate a typechecked world DSL term.
    - `Swarm.Game.World.Load`: just loading world DSL terms from disk.
2023-08-17 11:08:42 +00:00
Karl Ostmo
0179fa61b6
add more markup to tutorial objectives prose (#1412)
Closes #1411
2023-08-15 07:06:56 +00:00
Ondřej Šebek
00a1dde159
Refactor mystery baton type (#1425)
* add more descriptive name to the mysterious `MVar` in Web API startup function
2023-08-13 20:06:43 +00:00
Ondřej Šebek
f743c90027
Render markdown in entity descriptions (#1413)
* use `Markdown.Document` as `entityDescription`
* add missing spaces in `chunksOf`
* fix code in `entities.yaml` (mostly types and few outdated snippets)
* add code markdown in craft tutorial
* use colours for types and entities

- closes #1408
- closes #1409
2023-08-12 11:42:12 +00:00
Brent Yorgey
feb426a226
Throw an error instead of crashing on impredicative types (#1418)
Towards #351.  This is not a solution to the underlying problem, but at least it prevents the game from crashing and returns a placeholder error message instead.
2023-08-08 03:32:19 +00:00
Brent Yorgey
8aea6a24be
Refactor to more consistently use "capability style" in loading + initializing code (#1392)
Closes #1122 .  General principles:

- Use `SystemFailure` as error rather than `Text` as much as possible, and use `prettyFailure` only at the very top level.
- Replace `ExceptT` with `Has (Throw SystemFailure)` constraint.
- Use `Accum (Seq SystemFailure)` constraints to accumulate warnings that should not abort computation, rather than returning a pair of a list of warnings + result.
- Use `Has (Lift IO)` constraint instead of `MonadIO`, which means using `sendIO` instead of `liftIO`.
- In general, use `runThrow` to dispatch a `Throw` constraint (results in returning an `Either`, just like `runExceptT`), and `runM` to dispatch a final `Lift IO` constraint to result in an `IO` computation.
- Use `withThrow` to adapt from one type of error to another.
2023-08-06 22:12:41 +00:00
Brent Yorgey
c69d76edf3
mention drill command in drill entity description (#1404)
Based on feedback from `__monty__` in IRC.
2023-08-05 18:28:11 +00:00
Ondřej Šebek
1eb2f9c567
Parse markdown descriptions (#1106)
* use CommonMark to parse simple markdown AST parametrised on inline/block code
* validate swarm code (`Document Text -> Document Syntax`)
* update descriptions to use markdown with following conventions:
  - `move` - valid swarm code (the easy to write default)
  - `wedge`{=entity} - for swarm entities
  - `unit`{=type} - for swarm types
  - `require <a> <b>`{=snippet} - raw snippets for invalid code
  - **Alt-G** - bold for keyboard shortcuts
- highlight code in brick widgets
- closes #309
- closes #545
- precedes #574
- precedes #1406
- precedes #1407
2023-08-05 15:39:07 +00:00