Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
110 commits
Select commit Hold shift + click to select a range
82ea1c7
chore: WiP
SeriousSoftware Aug 25, 2016
64066e1
chore: Some tidy up
SeriousSoftware Sep 2, 2016
1b54f0c
bugfix: jsEnv := PhantomJSEnv(autoExit = false).value blocks testing
SeriousSoftware Sep 2, 2016
804caa2
chore: rewrite as a more reactive design 00 WiP Pre refomat
SeriousSoftware Sep 6, 2016
6d2d7e8
chore: rewrite as a more reactive design 01 WiP refomat
SeriousSoftware Sep 6, 2016
80cabd5
chore: rewrite as a more reactive design 02 WiP
SeriousSoftware Sep 7, 2016
9ccb795
chore: rewrite as a more reactive design 03 Back in bussiness
SeriousSoftware Sep 7, 2016
2d675be
chore: rewrite as a more reactive design 04 WiP
SeriousSoftware Sep 7, 2016
e35a453
chore: rewrite with new tests 01 - Remove the imageFuture doublure
SeriousSoftware Sep 11, 2016
2885270
chore: rewrite with new tests 02 - Fighting DOM Exception 18
SeriousSoftware Sep 11, 2016
f86bc84
chore: rewrite with new tests 02 - Fighting DOM Exception 18
SeriousSoftware Sep 11, 2016
5697ddf
chore: rewrite with new tests 03 - Fighting DOM Exception 18
SeriousSoftware Sep 11, 2016
747319c
chore: rewrite with new tests 04 - Fighting DOM Exception 18
SeriousSoftware Sep 11, 2016
b75f588
chore: rewrite with new tests 05 - Fighting DOM Exception 18
SeriousSoftware Sep 11, 2016
2d9e147
chore: rewrite with new tests 05 - Fighting DOM Exception 18
SeriousSoftware Sep 11, 2016
b0c361a
chore: rewrite with new tests 07 - Fighting DOM Exception 18
SeriousSoftware Sep 11, 2016
fc6df66
chore: rewrite with new tests 09 - Fighting DOM Exception 18 Try CORS…
SeriousSoftware Sep 12, 2016
915f42b
chore: rewrite with new tests 10 - Fighting DOM Exception 18 Try CORS…
SeriousSoftware Sep 12, 2016
b148378
chore: rewrite with new tests 11 - Fighting DOM Exception 18 Try CORS…
SeriousSoftware Sep 12, 2016
0dcf6aa
chore: rewrite with new tests 11 - Fighting DOM Exception 18
SeriousSoftware Sep 14, 2016
3f18882
chore: rewrite with new tests 11 - Fighting DOM Exception 18
SeriousSoftware Sep 19, 2016
2ba92e7
feature: Controllable canvas text in order to test canvas.
SeriousSoftware Sep 20, 2016
5a6feb9
chore: refine the test 00
SeriousSoftware Sep 20, 2016
d320875
chore: refine the test 01
SeriousSoftware Sep 21, 2016
498ef0c
chore: refine the test 01 -test canvas size default
SeriousSoftware Sep 21, 2016
5dbfad9
chore: refine the test 01 -test canvas size default
SeriousSoftware Sep 21, 2016
2ea9ca7
chore: refine the test 02 -test visual elements
SeriousSoftware Sep 21, 2016
ec57bec
chore: refine the test 03 -test visual elements scala 1:1
SeriousSoftware Sep 21, 2016
f14f1a4
chore: refine the test 03 -test visual elements
SeriousSoftware Sep 21, 2016
36fee09
chore: refine the test 03 -test visual elements
SeriousSoftware Sep 21, 2016
14a7f4c
chore: refine the test 04 -test visual elements
SeriousSoftware Sep 22, 2016
4a6a820
chore: refine the test 04-The Lord has helped us to this point.
SeriousSoftware Sep 23, 2016
bdf36a2
chore: refine the test 05- Stuck by line PageSuite:24
SeriousSoftware Sep 23, 2016
42259b6
chore: refine the test 05-The Lord has helped us to this point.
SeriousSoftware Sep 24, 2016
48ada9a
chore: refine the test 06-The Lord has helped us to this point.
SeriousSoftware Sep 24, 2016
cca1fe8
chore: refine the test 07
SeriousSoftware Sep 24, 2016
d9bbbff
chore: refine the test 09
SeriousSoftware Sep 24, 2016
1ace4c9
chore: refine the test 09
SeriousSoftware Sep 24, 2016
8d64fdb
chore: refine the test 10
SeriousSoftware Sep 25, 2016
2a60953
chore: refine the test 10 -finding hashcodes
SeriousSoftware Sep 25, 2016
fba56c8
chore: refine the test 10 finding hashcodes
SeriousSoftware Sep 25, 2016
054d4d1
chore: refine the test 11
SeriousSoftware Sep 25, 2016
031b8bc
chore: refine the test 09
SeriousSoftware Sep 25, 2016
26b6299
feature: PageSuite covers Page trait's HTML Canvas.
SeriousSoftware Sep 25, 2016
0ecefd6
feature: PageSuite covers Page trait's HTML Canvas, run => local reso…
SeriousSoftware Sep 26, 2016
d49e3fa
feature: GameSuite covers GameState. WiP
SeriousSoftware Sep 26, 2016
bd14b5c
feature: GameSuite covers GameState test-only - Travis trigger.
SeriousSoftware Sep 27, 2016
a30cfcc
feature: GameSuite covers GameState test-only
SeriousSoftware Sep 27, 2016
5c65e2c
feature: GameSuite covers GameState test-only
SeriousSoftware Sep 27, 2016
8a6ed5b
feature: GameSuite covers GameState test-only
SeriousSoftware Sep 27, 2016
a949734
feature: GameSuite covers GameState test-only
SeriousSoftware Sep 27, 2016
384dc08
feature: GameSuite covers GameState test-only
SeriousSoftware Sep 27, 2016
6c1b38f
feature: GameSuite covers GameState test-only
SeriousSoftware Sep 27, 2016
489f691
feature: GameSuite covers GameState test-only
SeriousSoftware Sep 27, 2016
df15353
feature: GameSuite covers GameState test-only
SeriousSoftware Sep 27, 2016
74b55ee
feature: GameSuite covers GameState test-only
SeriousSoftware Sep 27, 2016
e9b8969
feature: GameSuite covers GameState test-only
SeriousSoftware Sep 28, 2016
d9ecdd5
feature: GameSuite covers GameState debugging Travis system
SeriousSoftware Sep 28, 2016
0912169
feature: GameSuite covers GameState test-only
SeriousSoftware Sep 28, 2016
80fb535
feature: GameSuite covers GameState test-only
SeriousSoftware Sep 28, 2016
6e341c0
feature: GameSuite covers GameState test-only
SeriousSoftware Sep 28, 2016
a185b7a
feature: GameSuite covers GameState test-only
SeriousSoftware Sep 28, 2016
8961ba5
feature: GameSuite covers GameState test-only
SeriousSoftware Sep 30, 2016
b06c246
feature: GameSuite covers GameState test-only
SeriousSoftware Sep 30, 2016
03da14a
feature: Suites covers App
SeriousSoftware Sep 30, 2016
b27d2a1
Update README.md
SeriousSoftware Oct 2, 2016
a066e92
Add files via upload
SeriousSoftware Oct 2, 2016
2ba108c
feat: Prepare build.sbt adjustment
SeriousSoftware Oct 2, 2016
494a144
feature: multi browser tests
SeriousSoftware Oct 4, 2016
0b1091c
Merge remote-tracking branch 'origin/experiment' into experiment
SeriousSoftware Oct 4, 2016
9725e7a
feature: multi browser tests - chrome disabled
SeriousSoftware Oct 4, 2016
4b9ce92
feature: multi browser tests - chrome disabled
SeriousSoftware Oct 5, 2016
0b135e7
feature: multi browser tests - chrome disabled
SeriousSoftware Oct 5, 2016
80fd6e0
feature: WiP
SeriousSoftware Oct 9, 2016
28977df
feature: Readme edited
SeriousSoftware Oct 9, 2016
23c8e7c
feature: Readme edited
SeriousSoftware Oct 9, 2016
5da9e49
feature: Readme edited
SeriousSoftware Oct 10, 2016
d32ca95
feature: Tackling Firefox issue
SeriousSoftware Oct 10, 2016
51ccf05
feature: Tackling Firefox issue
SeriousSoftware Oct 10, 2016
912ae0b
feature: Tackling Firefox issue
SeriousSoftware Oct 16, 2016
5ba6d0b
feature: Tackling Firefox issue
SeriousSoftware Oct 16, 2016
ea70daf
feature: Tackling Firefox issue
SeriousSoftware Oct 16, 2016
a709075
feature: Updated Readme.md
SeriousSoftware Oct 17, 2016
7c84f13
feature: Updated Readme.md
SeriousSoftware Oct 17, 2016
20ec763
feature: Updated Readme.md
SeriousSoftware Oct 17, 2016
f2fbba2
feature: Updated Readme.md
SeriousSoftware Oct 17, 2016
7695f45
feature: Updated Readme.md
SeriousSoftware Oct 17, 2016
3d3f8ba
feature: Updated Readme.md
SeriousSoftware Oct 17, 2016
3f4fda5
feature: Bump to Scala.js 0.6.13
SeriousSoftware Oct 21, 2016
ebb708b
feature: Updated README.md
SeriousSoftware Oct 23, 2016
efa63d7
feature: Updated README.md
SeriousSoftware Oct 27, 2016
8bd32ff
Version 2.0
SeriousSoftware Oct 27, 2016
01f219d
Version 2.0
SeriousSoftware Oct 27, 2016
29c01d7
Version 2.0 errata
SeriousSoftware Oct 27, 2016
48e9bc2
Version 2.0 errata 01
SeriousSoftware Oct 27, 2016
d7fe452
Version 2.0 Dot the i's and cross the t's. 00
SeriousSoftware Oct 30, 2016
b07990b
Merge remote-tracking branch 'origin/master_V2' into master_V2
SeriousSoftware Oct 30, 2016
852daf3
Version 2.0 Dot the i's and cross the t's. 01
SeriousSoftware Oct 30, 2016
157e48c
Version 2.0 Dot the i's and cross the t's. 02
SeriousSoftware Oct 31, 2016
c847f7f
Version 2.0 Dot the i's and cross the t's. 03
SeriousSoftware Nov 1, 2016
f184108
Version 2.0 Dot the i's and cross the t's. 03
SeriousSoftware Nov 2, 2016
1299c07
Version 2.0 Dot the i's and cross the t's. 05 - Using the github.com …
SeriousSoftware Nov 2, 2016
b7c3544
Version 2.0 Dot the i's and cross the t's. 06 - Using the github.com …
SeriousSoftware Nov 2, 2016
2344749
Version 2.0 Dot the i's and cross the t's. 07 - Using the github.com …
SeriousSoftware Nov 2, 2016
4231182
Version 2.0 Dot the i's and cross the t's. 08 - Using the github.com …
SeriousSoftware Nov 2, 2016
60a2c0c
Version 2.0 Dot the i's and cross the t's. 09 - Using the github.com …
SeriousSoftware Nov 2, 2016
ba5202f
feature: bump to Scala v 2.12.0
SeriousSoftware Nov 5, 2016
907c542
feature: Cosmetic update
SeriousSoftware Nov 6, 2016
e842687
feature: Cosmetic update
SeriousSoftware Nov 6, 2016
b89df1e
feature: Release V 2.0
SeriousSoftware Nov 7, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@ target/
*.sc

