Skip to content
This repository was archived by the owner on Sep 16, 2025. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
3daea5c
Expand .gitignore
davesmith00000 Apr 8, 2023
5d45b15
README typo
davesmith00000 Apr 8, 2023
6fd7efc
Basic Nix flake
davesmith00000 Apr 8, 2023
7d747be
Initial Tyrian project set up
davesmith00000 Apr 8, 2023
cbcff0d
Fix GHA workflow
davesmith00000 Apr 8, 2023
2e4c23d
Try again
davesmith00000 Apr 8, 2023
414b5a1
Change base package
davesmith00000 Apr 8, 2023
699bbd1
Ported Colour class
davesmith00000 Apr 8, 2023
0642ce6
Ported Hexagon class
davesmith00000 Apr 8, 2023
5f34b58
Ported BoardMapTile class
davesmith00000 Apr 8, 2023
133f0e3
Ported Version class
davesmith00000 Apr 8, 2023
12cefff
Ported Monster class
davesmith00000 Apr 8, 2023
6e5f5e8
HexagonTests ported (failing)
davesmith00000 Apr 8, 2023
47be22c
Ported Character class
davesmith00000 Apr 8, 2023
2a8bf5d
Ported SpecialRules class
davesmith00000 Apr 9, 2023
a826b0f
WIP
davesmith00000 Apr 9, 2023
4fcbc6e
Ported BoardOverlay class
davesmith00000 Apr 9, 2023
3e0a233
Ported Scenario class
davesmith00000 Apr 9, 2023
1c7f3ff
WIP
davesmith00000 Apr 9, 2023
b882336
Blocking out some functions
davesmith00000 Apr 9, 2023
081c868
No compile errors, lots missing
davesmith00000 Apr 10, 2023
458a6f9
A few chunks of Main
davesmith00000 Apr 10, 2023
a3a3934
Working through Main
davesmith00000 Apr 10, 2023
54206f5
Initial function ported, does not compile
davesmith00000 Apr 10, 2023
2a889d1
Adds a HTML page that can be used for scaling images and extracting J…
hobnob Apr 28, 2023
9e7e301
Starts to build out the Indigo implementation
hobnob May 2, 2023
6a1479c
Adds a map tile (a1a) with move icon
hobnob May 4, 2023
9c3429a
Updates tooling with keyboard events
hobnob May 5, 2023
1531278
Adds copy JSON button to tooling
hobnob May 5, 2023
3caa47a
Map tiles can now be moved across the screen
hobnob May 11, 2023
896dbef
Creates a context menu that can be used to rotate or remove a room
hobnob May 16, 2023
716cb6b
Fixes rotations for rooms
hobnob May 18, 2023
f02f410
Monsters can now be moved around the board
hobnob May 22, 2023
7287543
Converts PNG files to webp
hobnob May 22, 2023
d0c2fc1
Overlays can now be rotated and removed
hobnob May 31, 2023
a51bb4c
Fixed Typo
hobnob May 31, 2023
9286696
Adds webp to tooling
hobnob May 31, 2023
f52a3eb
Monsters now have player markers and can be removed
hobnob Jun 1, 2023
bb5f925
Context menu only shows when dragging
hobnob Jun 1, 2023
537057e
Monster level can now be assigned via context menu
hobnob Jun 1, 2023
8d95ad5
Improves Monster rendering and adds a cell map
hobnob Jun 7, 2023
1c406c7
Cell map now also takes into account drag data
hobnob Jun 7, 2023
b0740e0
Validation now uses flags
hobnob Jun 8, 2023
17d95a7
Amalgamates a lot of the complex rotations into a single trait
hobnob Jun 9, 2023
33d3a89
Adds coins
hobnob Jun 11, 2023
1668a28
Adds tokens
hobnob Jun 11, 2023
291b644
Adds styles
hobnob Jun 12, 2023
6105427
Upgrades to latest Tyrian, Indigo, Scala, and Mill
hobnob Jun 13, 2023
c9dceea
Removes older assets
hobnob Jun 13, 2023
a340657
Context menus now work in the same way as the original
hobnob Jun 19, 2023
d65bc14
Adds Scenario Title and fixes context menu showing with no items in it
hobnob Jun 20, 2023
010bd15
Starts to add left menu to creator and fixes footer
hobnob Jun 22, 2023
6f67ecf
Can now drag items from left menu to the board
hobnob Jun 29, 2023
2625582
Adds storage capability
hobnob Jul 4, 2023
fc35fa5
A number of changes and fixes
hobnob Jul 10, 2023
bdb90a8
Update ci.yml
hobnob Jul 10, 2023
f949f45
Finishes conversion to odd row
hobnob Jul 12, 2023
5d4341a
Starts adding import/export to creator
hobnob Aug 10, 2023
7f2c4ea
Export now works correctly from Creator
hobnob Aug 16, 2023
880eca0
Imports now work correctly within the creator
hobnob Sep 15, 2023
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
15 changes: 15 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: CI
on: [workflow_dispatch, push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: olafurpg/setup-scala@v14
with:
java-version: [email protected]
- uses: jodersky/setup-mill@master
with:
mill-version: 0.11.1
- name: Compile & Test
run: bash ci.sh
37 changes: 35 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,10 +1,43 @@
elm-stuff/
build/
.metals/
.vscode
obj/
bin/
**/assets/js/main*
**/assets/js/creator*
**/assets/js/node_modules
**/assets/css/

# JS
node_modules

# sbt
target

# mill
out

# Scala-CLI
.scala-build

# Direnv
.envrc
.direnv

# Misc
.DS_Store

# IDE's and other build tools
.idea
*.iml
.vscode
.vim
.metals
.bloop
metals.sbt
.bsp
.ammonite
.coursier

# parcel
.parcel-cache
dist
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ The quickest and easiest way to get up and running is by opening

### Using a Local Server
If you'd rather use a local server than the online version (perhaps you're playing
ove LAN, or just fancy the technical challenge), then you can do that too!
over LAN, or just fancy the technical challenge), then you can do that too!
In essence all you need to do is download the correct file and set up port forwarding,
but more detailed instructions are below:

