Skip to content

Commit 7c7b5ea

Browse files
authored
Merge pull request #265 from oskarrough/better-docs
Better docs
2 parents c524b39 + 8a434df commit 7c7b5ea

File tree

7 files changed

+63
-72
lines changed

7 files changed

+63
-72
lines changed

DOCUMENTATION.md

Lines changed: 23 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,6 @@ In the root of this project you'll find configuration files as well as three fol
1111
- [public →](public/) Copied to the web root as-is
1212
- [tests →](tests/) Contains all tests for the game engine. Nothing for the UI. Run `npm test`.
1313

14-
## Coding style
15-
16-
- JavaScript (ES modules)
17-
- Web components and Preact HTM for rendering
18-
- Immer for immutable state updates
19-
- Error handling: Use try/catch sparingly; prefer validation and early returns
20-
- JSDoc for documentation
21-
- No semicolons, single quotes, tabs
22-
2314
### Game
2415

2516
#### Game State
@@ -82,28 +73,10 @@ Every card must define two exports:
8273
- default: the card
8374
- upgrade: upgrade(card) => card
8475

85-
#### dungeon-encounters.js
76+
#### dungeons.js
8677

8778
Contains different monsters, room and dungeons. All created with methods from the game.
8879

89-
### UI
90-
91-
The UI is made with htm and preact. I've tried not to create too many components and abstractions, although this might come back to haunt us.
92-
93-
Everything starts with [index.html](https://github.com/oskarrough/slaytheweb/blob/main/index.html). When loaded,
94-
we show a splash/welcome screen as defined in [index.js](https://github.com/oskarrough/slaytheweb/blob/main/src/ui/index.js).
95-
96-
Next, when you tap "Start Game", we load [app.js](https://github.com/oskarrough/slaytheweb/blob/main/src/ui/app.js).
97-
This one connects everything and manages the game state.
98-
99-
#### Animations
100-
101-
See [animations.js](src/ui/animations.js). Most are made with gsap.
102-
103-
#### Sounds
104-
105-
See [sounds.js](src/ui/sounds.js) using the Web Audio API.
106-
10780
## Tests
10881

10982
Scripts are checked with [eslint](https://eslint.org/), formatted with [prettier](https://prettier.io/) and tested with [ava](https://github.com/avajs/ava).
@@ -118,10 +91,32 @@ Additionally you can run `npm run lint` to automatically format all scripts acco
11891

11992
You can also just run ava directly and do as you please. Example: `npm test tests/actions.js --watch`
12093

94+
## UI
95+
96+
The UI is made with web components, htm and preact. I've tried not to create too many components and abstractions, and copy/paste more, although this might come back to haunt us.
97+
98+
In order to have easy HTML layouts (and more :tm:), we have Astro set up here. This means you can define new routes in src/ui/pages.
99+
100+
### Animations
101+
102+
See [animations.js](src/ui/animations.js). Most are made with gsap.
103+
104+
### Sounds
105+
106+
See [sounds.js](src/ui/sounds.js) using the Web Audio API.
107+
121108
## Backend
122109

123110
With the integration of https://github.com/oskarrough/slaytheweb-backend in `game/backend.js`, you can choose to save your current run state in the Slay the Web database. Nothing but game state & date is stored. All runs are visible on `stats.html`.
124111

125112
## Footnotes
126113

127114
In the beginning I made this diagram of how the game works. It's probably outdated now but keeping it here for reference: https://kinopio.club/slay-the-web-Dh3xUjjHbol7RbCuqZQDn.
115+
116+
- JavaScript (ES modules)
117+
- Web components and Preact HTM for rendering
118+
- Immer for immutable state updates
119+
- Error handling: Use try/catch sparingly; prefer validation and early returns
120+
- JSDoc for documentation
121+
- No semicolons, single quotes, tabs
122+

src/content/dungeons.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import {Monster} from '../game/monster.js'
2+
import {MonsterRoom} from '../game/rooms.js'
3+
import Dungeon from '../game/dungeon.js'
4+
5+
export const createDefaultDungeon = () => {
6+
return Dungeon({
7+
width: 6,
8+
height: 10,
9+
minRooms: 3,
10+
maxRooms: 4,
11+
customPaths: '0235',
12+
})
13+
}
14+
15+
// This is the dungeon used in tests. Don't change it without running tests.
16+
export const createTestDungeon = () => {
17+
const dungeon = Dungeon({width: 1, height: 3})
18+
const intents = [{block: 7}, {damage: 10}, {damage: 8}, {}, {damage: 14}]
19+
// Add monster rooms on the first three nodes
20+
dungeon.graph[1][0].room = MonsterRoom(Monster({hp: 42, intents}))
21+
dungeon.graph[2][0].room = MonsterRoom(Monster({hp: 24, intents}), Monster({hp: 13, intents}))
22+
dungeon.graph[3][0].room = MonsterRoom(Monster({hp: 42, intents}))
23+
return dungeon
24+
}
25+

src/content/dungeon-encounters.js renamed to src/content/monster-rooms.js

Lines changed: 9 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,8 @@
1-
import Dungeon from '../game/dungeon.js'
2-
import {MonsterRoom} from '../game/rooms.js'
31
import {Monster} from '../game/monster.js'
2+
import {MonsterRoom} from '../game/rooms.js'
43
import {random} from '../utils.js'
54

6-
// A dungeon encounter is the combination of a Room and Monster(s).
7-
8-
// Hello. With the imported functions above you can create a dungeon with different rooms and monsters.
9-
// Should be able to support even more monsters (4-5)
10-
11-
// This is the efault dungeon currently used.
12-
export const dungeonWithMap = () => {
13-
return Dungeon({
14-
width: 6,
15-
height: 10,
16-
minRooms: 3,
17-
maxRooms: 4,
18-
customPaths: '0235',
19-
})
20-
}
21-
22-
// This is the dungeon used in tests. Don't change it without running tests.
23-
export const createTestDungeon = () => {
24-
const dungeon = Dungeon({width: 1, height: 3})
25-
// The tests rely on the first room having a single monster, second room two monsters.
26-
const intents = [{block: 7}, {damage: 10}, {damage: 8}, {}, {damage: 14}]
27-
dungeon.graph[1][0].room = MonsterRoom(Monster({hp: 42, intents}))
28-
dungeon.graph[2][0].room = MonsterRoom(Monster({hp: 24, intents}), Monster({hp: 13, intents}))
29-
dungeon.graph[3][0].room = MonsterRoom(Monster({hp: 42, intents}))
30-
return dungeon
31-
}
32-
33-
// Here are some different monsters we use in the game.
34-
// should be changed to have monster files, to make adding/editing them easier
5+
// Groups of monster rooms of varying difficulty. Technically elites and bosses are just stronger monsters.
356
export const easyMonsters = {}
367
export const monsters = {}
378
export const elites = {}
@@ -56,6 +27,7 @@ easyMonsters['Easy does it x2'] = MonsterRoom(
5627
random: 1,
5728
}),
5829
)
30+
5931
monsters['RNG does it'] = MonsterRoom(
6032
Monster({
6133
hp: random(18, 20),
@@ -70,7 +42,6 @@ monsters['Easy one'] = MonsterRoom(
7042
random: 2,
7143
}),
7244
)
73-
7445
//not perfect copy of base game monster, but pretty close
7546
//needs to gain strength (add to the 6 block)
7647
monsters['jaw worm'] = MonsterRoom(
@@ -108,19 +79,19 @@ monsters['Tiny Trio'] = MonsterRoom(
10879
Monster({hp: random(12, 15), random: 2, intents: [{damage: 6}]}),
10980
Monster({hp: random(10, 16), random: 3, intents: [{damage: 6}]}),
11081
)
111-
elites['monster7'] = MonsterRoom(
112-
Monster({
113-
hp: 46,
114-
intents: [{damage: 12}, {block: 6, damage: 11}, {block: 5, damage: 16}, {}, {block: 6}],
115-
}),
116-
)
11782
monsters['monster10'] = MonsterRoom(
11883
Monster({
11984
hp: 28,
12085
intents: [{weak: 1}, {block: 10, damage: 10}, {damage: 21}],
12186
}),
12287
)
12388

89+
elites['monster7'] = MonsterRoom(
90+
Monster({
91+
hp: 46,
92+
intents: [{damage: 12}, {block: 6, damage: 11}, {block: 5, damage: 16}, {}, {block: 6}],
93+
}),
94+
)
12495
elites['monster9'] = MonsterRoom(
12596
Monster({
12697
hp: 60,

src/game/actions.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {isDungeonCompleted, getRoomTargets, getCurrRoom} from './utils-state.js'
44
import powers from './powers.js'
55
import {conditionsAreValid} from './conditions.js'
66
import {createCard, CardTargets} from './cards.js'
7-
import {dungeonWithMap} from '../content/dungeon-encounters.js'
7+
import {createDefaultDungeon} from '../content/dungeons.js'
88

99
// Enable support for Map and Set. See https://immerjs.github.io/immer/installation/
1010
enableMapSet()
@@ -77,13 +77,13 @@ function createNewState() {
7777
}
7878

7979
/**
80-
* By default a new game doesn't come with a dungeon. You have to set one explicitly. Look in dungeon-encounters.js for inspiration.
80+
* By default a new game doesn't come with a dungeon. You have to set one explicitly. Look in dungeons.js for inspiration.
8181
* @param {State} state
8282
* @param {Dungeon} [dungeon]
8383
* @returns {State} .
8484
*/
8585
function setDungeon(state, dungeon) {
86-
if (!dungeon) dungeon = dungeonWithMap()
86+
if (!dungeon) dungeon = createDefaultDungeon()
8787
state.dungeon = dungeon
8888
return state
8989
// return produce(state, (draft) => {

src/game/dungeon.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {uuid, shuffle, random as randomBetween, pick} from '../utils.js'
2-
import {easyMonsters, monsters, elites, bosses} from '../content/dungeon-encounters.js'
2+
import {easyMonsters, monsters, elites, bosses} from '../content/monster-rooms.js'
33
import {StartRoom, CampfireRoom} from './rooms.js'
44

55
/**

tests/actions.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import actions from '../src/game/actions.js'
44
import {createCard, CardTargets} from '../src/game/cards.js'
55
import {MonsterRoom} from '../src/game/rooms.js'
66
import {Monster} from '../src/game/monster.js'
7-
import {createTestDungeon} from '../src/content/dungeon-encounters.js'
7+
import {createTestDungeon} from '../src/content/dungeons.js'
88
import {getRoomTargets, getCurrRoom, isCurrRoomCompleted} from '../src/game/utils-state.js'
99
import {canPlay} from '../src/game/conditions.js'
1010

tests/dungeon.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// @ts-ignore
22
import test from 'ava'
3-
import {createTestDungeon} from '../src/content/dungeon-encounters.js'
3+
import {createTestDungeon} from '../src/content/dungeons.js'
44
import actions from '../src/game/actions.js'
55
import Dungeon from '../src/game/dungeon.js'
66
import {MonsterRoom} from '../src/game/rooms.js'

0 commit comments

Comments
 (0)