# Scala-IDE specific
.cache-main
.cache-tests
.classpath
.project
.scala_dependencies
.settings
.worksheet
bin/

# IntelliJ
*.iml
Expand Down
26 changes: 17 additions & 9 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,24 +1,32 @@
#https://docs.travis-ci.com/user/languages/scala
language: scala
before_install:
# Initilize xvfb for headless testing
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
#- sleep 3 # give xvfb some time to start

script:
- sbt ++$TRAVIS_SCALA_VERSION test
- sbt ++$TRAVIS_SCALA_VERSION firefox:test

# Trick to avoid unnecessary cache updates
- find $HOME/.sbt -name "*.lock" | xargs rm

scala:
- 2.11.8
- 2.12.0

jdk:
- oraclejdk8
sudo: false

cache:
directories:
- $HOME/.ivy2/cache
- $HOME/.sbt/boot/
- $HOME/.ivy2
- $HOME/.m2/repository
- $HOME/.sbt

env:
- CI=travis

#branches:
# only:
# - master

# - sbt ++$TRAVIS_SCALA_VERSION 'set scalaJSStage in Global := FastOptStage' test 'set scalaJSStage in Global := FullOptStage' test
addons:
firefox: "46.0.1"
12 changes: 12 additions & 0 deletions Licence.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
2016-10-01 Simple Game
©2016 by F.W. van den Berg Licensed under the EUPL-1.1