Expand Down
4 changes: 4 additions & 0 deletions VirtualGloomhavenBoard/Indigo/.jvmopts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-Xss8m
-Xms1G
-Xmx8G
-XX:+UseG1GC
1 change: 1 addition & 0 deletions VirtualGloomhavenBoard/Indigo/.mill-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.11.1
9 changes: 9 additions & 0 deletions VirtualGloomhavenBoard/Indigo/.parcelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": [
"@parcel/config-default"
],
"reporters": [
"...",
"parcel-reporter-static-files-copy"
]
}
26 changes: 26 additions & 0 deletions VirtualGloomhavenBoard/Indigo/.scalafix.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
rules = [
DisableSyntax,
OrganizeImports
]

OrganizeImports {
removeUnused = false
}

DisableSyntax {
noVars = true
noThrows = true
noNulls = true
noReturns = true
noWhileLoops = true
noAsInstanceOf = false # Doesn't seem to work correctly
noIsInstanceOf = false # Doesn't seem to work correctly
noXml = true
noDefaultArgs = true
noFinalVal = true
noFinalize = true
noValPatterns = true
# noUniversalEquality = false # handled by scala 3
# noUniversalEqualityMessage = "== and != are unsafe since they allow comparing two unrelated types"
# regex = []
}
6 changes: 6 additions & 0 deletions VirtualGloomhavenBoard/Indigo/.scalafmt.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
version = 3.5.8
runner.dialect = scala3
style = defaultWithAlign
maxColumn = 120
rewrite.rules = [RedundantBraces,RedundantParens,PreferCurlyFors]
danglingParentheses.preset = true
87 changes: 87 additions & 0 deletions VirtualGloomhavenBoard/Indigo/build.sc
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import $ivy.`com.lihaoyi::mill-contrib-bloop:$MILL_VERSION`
import mill._
import mill.scalalib._
import mill.scalajslib._
import mill.scalajslib.api._
import $file.gamedata.gameData

object `vgb-common` extends VgbModule

object `vgb-game` extends VgbModule {
override def moduleDeps = Seq(`vgb-common`)

// generatedSources is a list of paths to source files.
// It is called on compile, so by hooking in our function
// our code is re-generated on compilation.
override def generatedSources: T[Seq[PathRef]] = T {
// Set a working directory inside the `out` dir
val wd = os.pwd / "out" / "gamedata"
// Make sure it exists
os.makeDir.all(wd)

gameData.CodeGen
.generate()
.map(d =>
d match {
case (file, data) =>
// Write to the file
os.write.over(
wd / s"""${file.capitalize}.scala""",
s"""/* This file is auto-generated. Please do not modify it manually */
|${data}""".stripMargin.trim
)
}
)

// Call out code gen function and concat the paths onto
// the standard path list.
Seq(PathRef(wd)) ++ super.generatedSources()
}
}

