Commit Graph

1175 Commits

Author SHA1 Message Date
Karl Ostmo
8239f27247
dedicated record for randomness (#1653)
Reduces the number of fields in the toplevel `GameState` by one.
2023-11-22 21:44:31 +00:00
Karl Ostmo
4b7cb8d1af
validate display character widths (#1655)
Characters that are too wide mess up the world rendering.

## Demo

    scripts/play.sh -i data/scenarios/Testing/_Validation/1655-display-characters.yaml
2023-11-22 21:21:13 +00:00
Karl Ostmo
40f26df9a8
use built-in portal functionality for Hackman scenario (#1651)
Previously, the logic to wrap horizontally was hand-coded, both for the player (using a dedicated monitor robot) and for ghosts (who, as system robots, implemented the teleportation themselves).

Now that we can use built-in portal functionality (#1356), no custom logic is needed to handle the teleportation.  A (much-simplified) monitor robot still observes the base robot to award the hidden "World wrap" goal.

## Demo

    scripts/play.sh -i data/scenarios/Challenges/hackman.yaml --autoplay --speed 6
2023-11-22 18:18:42 +00:00
Karl Ostmo
3c970c19ff
group robot info into subrecord (#1652)
Add another subrecord to `GameState` dedicated to robot fields.  This shrinks the size of `GameState` by 8 more fields.  It's getting reasonable now!

The `_viewCenter*` fields were put there too, for now, because the manually-defined `setter` of the `viewCenterRule` lens needs access to the `robotMap` field.
2023-11-22 18:06:13 +00:00
Karl Ostmo
724650d8d9
serve static index page (#1648)
API docs are moved under `api/`, and the landing page for http://localhost:5357/ is now a static `index.html` page.

This paves the way for a JS-enabled web frontend demo.
2023-11-21 17:10:46 +00:00
Karl Ostmo
27f0d087ad
render recognized structures in bold (#1646)
Visually differentiate entities in the plane when they become part of a recognized structure.

## Demo

    scripts/play.sh -i data/scenarios/Testing/1575-structure-recognizer/1575-browse-structures.yaml --autoplay --speed 2

![image](https://github.com/swarm-game/swarm/assets/261693/71d7f3cc-40b9-4ffe-88c9-7c528cc358b3)
2023-11-21 16:58:50 +00:00
Karl Ostmo
bba15a7337
split cheatsheet generation to separate module (#1640)
Towards #1546.

This is a no-op refactoring to reduce the size of `Gen.hs` by about 200 lines.
2023-11-21 03:43:00 +00:00
Karl Ostmo
303e58db97
fix wiki table generation (#1639)
Tables were not rendering properly (same fix as #1577).

Commands table is now updated: https://github.com/swarm-game/swarm/wiki/Commands-Cheat-Sheet
2023-11-20 17:24:49 +00:00
Karl Ostmo
01a5b070e7
render map to PNG format (#1632)
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)
2023-11-20 04:37:49 +00:00
Karl Ostmo
e43ff3e915
Structure recognition with encroaching entities (#1637)
Structure recognition already supports overlapping bounding boxes between two structures (where one of the structure templates has vacant cells).  This PR adds test coverage for this.

More importantly, this PR makes sure that structures can be recognized even with non-participating entities within their bounding box.  The same integration test (`1575-bounding-box-overlap.yaml`) covers this case as well.

A "non-participating entity" is an entity that is not an ingredient to any structures participating in structure recognition.  Such entities are "masked out" when the world cells (i.e. the "haystack") are queried to apply the Aho-Corasick matcher to.

## Example

Given a structure defined as `boulder`s (`@`) in a backwards "L" shape, it will be recognized despite a `mountain` (`A`) within its bounding box:

![image](https://github.com/swarm-game/swarm/assets/261693/1c559a50-e9bd-4f97-87a1-20d4f964cfa9)

This is because `mountain` is not a member of any recognizable structures.

## Caveats

This PR strictly increases the situations in which valid structures may be recognized.

However, it is still the case that encroaching entities that **are** members of some structure template will thwart structure recognition.  One consequence of this is that the order in which structures are completed can matter.

If some partially-built but incomplete structure lies within the bounding box of another candidate structure, the candidate structure will not be recognized as "complete" unless (1) the offending entities are removed first, or (2) the other structure is completed first.
2023-11-20 04:21:14 +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
4630e89314
Decouple robot log message colors from entity colors (#1634)
This is code cleanup towards #1415, which will require some refactoring of `Attr.hs`.

## Demo

    scripts/play.sh -i data/scenarios/Testing/9999-message-colors.yaml --autoplay --speed 2

![Screenshot from 2023-11-16 17-25-14](https://github.com/swarm-game/swarm/assets/261693/1fdfa852-1acc-4ff4-93d5-7818ae858f86)
2023-11-17 04:30:39 +00:00
Karl Ostmo
ae535dee3d
achievement for giving to self (#1629)
Closes #1540.

![Screenshot from 2023-11-14 22-28-34](https://github.com/swarm-game/swarm/assets/261693/e1a1cd47-9ddf-4120-aa1a-197b2acb8d49)
2023-11-15 15:57:14 +00:00
persik
a306d05f61
Add TimeEffect effect for getting current time (#1620)
fixes #1502

Add TimeEffect effect for getting current time.
2023-11-15 06:17:09 +00:00
Brent Yorgey
8f52e53a22
Fix the stack build (#1627)
Closes #1624.

Note, however, that currently (until #1623) this will not work on Windows, since I explicitly added `vty-unix` as an `extra-dep` in the `stack.yaml` file.  However, I expect we will get #1623 soon and then we can remove it.
2023-11-15 03:23:23 +00:00
Karl Ostmo
f9ef0094f0
path caching (#1595)
Closes #1569

## Performance

Path cache invalidation upon world modifications (i.e. entities inserted or removed) entails iterating over all of the previously-cached paths [here](https://github.com/swarm-game/swarm/pull/1595/files#r1390158411).  For efficiency's sake, we avoid iterating over "all existing robots".

Any scenario that does not use the `path` command is entirely unaffected by this change.

## Demo

Previously, this demo was virtually unplayable, since when moving between widely-spaced "clusters" of flowers, an expensive A-star search was invoked at almost every tick.  Now, the vast majority of moves utilize the cache, and the demo exhibits minimal stuttering (e.g. when a single A-star search is performed when moving between distant clusters).

    scripts/play.sh -i scenarios/Fun/horton.yaml --autoplay --speed 7

### Event log

An event log specific to the path cache is maintained with its own ring buffer:

    scripts/play.sh -i scenarios/Testing/1569-pathfinding-cache/1569-harvest-batch.yaml --autoplay

 and view http://localhost:5357/paths/log
2023-11-14 21:15:00 +00:00
Chris Hackett
ca1918a443
Update to support running on Windows (#1617)
Added support for running on Windows, in command line or Powershell terminals.

Currently terminal emulators such as mintty, ConEmu, alacritty, etc are not supported.

Addresses issues #1607 and #53.
2023-11-14 20:58:34 +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
persik
aca8049789
Don't auto-complete commands that require God capability outside creative mode (#1619)
fixes #1572
Fixed auto-completion for non-creative mode
2023-11-13 19:01:32 +00:00
Brent Yorgey
3592b4ea6d
Fix REPL type display (#1610)
Make sure it again prints the type on one line, by using `prettyTextLine` instead of `prettyText` to format the type.

Fixes #1597.
2023-11-11 20:47:45 +00:00
Karl Ostmo
17299175d4
use mkReturn in more places (#1615)
`mkReturn` originally introduced in #1588.
2023-11-11 00:36:05 +00:00
Karl Ostmo
5a91c384e1
Extract pure walkability logic (#1614)
This simplifies the implementation of #1595.
2023-11-10 15:37:16 +00:00
Karl Ostmo
666850189b
indicate whether a goal is optional (#1613)
![Screenshot from 2023-11-09 14-20-49](https://github.com/swarm-game/swarm/assets/261693/f444d787-b9f9-4e79-bb44-2e005ace3e26)

![Screenshot from 2023-11-09 14-20-56](https://github.com/swarm-game/swarm/assets/261693/7a3c3dd6-6e21-47cb-a70e-5c405df20d31)
2023-11-09 23:19:07 +00:00
Brent Yorgey
96d3062550
update to megaparsec-9.6.1 (#1609)
* Update to `megaparsec-9.6.1`.  This allows us to remove any annoying workaround. 
* Bump stack resolver to LTS-21.19.
* Drop support for GHC 8.10.
2023-11-08 12:26:23 -06: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
Brent Yorgey
990195f44c
0.5 release (#1606)
Closes #1543 .
2023-11-01 10:18:16 +00:00
Karl Ostmo
3a39873437
Use rich entity modification info (#1604)
This is a refactoring that is a prerequisite for both #1579 and #1595.
2023-10-29 20:38:16 +00:00
Karl Ostmo
d3889ef3cd
Achievement for pointless swapping (#1588)
# Demo

    scripts/play.sh -i creative --seed 0

Then:

    turn right; move; turn right; move; t <- grab; move; swap t;

![image](https://github.com/swarm-game/swarm/assets/261693/eb2fb7bf-26e7-43c3-8b0b-2c92f35f9244)
2023-10-23 17:22:02 +00:00
Karl Ostmo
4f21fd89e0
combination locks scenario (#1591)
![image](https://github.com/swarm-game/swarm/assets/261693/4229e45e-5c9c-4c15-b82e-0d5a28472798)

# Demo

    scripts/play.sh -i data/scenarios/Challenges/combo-lock.yaml --autoplay
2023-10-22 05:06:19 +00:00
Karl Ostmo
96ee7f0af9
Account for symlink when applying JSON schemas (#1586)
This allows the validation to work in VS Code if one happens to open the symlinked version of a scenario file, which is easy to do accidentally via CTRL+P.
2023-10-18 14:41:36 +00:00
Ondřej Šebek
2c3fc525c9
Add wave program to benchmarks (#1576)
* add wave program and parametrise it to compare inlined/generic version
* use [`tasty-bench`](https://hackage.haskell.org/package/tasty-bench) library to show comparison
* move benchmarks to test folder as they can now share tasty code
* closes #1574 

Using the recursive definition with ifs leads to a 3x slowdown:
```
wavesInlined
  10: OK
    361  ms ±  29 ms
  20: OK
    718  ms ±  35 ms
  30: OK
    1.066 s ±  28 ms
  40: OK
    1.437 s ±  37 ms
wavesWithDef
  10: OK
    1.052 s ±  51 ms, 2.92x
  20: OK
    2.117 s ±  34 ms, 2.95x
  30: OK
    3.144 s ±  80 ms, 2.95x
  40: OK
    4.191 s ±  91 ms, 2.92x
```
But if we just inline and simplify the code, we can remove the runtime overhead completely.
2023-10-09 04:45:27 +00:00
Karl Ostmo
4e886e0c3c
Autogenerate scenario schema doc (#1441)
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
2023-10-09 02:11:30 +00:00
Karl Ostmo
85536b840e
command types on one line (#1577)
# Before

![image](https://github.com/swarm-game/swarm/assets/261693/c576927d-944b-4cdf-8c73-5b50ede94691)


# After

![image](https://github.com/swarm-game/swarm/assets/261693/5c406f57-080d-4e5f-9543-dc7348e48dea)
2023-10-09 01:48:45 +00:00
Ondřej Šebek
694e00b678
Make function chains pretty (#1479)
- closes #1473
2023-10-07 21:04:01 +00:00
Brent Yorgey
11053c4065
Restore the "classic world" background for friend challenge (#1566)
This was broken by #1376.  Any challenge which did *not* specify a `default` field would have had the classic world as an implicit background, but in this case I failed to add the proper `dsl` field to specify it.  I don't *think* there are any other such challenge scenarios, although to be really sure we would have to identify all the scenarios did not specify a `default` field before #1376 was merged and ensure that each of them now has an appropriate `dsl` field.

Before:

![before](https://github.com/swarm-game/swarm/assets/533859/4756e889-5455-4a88-b114-ae00df79555c)


After:

![after](https://github.com/swarm-game/swarm/assets/533859/9004e108-5c39-4de9-a2fe-c60e38b63ca0)
2023-10-07 19:58:26 +00:00
Karl Ostmo
346f960085
more partial function bans (#1564)
Towards #1494.

Replaced/restricted uses of `Prelude.tail` and `Prelude.!!`.  Quarantined `undefined`.

Introduced a new function `listEnumsNonempty` that is guaranteed safe.
2023-10-02 03:13:20 +00:00
Karl Ostmo
b82b0f7c6a
use Int64 for time (#1491)
Should benchmark this to see if it's faster than `Integer`.

# `stack bench` output
Personally, I'm not sure what the best way to benchmark this particular change, but here's the output of `stack bench` anyway:
## Before
```
benchmarking run 1000 game ticks/idlers/10
time                 2.634 ms   (2.629 ms .. 2.641 ms)
                     1.000 R²   (1.000 R² .. 1.000 R²)
mean                 2.636 ms   (2.634 ms .. 2.640 ms)
std dev              10.45 μs   (6.667 μs .. 15.88 μs)
                   
benchmarking run 1000 game ticks/idlers/20
time                 2.660 ms   (2.653 ms .. 2.668 ms)
                     1.000 R²   (1.000 R² .. 1.000 R²)
mean                 2.661 ms   (2.657 ms .. 2.667 ms)
std dev              18.53 μs   (12.24 μs .. 30.77 μs)
                   
benchmarking run 1000 game ticks/idlers/30
time                 2.660 ms   (2.653 ms .. 2.670 ms)
                     1.000 R²   (1.000 R² .. 1.000 R²)
mean                 2.685 ms   (2.678 ms .. 2.696 ms)
std dev              29.12 μs   (20.64 μs .. 42.37 μs)
                   
benchmarking run 1000 game ticks/idlers/40
time                 2.693 ms   (2.686 ms .. 2.700 ms)
                     1.000 R²   (1.000 R² .. 1.000 R²)
mean                 2.694 ms   (2.689 ms .. 2.705 ms)
std dev              26.61 μs   (17.81 μs .. 45.78 μs)
                   
benchmarking run 1000 game ticks/trees/10
time                 2.627 ms   (2.623 ms .. 2.632 ms)
                     1.000 R²   (1.000 R² .. 1.000 R²)
mean                 2.625 ms   (2.622 ms .. 2.629 ms)
std dev              12.55 μs   (8.749 μs .. 18.38 μs)
                   
benchmarking run 1000 game ticks/trees/20
time                 2.647 ms   (2.642 ms .. 2.653 ms)
                     1.000 R²   (1.000 R² .. 1.000 R²)
mean                 2.648 ms   (2.645 ms .. 2.656 ms)
std dev              17.86 μs   (10.58 μs .. 31.07 μs)
                   
benchmarking run 1000 game ticks/trees/30
time                 2.672 ms   (2.667 ms .. 2.676 ms)
                     1.000 R²   (1.000 R² .. 1.000 R²)
mean                 2.673 ms   (2.668 ms .. 2.683 ms)
std dev              22.85 μs   (14.67 μs .. 38.46 μs)
                   
benchmarking run 1000 game ticks/trees/40
time                 2.697 ms   (2.693 ms .. 2.700 ms)
                     1.000 R²   (1.000 R² .. 1.000 R²)
mean                 2.699 ms   (2.694 ms .. 2.708 ms)
std dev              23.96 μs   (16.47 μs .. 38.01 μs)
                   
benchmarking run 1000 game ticks/circlers/10
time                 229.9 ms   (229.0 ms .. 230.8 ms)
                     1.000 R²   (1.000 R² .. 1.000 R²)
mean                 230.3 ms   (230.0 ms .. 230.8 ms)
std dev              639.7 μs   (458.4 μs .. 842.9 μs)
variance introduced by outliers: 11% (moderately inflated)
                   
benchmarking run 1000 game ticks/circlers/20
time                 434.7 ms   (433.9 ms .. 435.2 ms)
                     1.000 R²   (1.000 R² .. 1.000 R²)
mean                 435.7 ms   (435.2 ms .. 436.5 ms)
std dev              800.9 μs   (432.2 μs .. 1.072 ms)
variance introduced by outliers: 14% (moderately inflated)
                   
benchmarking run 1000 game ticks/circlers/30
time                 637.5 ms   (634.5 ms .. 641.2 ms)
                     1.000 R²   (1.000 R² .. 1.000 R²)
mean                 640.5 ms   (639.2 ms .. 641.6 ms)
std dev              1.553 ms   (1.244 ms .. 1.907 ms)
variance introduced by outliers: 16% (moderately inflated)
                   
benchmarking run 1000 game ticks/circlers/40
time                 851.5 ms   (NaN s .. 864.0 ms)
                     1.000 R²   (1.000 R² .. 1.000 R²)
mean                 852.1 ms   (850.0 ms .. 853.4 ms)
std dev              2.138 ms   (657.7 μs .. 2.908 ms)
variance introduced by outliers: 19% (moderately inflated)
                   
benchmarking run 1000 game ticks/movers/10
time                 382.4 ms   (379.9 ms .. 384.1 ms)
                     1.000 R²   (1.000 R² .. 1.000 R²)
mean                 383.9 ms   (382.8 ms .. 385.1 ms)
std dev              1.601 ms   (973.2 μs .. 2.420 ms)
variance introduced by outliers: 14% (moderately inflated)
                   
benchmarking run 1000 game ticks/movers/20
time                 721.9 ms   (712.2 ms .. 729.8 ms)
                     1.000 R²   (1.000 R² .. 1.000 R²)
mean                 722.6 ms   (720.4 ms .. 725.9 ms)
std dev              3.234 ms   (1.128 ms .. 4.250 ms)
variance introduced by outliers: 19% (moderately inflated)
                   
benchmarking run 1000 game ticks/movers/30
time                 1.076 s    (1.063 s .. 1.095 s)
                     1.000 R²   (1.000 R² .. 1.000 R²)
mean                 1.071 s    (1.067 s .. 1.074 s)
std dev              4.317 ms   (2.285 ms .. 5.464 ms)
variance introduced by outliers: 19% (moderately inflated)
                   
benchmarking run 1000 game ticks/movers/40
time                 1.440 s    (1.436 s .. 1.446 s)
                     1.000 R²   (NaN R² .. 1.000 R²)
mean                 1.436 s    (1.435 s .. 1.438 s)
std dev              1.923 ms   (544.1 μs .. 2.572 ms)
variance introduced by outliers: 19% (moderately inflated)
```
## After
```
benchmarking run 1000 game ticks/idlers/10
time                 2.559 ms   (2.515 ms .. 2.626 ms)
                     0.996 R²   (0.994 R² .. 0.999 R²)
mean                 2.557 ms   (2.539 ms .. 2.583 ms)
std dev              83.13 μs   (63.17 μs .. 120.2 μs)
variance introduced by outliers: 20% (moderately inflated)
                   
benchmarking run 1000 game ticks/idlers/20
time                 2.518 ms   (2.508 ms .. 2.528 ms)
                     1.000 R²   (1.000 R² .. 1.000 R²)
mean                 2.534 ms   (2.526 ms .. 2.546 ms)
std dev              36.80 μs   (30.33 μs .. 51.03 μs)
                   
benchmarking run 1000 game ticks/idlers/30
time                 2.544 ms   (2.527 ms .. 2.565 ms)
                     0.999 R²   (0.999 R² .. 1.000 R²)
mean                 2.540 ms   (2.533 ms .. 2.551 ms)
std dev              35.25 μs   (23.47 μs .. 54.64 μs)
                   
benchmarking run 1000 game ticks/idlers/40
time                 2.598 ms   (2.578 ms .. 2.627 ms)
                     0.997 R²   (0.995 R² .. 0.999 R²)
mean                 2.693 ms   (2.660 ms .. 2.733 ms)
std dev              135.0 μs   (110.1 μs .. 169.4 μs)
variance introduced by outliers: 38% (moderately inflated)
                   
benchmarking run 1000 game ticks/trees/10
time                 2.590 ms   (2.538 ms .. 2.642 ms)
                     0.998 R²   (0.998 R² .. 0.999 R²)
mean                 2.548 ms   (2.538 ms .. 2.566 ms)
std dev              49.94 μs   (39.27 μs .. 67.19 μs)
                   
benchmarking run 1000 game ticks/trees/20
time                 2.617 ms   (2.568 ms .. 2.679 ms)
                     0.998 R²   (0.997 R² .. 0.999 R²)
mean                 2.562 ms   (2.541 ms .. 2.585 ms)
std dev              78.13 μs   (63.71 μs .. 95.38 μs)
variance introduced by outliers: 19% (moderately inflated)
                   
benchmarking run 1000 game ticks/trees/30
time                 2.559 ms   (2.533 ms .. 2.591 ms)
                     0.999 R²   (0.999 R² .. 1.000 R²)
mean                 2.555 ms   (2.544 ms .. 2.573 ms)
std dev              49.00 μs   (34.54 μs .. 65.61 μs)
                   
benchmarking run 1000 game ticks/trees/40
time                 2.820 ms   (2.729 ms .. 2.906 ms)
                     0.994 R²   (0.991 R² .. 0.996 R²)
mean                 2.620 ms   (2.594 ms .. 2.666 ms)
std dev              121.2 μs   (86.30 μs .. 167.3 μs)
variance introduced by outliers: 34% (moderately inflated)
                   
benchmarking run 1000 game ticks/circlers/10
time                 230.6 ms   (228.8 ms .. 232.5 ms)
                     1.000 R²   (0.999 R² .. 1.000 R²)
mean                 233.5 ms   (231.7 ms .. 236.0 ms)
std dev              3.275 ms   (1.853 ms .. 5.093 ms)
variance introduced by outliers: 11% (moderately inflated)
                   
benchmarking run 1000 game ticks/circlers/20
time                 448.8 ms   (433.6 ms .. 464.6 ms)
                     0.999 R²   (0.999 R² .. 1.000 R²)
mean                 441.1 ms   (437.3 ms .. 446.1 ms)
std dev              5.991 ms   (3.879 ms .. 8.282 ms)
variance introduced by outliers: 14% (moderately inflated)
                   
benchmarking run 1000 game ticks/circlers/30
time                 655.5 ms   (646.9 ms .. 666.9 ms)
                     1.000 R²   (NaN R² .. 1.000 R²)
mean                 652.3 ms   (650.6 ms .. 654.5 ms)
std dev              2.448 ms   (1.442 ms .. 3.702 ms)
variance introduced by outliers: 16% (moderately inflated)
                   
benchmarking run 1000 game ticks/circlers/40
time                 863.8 ms   (861.6 ms .. 868.3 ms)
                     1.000 R²   (1.000 R² .. NaN R²)
mean                 865.5 ms   (864.4 ms .. 867.3 ms)
std dev              1.833 ms   (84.64 μs .. 2.435 ms)
variance introduced by outliers: 19% (moderately inflated)
                   
benchmarking run 1000 game ticks/movers/10
time                 397.4 ms   (382.4 ms .. 412.7 ms)
                     0.999 R²   (0.996 R² .. 1.000 R²)
mean                 395.7 ms   (391.2 ms .. 400.5 ms)
std dev              6.397 ms   (4.350 ms .. 8.877 ms)
variance introduced by outliers: 14% (moderately inflated)
                   
benchmarking run 1000 game ticks/movers/20
time                 721.3 ms   (698.4 ms .. 742.5 ms)
                     1.000 R²   (1.000 R² .. 1.000 R²)
mean                 722.5 ms   (719.8 ms .. 725.4 ms)
std dev              3.533 ms   (1.527 ms .. 4.427 ms)
variance introduced by outliers: 19% (moderately inflated)
                   
benchmarking run 1000 game ticks/movers/30
time                 1.053 s    (1.014 s .. 1.114 s)
                     1.000 R²   (0.999 R² .. 1.000 R²)
mean                 1.067 s    (1.059 s .. 1.081 s)
std dev              13.55 ms   (1.042 ms .. 17.01 ms)
variance introduced by outliers: 19% (moderately inflated)
                   
benchmarking run 1000 game ticks/movers/40
time                 1.392 s    (1.333 s .. 1.421 s)
                     1.000 R²   (1.000 R² .. 1.000 R²)
mean                 1.439 s    (1.417 s .. 1.481 s)
std dev              42.42 ms   (222.2 μs .. 49.25 ms)
variance introduced by outliers: 19% (moderately inflated)
```
2023-10-02 02:56:02 +00:00
Karl Ostmo
9bb18b9a21
Limit system robot activity tracking (#1562)
Extension of #1484 that partially mitigates #1558.

Let's not bother to track the activity levels of system robots when we're not in creative mode, because they won't even show up in the `F2` dialog.  This mitigation can be substantial, as we generally expect there to be many more system robots than player robots.

It doesn't have quite the same "warm up" drawback as the potential mitigation described in https://github.com/swarm-game/swarm/issues/1558#issuecomment-1741794123, because player robots will always be warmed up, and system robots will have been warmed up if we've been playing in creative mode.  We wouldn't necessarily expect frequent toggling in-and-out of creative mode while trying to observe performance in the `F2` dialog.
2023-10-01 15:05:35 +00:00
Karl Ostmo
c1d0fdd3ad
robot wave scenario (#1556)
![image](https://github.com/swarm-game/swarm/assets/261693/5952ccb9-02fe-47af-9a22-b45b130316e2)

# Demo

    scripts/play.sh -i data/scenarios/Challenges/wave.yaml --autoplay
2023-10-01 14:49:54 +00:00
Ondřej Šebek
24ef7c21dc
Web API docs improvements (#1529)
* 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
2023-09-28 11:04:40 +00:00
Brent Yorgey
ae50cf58c2
Fix reference to nonexistent entity type (#1549)
Toward #1547.

I decided to simply fix the error in this PR.  At #1547 there is discussion of various other means to prevent this kind of error in the future (both for developers and players), but I will leave implementing some of those ideas to a future PR.
2023-09-27 09:01:59 +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
Brent Yorgey
c2a2435957
update CONTRIBUTING guide, and remove info from README (#1512)
All README info is now on the website.
2023-09-23 21:46:04 +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
Karl Ostmo
ab7e5b6d8b
disambiguate doc links, elaborate waypoint ordering (#1531)
Towards #1366

Cleans up many Haddock warnings.
2023-09-17 15:18:16 +00:00
Ondřej Šebek
b329a4374a
Update Web module haddock (#1527)
* update Haddock documentation in Web module
* add explicit export lists
* move handlers to top level so the code gets more spaced out
2023-09-16 15:25:42 +00:00
Brent Yorgey
4366026d64
allow megaparsec-9.5 (#1525)
Tests all passed with `cabal test --constraint='megaparsec >= 9.5'`.
2023-09-15 10:10:41 +00:00
Karl Ostmo
a9ded587eb
Render map preview on scenario selection screen (#1515)
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▒
▒▒▒•▒•▒•▒▒▒▒▒▒▒•▒•▒•▒▒▒
▒•••••▒••••▒••••▒•••••▒
▒•▒▒▒▒▒▒▒▒•▒•▒▒▒▒▒▒▒▒•▒
▒•••••••••••••••••••••▒
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒

```
2023-09-15 06:11:47 +00:00
Brent Yorgey
85b33ef5c9
Refactor LogEntry type (#1513)
In preparation for #1483.   `LogEntry` started life as something specific to robot logs.  It then evolved to be used in the system log as well (see #1039 and #652), but in a sort of hacky way.  This PR refactors `LogEntry` to be more generic.

- Move `Swarm.Game.Log` -> `Swarm.Log` since it's not specific to gameplay.
- Rename `ErrorLevel` to `Severity`, add a new `Info` level, and add a top-level `leSeverity` field
- Rename `leRobotName` to just `leName`, since it was already being used to name both robots and system components anyway
- Move robot-specific fields (*e.g.* robot ID) into the new `RobotLogSource` type, and add `LogSource` to differentiate between robot and system logs
- Various other minor improvements and tweaks
2023-09-15 03:08:25 +00:00
Brent Yorgey
932bc45696
Lengthen timeout for Challenges/ice-cream (#1522)
It seems like I have seen a few spurious failures where this scenario timed out, so make the timeout longer to add some buffer.
2023-09-13 22:42:23 +00:00