This Software is provided to You under the terms of the European Union Public License (the "EUPL") version 1.1
or – as soon they will be approved by the European Commission - subsequent versions of the EUPL (the "Licence")
as published by the European Union. Any use of this Software, other than as authorized under this License is
strictly prohibited (to the extent such use is covered by a right of the copyright holder of this Software).

This Software is provided under the License on an "AS IS" basis and without warranties of any kind concerning
the Software, including without limitation merchantability, fitness for a particular purpose, absence of defects
or errors, accuracy, and non-infringement of intellectual property rights other than copyright. This disclaimer
of warranty is an essential part of the License and a condition for the grant of any rights to this Software.
213 changes: 208 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,215 @@
<a href="http://www.w3.org/html/logo/">
<img src="https://www.w3.org/html/logo/badge/html5-badge-h-css3-graphics-semantics.png" width="99" height="32" alt="HTML5 Powered with CSS3 / Styling, Graphics, 3D &amp; Effects, and Semantics" title="HTML5 Powered with CSS3 / Styling, Graphics, 3D &amp; Effects, and Semantics"></a>[![Scala.js](https://img.shields.io/badge/scala.js-0.6.10%2B-blue.svg?style=flat)](https://www.scala-js.org)
[![Build Status](https://travis-ci.org/amsterdam-scala/Sjs-Simple-HTML5-canvas-game.svg?branch=master)](https://travis-ci.org/amsterdam-scala/Sjs-Simple-HTML5-canvas-game)
[![Build Status](https://travis-ci.org/amsterdam-scala/Sjs-Simple-HTML5-canvas-game.svg?branch=master_V2)](https://travis-ci.org/amsterdam-scala/Sjs-Simple-HTML5-canvas-game)

# Simple HTML5 Canvas game ported to Scala.js
**Featuring Scala.js "in browser testing" by ScalaTest 3.x**

Original tutorial in Javascript :
[How to make a simple HTML5 Canvas game](http://www.lostdecadegames.com/how-to-make-a-simple-html5-canvas-game/)
A Scala hardcore action game where you possess and play as a Hero :smile:.

Play the [live demo](http://goo.gl/oqSFCa). Scala doc is [here](https://amsterdam-scala.github.io/Sjs-Simple-HTML5-canvas-game/docs/api/index.html#nl.amsscala.package).
## Project
This "Simple HTML5 Canvas Game" is a [Scala.js](https://en.wikipedia.org/wiki/Scala.js) project which targets a browser capable displaying HTML5, especially the `<canvas>` element.
Stored on GitHub.com, due to [sbt](https://en.wikipedia.org/wiki/sbt_(software)) the code is also remote tested on Travis-CI. Also possible on an other continuous integration service.

Further Resources, Notes, and Considerations
This quite super simple game is heavily über engineered. It's certainly not the game that counts but the technology around it, it features:

1. [HTML5 Canvas](https://en.wikipedia.org/wiki/Canvas_element) controlled by Scala.js
1. Headless canvas [Selenium 2](https://en.wikipedia.org/wiki/Selenium_(software)) "in browser testing" with the recently released ScalaTest 3.x
1. [ScalaTest 3.x](http://www.scalatest.org) featuring "async" testing styles.
1. Scala 2.12 compiler.
1. Exhaustive use of a variety of Scala features, e.g.:
* `Traits`, (`case`) `Class`es and `Object`s (singletons)
* `Future`s sane way to dramatically reduce latency in web requests
* [Generic[T] objects](https://en.wikipedia.org/wiki/Generic_programming) (even in the frenzied Ough).
* [Algebraic Data Types](https://en.wikipedia.org/wiki/Algebraic_data_type)
* [Pattern matching](https://en.wikipedia.org/wiki/Pattern_matching)
* [Lazy evaluation](https://en.wikipedia.org/wiki/Lazy_evaluation)
1. Reactive design instead of continuous polling.
1. Eliminating a continuously redrawn of the canvas saves cpu time and (mobile) power.
1. Tackling [CORS](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image) enabled images.
1. [Scala generated HTML](http://www.lihaoyi.com/scalatags/).
1. CSS Ribbon
1. [Scala 2.12 fresh Scaladoc look.](https://amsterdam-scala.github.io/Sjs-Simple-HTML5-canvas-game/docs/api/index.html).

## Motivation
Scala.js compile-to-Javascript language is by its compile phase ahead of runtime errors in production. It prevents you of nasty
runtime errors because everything must be ok in the compile phase, specially the types of the functions and variables.

In the original tutorial in Javascript: [How to make a simple HTML5 Canvas game](http://www.lostdecadegames.com/how-to-make-a-simple-html5-canvas-game/),
a continuous redraw of the canvas was made, which is a simple solution, but resource costly.
## Usage
Play the [live demo](http://goo.gl/oqSFCa). Scaladoc you will find [here](https://amsterdam-scala.github.io/Sjs-Simple-HTML5-canvas-game/docs/api/index.html#nl.amsscala.package).
[Installation instructions here](#installation-instructions)

## Architecture
![class diagram](https://raw.githubusercontent.com/amsterdam-scala/Sjs-Simple-HTML5-canvas-game/master/doc/HTML5CanvasGame.png)
#### Discussion:

By the initial call from `SimpleCanvas.main` to `Game.play` its (private) `gameLoop` will periodic started given its `framesPerSec` frequency.
There the status of eventually pressed arrow keys will be tested and per `GameState.keyEffect` converted to a move of the `Hero`.
In an instance of `GameState` the position of the `CanvasComponent`s are immutable recorded. When a change has to be made a new instance will be
generated with only the changed variables adjusted and leaving the rest unchanged by copying the object.

With the changes in this `CanvasState` a render method of `Page` is only called if the instance is found changed.

The render method repaints the canvas completely. Successively the background, monster and hero will be painted, so the last image is at the foreground.
The images found are the respectively instances of `CanvasComponent` subclasses `Playground`, `Monster` and `Hero`.
They are asynchronously loaded once at startup by means of the use of `Future`s.

In spite of the fact that the application is technically one-tier in an MVC design pattern perspective, everything runs in the browser,
the following parts can be identified:

<table>
<tr>
<th>Part</th>
<th>Class</th>
<th>Auxiliary</th>
</tr>
<tr>
<td>Model</td>
<td>GameState</td>
<td>Position</td>
</tr>
<tr>
<td>View</td>
<td>Page</td>
<td>CanvasComponents (Playground, Monster and Hero)</td>
</tr>
<tr>
<td>Controller</td>
<td>Game</td>
<td>GameState</td>
</tr>
</table>

Communication from Game to Page is done by calling with a modified GameState to Page.

#### Unit Testing

Unit testing is done with [ScalaTest 3.x](http://www.scalatest.org/) which is completely detached from the JVM system and Java runtime.
Although running sbt, the test code will be executed in a browser.
This is enabled by a [Selenium environment](https://github.com/scala-js/scala-js-env-selenium) interface direct running to [Firefox](http://www.mozilla.org) and via Chrome Driver to a Google [Chrome browser](https://sites.google.com/a/chromium.org/chromedriver/).

The necessary resources are downloaded from a external server because the test environment lacks a server for this this task.

The test tasks can be invoked by `chrome:test` for the Google Chrome browser and `firefox:test`, separated configs constructed in `InbrowserTesting.scala`.
As proposed by this [article](http://japgolly.blogspot.nl/2016/03/scalajs-firefox-chrome-sbt.html).

Unfortunately at [Travis-CI](travis-ci.org/amsterdam-scala/Sjs-Simple-HTML5-canvas-game) it's not possible to run Google Chrome, so `firefox:test` is the only option.
Also unfortunately `chrome:test` fails on `test 10`, so if executed locally `test 10` must be comment out.
<table>
<tr>
<th>Test Class file</th>
<th>Coverage</th>
<th>Remarks</th>
</tr>
<tr>
<td><code>CanvasComponentSuite</code></td>
<td>canvasComponent</td>
<td><code>Playground</code>, <code>Monster</code> and <code>Hero</code> are concrete classes of <code>CanvasComponent</code></td>
</tr>
<tr>
<td><code>GameStateSuite</code></td>
<td><code>GameState</code></td>
<td></td>
</tr>
<tr>
<td><code>GameSuite</code></td>
<td><code>Game</code></td>
<td></td>
</tr>
<tr>
<td><code>PageSuite</code></td>
<td><code>Page</code></td>
<td></td>
</tr>
</table>

##### CanvasComponentSuite
This excercises a Hero instance against border limitations.
##### GameStateSuite
E.g. GameState equality.
##### GameSuite
Test the effect of the arrow keys on the Hero moves.
##### PageSuite
This is the most interesting unit test, it features:
* Asynchronous non-blocking testing
* Canvas testing

###### Asynchronous non-blocking testing
ScalaTest 3.x supports asynchronous non-blocking testing by returning a `Future[Assertion]` type. With this the assertion is
postponed as long if the `Future` is not completed.
###### Canvas testing
Because of the difference of processing between various render engines in browsers, is it hard to test the content of a canvas.
One pixel difference becomes immediately a negative test result. However, a couple of techniques can be used by hashing the canvas to
a hash value. The techniques are:
* Exact comparison, only possible if a complete image is rendered in the same sized canvas. In this case no processing (cropping, resizing) is required and therefor not tainted. Only the pixels of original source are used which gives the same result, even in different browsers. Actual it's a property of the source.
* A different hash value per different browser. In this case there are multiple hash values valid, one per browser.
* Tainted canvas. E.g. text on a canvas gives sometimes a slightly different result in pixels by e.g. rounding errors. The only test we can do is to test if the canvas has changed.

## Installation instructions
1. Clone the Github project to a new directory. This is the project directory which become the working directory of current folder.
1. Naturally, at least a Java SE Runtime Environment (JRE) is installed on your platform and has a path to it enables execution.
1. (Optional) Test this by submitting a `java -version` command in a [Command Line Interface (CLI, terminal)](https://en.wikipedia.org/wiki/Command-line_interface). The output should look like this:
```
java version "1.8.0_102"
Java(TM) SE Runtime Environment (build 1.8.0_102-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.102-b14, mixed mode)
```
1. Make sure sbt is runnable from almost any work directory, use eventually one of the platform depended installers:
1. [Installing sbt on Mac](http://www.scala-sbt.org/release/docs/Installing-sbt-on-Mac.html) or
1. [Installing sbt on Windows](http://www.scala-sbt.org/release/docs/Installing-sbt-on-Windows.html) or
1. [Installing sbt on Linux](http://www.scala-sbt.org/release/docs/Installing-sbt-on-Linux.html) or
1. [Manual installation](http://www.scala-sbt.org/release/docs/Manual-Installation.html) (not recommended)
1. (Optional ) To test if sbt is effective submit the `sbt sbtVersion` command. The response could look like as this:
```
[info] Set current project to fransdev (in build file:/C:/Users/FransDev/)
[info] 0.13.12
```
Remember shells (CLI's) are not reactive. To pick up the new [environment variables](https://en.wikipedia.org/wiki/Environment_variable) the CLI must be closed and restarted.
1. Run sbt in one of the next modes in a CLI in the working directory or current folder, a compilation will be started and a local web server will be spinned up using:
1. Inline mode on the command line: `sbt fastOptJS` or
1. Interactive mode, start first the sbt by hitting in the CLI `sbt` followed by `fastOptJS` on the sbt prompt, or
1. Triggered execution by a `~` before the command so `~fastOptJS`. This command will execute and wait after the target code is in time behind the source code (Auto build).
1. sbt will give a notice that the server is listening by the message: `Bound to localhost/127.0.0.1:12345`
(Ignore the dead letter notifications with the enter key.)
1. Open this application in a browser on [this given URL](http://localhost:12345/target/scala-2.12/classes/index-dev.html)

When running this way a tool ["workbench"](https://github.com/lihaoyi/workbench) also will be running in the browser, noticeable by opening the console of the browser.

<!-- #### Further Resources -->
<!-- #### Notes -->
<!-- #### Considerations -->

#### Licence
Licensed under the EUPL-1.1


```-------------------------------------------------------------------------------
Language files blank comment code
-------------------------------------------------------------------------------
Scala 6 96 113 261


game.js
-------------------------------------------------------------------------------
Language files blank comment code
-------------------------------------------------------------------------------
JavaScript 1 21 16 93

Scala.js minimal project
-------------------------------------------------------------------------------
Language files blank comment code
-------------------------------------------------------------------------------
JavaScript 1 26 1 572

-------------------------------------------------------------------------------
Language files blank comment code
-------------------------------------------------------------------------------
JavaScript 2 795 1 15423
HTML 2 13 25 51
CSS 1 14 0 49
-------------------------------------------------------------------------------
SUM: 5 822 26 15523
-------------------------------------------------------------------------------
```
Loading