object `vgb-ui` extends VgbModule {
override def moduleDeps = Seq(`vgb-common`, `vgb-game`)

def build() =
T.command {
T {
compile()
fastLinkJS()
}
}
}

trait VgbModule extends ScalaJSModule {
def scalaVersion = "3.3.0"
def scalaJSVersion = "1.13.1"

val indigoVersion = "0.15.0-RC4"
val tyrianVersion = "0.7.2-SNAPSHOT"
val circeVersion = "0.14.1"

def ivyDeps =
Agg(
ivy"io.indigoengine::tyrian-io::$tyrianVersion",
ivy"io.indigoengine::tyrian-indigo-bridge::$tyrianVersion",
ivy"io.indigoengine::indigo-json-circe::$indigoVersion",
ivy"io.indigoengine::indigo::$indigoVersion",
ivy"io.indigoengine::indigo-extras::$indigoVersion",
ivy"org.scala-js:scalajs-java-securerandom_sjs1_2.13:1.0.0",
ivy"io.circe::circe-core::$circeVersion",
ivy"io.circe::circe-generic::$circeVersion",
ivy"io.circe::circe-parser::$circeVersion"
)

override def esFeatures: T[ESFeatures] = T {
ESFeatures.Defaults.withESVersion(ESVersion.ES2015)
}

override def moduleKind = T(mill.scalajslib.api.ModuleKind.CommonJSModule)

object test extends ScalaJSTests with TestModule.Munit {

def ivyDeps = Agg(
ivy"org.scalameta::munit::1.0.0-M7"
)
}
}
4 changes: 4 additions & 0 deletions VirtualGloomhavenBoard/Indigo/gamedata/gameData.sc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
object CodeGen {
def generate(): List[(String, String)] =
List.empty
}
33 changes: 33 additions & 0 deletions VirtualGloomhavenBoard/Indigo/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"scripts": {
"start": "parcel wwwroot/index.html --open --dist-dir build --log-level info --no-cache",
"build": "parcel build wwwroot/index.html --dist-dir build --log-level info --no-cache"
},
"dependencies": {
"@microsoft/signalr": "^6.0.2",
"@microsoft/signalr-protocol-msgpack": "^6.0.2"
},
"devDependencies": {
"@parcel/packager-raw-url": "2.8.3",
"@parcel/transformer-sass": "^2.8.3",
"@parcel/transformer-webmanifest": "2.8.3",
"buffer": "^5.7.1",
"crypto-browserify": "^3.12.0",
"events": "^3.3.0",
"parcel": "^2.8.3",
"parcel-reporter-static-files-copy": "^1.5.0",
"process": "^0.11.10",
"stream-browserify": "^3.0.0"
},
"staticFiles": {
"staticPath": "wwwroot/static",
"watcherGlob": "**"
},
"alias": {
"assert": false,
"console": false,
"crypto": false,
"buffer": false,
"stream": false
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package vgb.common

enum BaseGame(val shortName: String):
case Gloomhaven extends BaseGame("gh")
case Frosthaven extends BaseGame("fh")
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package vgb.common

import indigo.*

enum TreasureChestType:
override def toString(): String = this match {
case Goal => "goal"
case Locked => "locked"
case Normal(i) => i.toString()
}

case Normal(val number: Byte) extends TreasureChestType
case Goal, Locked

object TreasureChestType:
def fromString(str: String) =
str.toLowerCase() match {
case "goal" => Goal
case "locked" => Locked
case _ =>
str.toByteOption match {
case Some(b) => Normal(b)
case None => Normal(0)
}
}

trait BoardOverlayType:
val baseGame: BaseGame
val cells: Batch[Point]
val flag: Flag
val verticalAssetName: Option[AssetName]
val name: String = this
.toString()
.toCharArray()
.foldLeft("")((s, c) => if c >= '0' && c <= 'Z' then s + " " + c else s + c)
.trim()
val codedName = name.toLowerCase().replace(" ", "-")
val assetName: AssetName = AssetName(s"""${baseGame.shortName}-${codedName}""")

enum DifficultTerrain(
val baseGame: BaseGame,
val cells: Batch[Point]
) extends BoardOverlayType:
val flag: Flag = Flag.DifficultTerrain
val verticalAssetName = None
case Rubble extends DifficultTerrain(BaseGame.Gloomhaven, Batch(Point(0, 0)))

enum Corridor(
val baseGame: BaseGame,
val cells: Batch[Point]
) extends BoardOverlayType:
val flag: Flag = Flag.Corridor
val verticalAssetName = None
case Altar extends Corridor(BaseGame.Gloomhaven, Batch(Point(0, 0)))

enum Door(
val baseGame: BaseGame,
val cells: Batch[Point],
val verticalAssetName: Option[AssetName]
) extends BoardOverlayType:
val flag: Flag = Flag.Door
case Altar extends Door(BaseGame.Gloomhaven, Batch(Point(0, 0)), None)

enum Hazard(val baseGame: BaseGame, val cells: Batch[Point]) extends BoardOverlayType:
val flag: Flag = Flag.Hazard
val verticalAssetName = None
case HotCoals extends Hazard(BaseGame.Gloomhaven, Batch(Point(0, 0)))
case Thorns extends Hazard(BaseGame.Gloomhaven, Batch(Point(0, 0)))

final case class Highlight(val baseGame: BaseGame, val colour: RGB) extends BoardOverlayType:
val cells: Batch[Point] = Batch(Point(0, 0))
val flag: Flag = Flag.Highlight
val verticalAssetName = None

object Highlight:
val Red = Highlight(BaseGame.Gloomhaven, RGB.Red)
val Orange = Highlight(BaseGame.Gloomhaven, RGB.Orange)
val Yellow = Highlight(BaseGame.Gloomhaven, RGB.Yellow)
val Green = Highlight(BaseGame.Gloomhaven, RGB.Green)
val Blue = Highlight(BaseGame.Gloomhaven, RGB.Blue)
val Indigo = Highlight(BaseGame.Gloomhaven, RGB.Indigo)

enum Obstacle(val baseGame: BaseGame, val cells: Batch[Point]) extends BoardOverlayType:
val flag: Flag = Flag.Obstacle
val verticalAssetName = None
case Boulder2 extends Obstacle(BaseGame.Gloomhaven, Batch(Point(0, 0), Point(1, 0)))

final case class Rift(val baseGame: BaseGame) extends BoardOverlayType {
val cells: Batch[Point] = Batch(Point(0, 0))
val flag: Flag = Flag.Rift
val verticalAssetName = None
}

enum StartingLocation(val baseGame: BaseGame) extends BoardOverlayType:
val cells: Batch[Point] = Batch(Point(0, 0))
val flag: Flag = Flag.StartingLocation
val verticalAssetName = None
case Gloomhaven extends StartingLocation(BaseGame.Gloomhaven)

enum Trap(val baseGame: BaseGame, val cells: Batch[Point]) extends BoardOverlayType:
val flag: Flag = Flag.Trap
val verticalAssetName = None
case BearTrap extends Trap(BaseGame.Gloomhaven, Batch(Point(0, 0)))

enum Treasure(val flag: Flag) extends BoardOverlayType:
val cells: Batch[Point] = Batch(Point(0, 0))
val verticalAssetName = None

override def toString(): String = this match
case Chest(_, _) => "Chest"
case Coin(_, _) => "Coin"

case Chest(val baseGame: BaseGame, val treasureType: TreasureChestType) extends Treasure(Flag.TreasureChest)
case Coin(val baseGame: BaseGame, val amount: Byte) extends Treasure(Flag.Coin)

final case class Token(val baseGame: BaseGame, val letter: Char) extends BoardOverlayType:
val cells: Batch[Point] = Batch(Point(0, 0))
val flag: Flag = Flag.Token
val verticalAssetName = None
override def toString(): String = s"""Token (${letter})"""

enum Wall(val baseGame: BaseGame, val cells: Batch[Point]) extends BoardOverlayType:
val flag: Flag = Flag.Wall
val verticalAssetName = None
case Rock extends Wall(BaseGame.Gloomhaven, Batch(Point(0, 0)))
Loading