Skip to content

Commit b06f723

Browse files
committed
Cleanup, rules rewriting, and minor classification errors fixed
1 parent 5058882 commit b06f723

File tree

17 files changed

+442
-291
lines changed

17 files changed

+442
-291
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ There is a lot to do, so feel free to [contribute](#contributing)!
5555
- [x] ~~Make the MonkeyRunner interface more reliable~~
5656
- [ ] Enhance the game re-implementation:
5757
- [x] ~~Develop a game explorer to build a database of state sequences for further analysis~~
58-
- [ ] Complete and implement the [game rules](utils/RULES.md)
58+
- [ ] Complete and implement the [game rules](RULES.md)
5959
- [x] ~~Prayers~~
6060
- [x] ~~Energy restoration~~
6161
- [x] ~~Knockback, collisions~~
@@ -84,6 +84,6 @@ There is a lot to do, so feel free to [contribute](#contributing)!
8484

8585
## Contributing
8686

87-
Open pull requests or issues if you have any proposition to make. Check the [roadmap](#roadmap) for ideas (there are many), and the [documentation](https://ychalier.github.io/hoplite/) for how to implement them. I put some screenshots [here](https://drive.google.com/file/d/1qxlnwcgf0HpPYMsUqjAjjSAjxX1xGKji/view?usp=sharing) (2MB) helping development.
87+
Open pull requests or issues if you have any proposition to make. Check the [roadmap](#roadmap) for ideas (there are many), and the [documentation](https://ychalier.github.io/hoplite/) for how to implement them. I put some screenshots [here](https://drive.google.com/file/d/1qxlnwcgf0HpPYMsUqjAjjSAjxX1xGKji/view?usp=sharing) (2MB) helping development, and the [templates](https://drive.google.com/file/d/12jOOsBgHntUWIagNk2fzicEvEETnyvvW/view?usp=sharing) (1MB) used for the classifiers.
8888

8989
If you implement some features, please make sure your code is clean enough (for this matter I use the [Pylint](https://www.pylint.org/) linter) and documented enough (add docstrings with short descriptions, types of arguments and returned values). I use [pdoc](https://pdoc3.github.io/pdoc/) to generate the documentation.

RULES.md

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
# An Empirical Study of Hoplite's Internal Rules
2+
3+
**Disclaimer: this document is unofficial and far from being complete.**
4+
5+
## 1. Terrain
6+
7+
The terrain is an hexagonal map made of 79 tiles, that are of two types:
8+
- the ground ![](assets/ground.png), on which the player can walk,
9+
- and the magma ![](assets/magma.png), where the player can not walk.
10+
11+
In each map there is one tile for the stairs ![](assets/stairs.png) leading to the next level. Until depth 15 (included), each map also features an altar ![](assets/altar_on.png) that the player can pray at (only once). Player and demons may walk on the stairs, but not over the altar. Depth 16 features a fleece ![](assets/fleece.png) that the player has to pick up before walking on the portal ![](assets/portal.png), escaping the dungeon and winning the game.
12+
13+
*Remark: this description only concerns the first 16 depths of the game,
14+
available in the free version of the game.*
15+
16+
## 2. Demons
17+
18+
Demons are the enemies of the game. There are four types of them:
19+
20+
Name | Asset | In-game description
21+
---- | ----- | -------------------
22+
Footman | ![](assets/footman.png) | A resident of the underworld that is skilled in melee combat. It can only attack adjacent tiles.
23+
Archer | ![](assets/archer.png) | A resident of the underworld that is skilled in ranged combat. It has a maximum range of 5 tiles and cannot attack adjacent tiles. It can only shoot in 6 directions.
24+
Demolitionist | ![](assets/demolitionist_holding_bomb.png) | A resident of the underworld that is able to throw bombs. It has a range of 3 tiles. It can only throw a bomb every 3 turn.
25+
Wizard | ![](assets/wizard_charged.png) | A resident of the underworld that is able to conjure beams of fire. It has a range of 5 tiles and will hit all tiles in range. It will avoid hitting other demons and cannot fire two turns in a row. It can only shoot in 6 directions.
26+
27+
### 2.1. Demon Attacks
28+
29+
At enemy's turn, each demon can either attack or move (but not both). Attacks always take priority over movement [[Developer's Discord]](https://discord.com/channels/692958702805975050/692958703229337661/704852139914035300).
30+
31+
The **footman** will attack (i.e. inflict one damage) whenever it is in a tile adjacent to the player's, after any player move and its consequences.
32+
33+
The **archer** will throw an arrow whenever the player is in its range area. This area is determine by six lines, one for each hexagonal direction (vertical, diagonal north-west / south-east, diagonal south-west / north-east). The archer can not shoot to a directly adjacent tile, and not beyond a 5 tile radius. Also, throwing an arrow requires a clear view: the archer can not shoot through an altar or another demon. The archer may throw an arrow every turn that satisfies those conditions.
34+
35+
The **demolitionist** will throw a bomb ![](assets/bomb.png) in a range of three tiles. It has to wait two full turns before being able to throw again. It will not throw a bomb to a tile adjacent to a demon [[Developer's Discord]](https://discord.com/channels/692958702805975050/692958703229337661/704958237224730654) [[Developer's Blog]](http://www.magmafortress.com/2015/03/hoplite-challenge-mode-is-ready.html).
36+
37+
The **wizard**, as the archer, has a range attack effective on the six hexagonal directions, with a maximum range of five tiles, having clear sight. Unlike the archer, it can shoot a tile directly adjacent to him. Though, it has two limitations:
38+
- the wizard has a one turn cooldown between two attacks,
39+
- the wizard will not shoot if its beam would reach a demon in the 5 tile range (meaning if there is a demon in reach behind the player, then wizard will not shoot) [[Developer's Blog]](http://www.magmafortress.com/2015/03/hoplite-challenge-mode-is-ready.html).
40+
41+
Here is a representation of the archer and the wizard ranges:
42+
43+
![](https://i.imgur.com/oklXok9.png)
44+
45+
### 2.2. Demon Movements
46+
47+
**TODO**
48+
49+
### 2.3. Demon Status
50+
51+
**TODO**
52+
53+
## 3. Player
54+
55+
The player is a Greek hoplite ![](assets/player.png).
56+
57+
### 3.1. Status
58+
59+
#### 3.1.1 Health
60+
61+
The player has a health bar composed of two values: the maximum health and the current health. At the beginning of the game, the player starts with 3 hearts out of 3. Each damage dealt by a demon decreases the current health by 1. When this amount reaches 0, the player dies and looses. Finishing a level does not heal the player. Here are the ways of restoring health:
62+
- the prayer "Divine Restoration" will restore all health up to the maximum health,
63+
- the prayer "Fortitude" will increase the maximum health by one and also increase the current health by one,
64+
- with the prayer "Regeneration", killing in three consecutive turns will restore one heart (until the maximum health is reached), once per depth.
65+
66+
The maximum health can not exceed 8 hearts, meaning "Fortitude" prayers are unavailable if the player already has a maximum health of 8 hearts.
67+
68+
![](https://i.imgur.com/C49TiUx.png)
69+
70+
#### 3.1.2. Energy
71+
72+
The player has an energy bar similar to the health one: it has a current value and a maximum value. At the beginning of the game, the player starts with 100 energy out of 100. Leaping consumes 50 energy (if the player does not have that amount of energy, it can not leap). Here are the ways of restoring energy:
73+
- going to the next level restores all the energy,
74+
- walking (or leaping) to a tile with an adjacent demon will restore 10 energy [[Developer's Blog]](http://www.magmafortress.com/2013/09/hoplite-20.html),
75+
- with the prayer "Bloodlust", each kill (stab, lunge, throw, bashed into lava, crushed, or explosion from a bashed bomb) will restore 6 energy,
76+
- with the prayer "Surge", killing in three consecutive turns will restore 100 energy
77+
- the prayer "Greater Energy" will increase the maximum energy by 20, and also increase the current energy by 20
78+
- the prayer "Greater Energy II" will increase the maximum energy by 15, and also increase the current energy by 15
79+
80+
![](https://i.imgur.com/PvO009g.png)
81+
82+
#### 3.1.3. Bash Cooldown
83+
84+
When the player uses the bash move, it starts a cooldown before being able to use it again. This cooldown starts at 4 turns, decreasing by one after each enemy turn: the player has to wait 3 full turns before bashing again.
85+
86+
The prayer "Quick Bash" reduces the cooldown starting value to 3 turns. With the prayer "Surge", killing in three consecutive turns will reset the cooldown, making bashing available again.
87+
88+
### 3.2. Moves
89+
90+
Each turn, the player performs one of the following moves:
91+
92+
#### 3.2.1. Walk
93+
94+
Walking to an adjacent tile, if it is not magma, and if there is no demon, bomb nor altar on it. If this tile happens to be the stairs, then the player goes to the next level. Walking triggers two attacks:
95+
96+
Attack | In-game description
97+
------ | -------------------
98+
Stab | Stabs are performed automatically based on your movement relative to demons. A demon will be stabbed any time you move between two tiles adjacent to that demon.
99+
Lunge | You will lunge automatically whenever moving directly toward a demon. Leaping toward a demon also trigger a lunge attack. Lunge only hits demons you move directly toward. You cannot lunge while your spear is on the ground.
100+
101+
#### 3.2.2. Leap
102+
103+
Jumping to a remote tile, if it is not magma, and if there is no demon, bomb nor altar on it. This consumes 50 energy, and so is only available when the player has at least this amount of energy. Leaping triggers the stab and lunge attacks.
104+
105+
A player can not leap to a tile directly adjacent to its position (that would be walking). Default leap distance is 2. This can be increased by one with the prayer "Winged Sandals".
106+
107+
With the prayer "Staggering Leap", demon adjacent to the tile the player lands on are stunned.
108+
109+
#### 3.2.3. Bash
110+
111+
Bash is only available if its cooldown is at zero. Bashing a tile knocks back entities (demons and bombs) around. After that, the cooldown starts (by default at 4 turns) preventing the player from bashing again. Bash can be used to skip a turn if it is really necessary. The precise knocking mechanism can be a little complex; here is how it works:
112+
113+
1. Determine which tiles are bashed:
114+
- by default, only the tile clicked on is bashed,
115+
- with the prayer "Sweeping Bash", an arc of tiles is bashed, centered on the clicked tile,
116+
- with the prayer "Spinning Bash", all tiles adjacent to the player are bashed.
117+
2. For each bashed tile:
118+
1. Consider the direction from the player to the bash tile, and look at the next tile A on that line. If there is not any demon or bomb on it, then this bashed tile is ignored.
119+
2. Otherwise, the target A is pushed to the next tile B in the computed direction:
120+
- if there is an altar on B, then nothing happens,
121+
- if B is out of the map:
122+
- if the target is a demon then it gets crushed (i.e. killed, counting as a player kill),
123+
- and if it is a bomb then nothing happens,
124+
- if the target is a demon and B a magma tile, the demon is killed (counting as a player kill) [[Developer's Blog]](http://www.magmafortress.com/2014/07/hoplite-23-progress.html),
125+
- otherwise:
126+
1. if B is occupied by a demon, this demon is **pushed away**,
127+
2. the target A is moved to B.
128+
3. Repeat the previous step if the player has made the prayer "Mighty Bash", increasing the knockback distance to 2.
129+
130+
The mechanism to **push away** a demon has been [described by the developer on Reddit](https://www.reddit.com/r/Hoplite/comments/fxx69q/will_i_fall_into_lava_if_i_bashreaction_how_does/fn9ntxe/?context=3). The game looks for empty tiles in the following order:
131+
132+
![](https://i.imgur.com/vSdBL6o.png)
133+
134+
The game looks for empty an empty tile in 1, and if not in 2 and 2' in random order. If it finds an empty tile (magma counts as empty, killing the demon), the demon is moved there. Otherwise, the demon in tile 1 is pushed away using the same algorithm, then the first demon is moved to tile 1. If a demon needs to be pushed away but has nowhere to escape (i.e. no demon can be pushed to make room for it), then it gets crushed.
135+
136+
#### 3.2.4. Throw
137+
138+
If the player has its spear, it may throw it to a tile in a given radius. This radius is 2 by default, but prayers "Greater Throw" and "Greater Throw II" both increase this radius by one.
139+
140+
After having thrown the spear, the player can not lunge anymore. Also, it will not be able to go through the stairs: it has to pick up the spear first, by walking (or leaping) on it.
141+
142+
#### 3.2.5. Others
143+
144+
If the player has made the prayer "Patience", it can idle and make no move, effectively skipping its turn.
145+
146+
If the player is on a tile adjacent to an altar where no prayer has been made before at this depth, then it can pray at the altar, also counting as a turn.
147+
148+
Both moves count as regular turns, meaning demons will attack and move.
149+
150+
## 4. Prayers
151+
152+
Here are the identified prayers on the free version of the game.
153+
154+
Prayer | In-game description | Sacrifice
155+
------ | ------------------- | ---------
156+
Divine Restoration | Heals Completely. | -
157+
Fortitude | Increases maximum health. | -
158+
Bloodlust | Killing restores 6 energy. | 1
159+
Mighty Bash | Increases knock back distance. | -
160+
Sweeping Bash | Affects targets in an arc. | -
161+
Spinning Bash | Affects all adjacent targets. | -
162+
Quick Bash | Reduces cooldown. | -
163+
Greater Throw | Increases throw distance. | -
164+
Greater Throw II | Increases throw distance. | 1
165+
Greater Energy | Increases maximum energy. | -
166+
Greater Energy II | Increases maximum energy. | 1
167+
Deep Lunge | Lunge penetrates through target. | -
168+
Patience | Allows skipping turns. | -
169+
Surge | Killing in three consecutive actions restores 100 energy, resets cooldowns and returns your spear. | 1
170+
Regeneration | Once per depth, killing in three consecutive actions regenerates health. | 1
171+
Winged Sandals | Increases leap distance. | 1
172+
Staggering Leap | Stuns adjacent enemies on landing. | 2

docs/game/state.html

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ <h1 class="title">Module <code>hoplite.game.state</code></h1>
5252
VICTORY = 4
5353
DEATH = 5
5454
STAIRS = 6
55+
BLACK = 7
5556

5657

5758
class GameState:
@@ -675,7 +676,8 @@ <h2 id="parameters">Parameters</h2>
675676
FLEECE = 3
676677
VICTORY = 4
677678
DEATH = 5
678-
STAIRS = 6</code></pre>
679+
STAIRS = 6
680+
BLACK = 7</code></pre>
679681
</details>
680682
<h3>Ancestors</h3>
681683
<ul class="hlist">
@@ -687,6 +689,10 @@ <h3>Class variables</h3>
687689
<dd>
688690
<div class="desc"></div>
689691
</dd>
692+
<dt id="hoplite.game.state.Interface.BLACK"><code class="name">var <span class="ident">BLACK</span></code></dt>
693+
<dd>
694+
<div class="desc"></div>
695+
</dd>
690696
<dt id="hoplite.game.state.Interface.DEATH"><code class="name">var <span class="ident">DEATH</span></code></dt>
691697
<dd>
692698
<div class="desc"></div>
@@ -767,6 +773,7 @@ <h4><code><a title="hoplite.game.state.GameState" href="#hoplite.game.state.Game
767773
<h4><code><a title="hoplite.game.state.Interface" href="#hoplite.game.state.Interface">Interface</a></code></h4>
768774
<ul class="two-column">
769775
<li><code><a title="hoplite.game.state.Interface.ALTAR" href="#hoplite.game.state.Interface.ALTAR">ALTAR</a></code></li>
776+
<li><code><a title="hoplite.game.state.Interface.BLACK" href="#hoplite.game.state.Interface.BLACK">BLACK</a></code></li>
770777
<li><code><a title="hoplite.game.state.Interface.DEATH" href="#hoplite.game.state.Interface.DEATH">DEATH</a></code></li>
771778
<li><code><a title="hoplite.game.state.Interface.EMBARK" href="#hoplite.game.state.Interface.EMBARK">EMBARK</a></code></li>
772779
<li><code><a title="hoplite.game.state.Interface.FLEECE" href="#hoplite.game.state.Interface.FLEECE">FLEECE</a></code></li>

docs/game/status.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ <h1 class="title">Module <code>hoplite.game.status</code></h1>
3434
@enum.unique
3535
class Prayer(enum.Enum):
3636
&#34;&#34;&#34;
37-
Prayers obtained at the altars of Apollo.
37+
Prayers obtained at the altars.
3838
&#34;&#34;&#34;
3939

4040
DIVINE_RESTORATION = 0
@@ -415,14 +415,14 @@ <h2 id="attributes">Attributes</h2>
415415
<span>(</span><span>value, names=None, *, module=None, qualname=None, type=None, start=1)</span>
416416
</code></dt>
417417
<dd>
418-
<div class="desc"><p>Prayers obtained at the altars of Apollo.</p></div>
418+
<div class="desc"><p>Prayers obtained at the altars.</p></div>
419419
<details class="source">
420420
<summary>
421421
<span>Expand source code</span>
422422
</summary>
423423
<pre><code class="python">class Prayer(enum.Enum):
424424
&#34;&#34;&#34;
425-
Prayers obtained at the altars of Apollo.
425+
Prayers obtained at the altars.
426426
&#34;&#34;&#34;
427427

428428
DIVINE_RESTORATION = 0

0 commit comments

Comments
 (0)