Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP


The big, ugly, pending pull request #11

wants to merge 240 commits into from

2 participants

Mikolaj Konarski Andres Löh
Mikolaj Konarski

Ping! :D

I hope this fits the mood of LambdaHack. At least, the monsters have been preserved, though their behaviour is a bit more varied now. Feel free to pick and choose, of course, I'll just reapply the rejected commits as initial commits of Allure --- the distant SF fork.

Mikolaj and others added some commits
Mikolaj Konarski Mikolaj multiple heroes: a hero now carries his personal number with him cbb5b67
Mikolaj Konarski Mikolaj multiple heroes: a number of heroes possible on each level 05a0949
Mikolaj Konarski Mikolaj multiple heroes: help text for hero selection keys
And a remark that the keys listed are the default keys,
in case we allow the user to change them (via config file or UI) later.
Mikolaj Konarski Mikolaj multiple heroes: prepare keys for hero selection commands b048766
Mikolaj Konarski Mikolaj the current target and look mode fields (see issue 28) c4fcdc8
Mikolaj Konarski Mikolaj multiple heroes: a few tweaks around the type of heroes on a level
We should probably use the same type for monsters, to have a number
with which to indicate a targeted monster. Monsters probably don't need
to carry their numbers in them, unlike heroes, because they don't get
moved to and from any "current monster" state field.
Mikolaj Konarski Mikolaj allow player to change levels freely in look mode 76af3b0
Mikolaj Konarski Mikolaj enable the look mode
TODO: some actions should behave differently in look mode, e.g., movement
Mikolaj Konarski Mikolaj fix a typo that breaks savegames and TODO about another bug b28dc42
Mikolaj Konarski Mikolaj mutiple heroes: Tab cycles among heroes on a level
TODO: currently all but on hero must remain on level 1. Either hero switching
in look mode or via number keys will solve that.
Mikolaj Konarski Mikolaj tweaks and comments, mostly about TODOs for actions 7bd9ccf
Mikolaj Konarski Mikolaj multiple heroes: spawn the number of heroes specified in config
Plus a few tweaks around.
Mikolaj Konarski Mikolaj vty support status update: vty maintainer OK with numpad number keys
I'll prepare a patch to differentiate numpad and top row number keys.
Mikolaj Konarski Mikolaj multiple heroes: Tab cycles heroes also in look mode
So it's now possible to move more than one hero to levels > 1.
Mikolaj Konarski Mikolaj multiple heroes: monsters chase closest heroes on the level 6d9a881
Mikolaj Konarski Mikolaj fix of a bug caused by config file options being case insensitive
TODO: perhaps make the options case sensitive; it costs too much debugging.
Mikolaj Konarski Mikolaj multiple heroes: monster attacks any hero correctly; infrastructure c…

Plus a bit of clean-up.
Mikolaj Konarski Mikolaj switch config file behaviour to case sensitive and rename options 7f861f6
Mikolaj Konarski Mikolaj change datatype of look mode from a tuple to a record
That's after I myself didn't remember what the components are used for.
Now it's documented in record field names.
Mikolaj Konarski Mikolaj code naming convention: "player" is the currently selected hero
This is short form of "player-controlled hero".
Other heroes and all heroes in general are just "heroes".
Mikolaj Konarski Mikolaj all heroes on level now displayed; player in reverse video 96a3f1e
Mikolaj Konarski Mikolaj fix issue #9 on kosmikus' fork (High score table, number of steps) de46aad
Mikolaj Konarski Mikolaj fix issue #8 on kosmikus' fork (High score table, boolean flags)
Exactly as proposed; minimal changes to get it working again.
Mikolaj Konarski Mikolaj fix monsters unable to attack selected hero
I misuderstood how the action monad "abort" propagates through nested actions.
Mikolaj Konarski Mikolaj all heroes (not only the player) regenrate at once
That's because we really want hero selection to be a purely UI distinction;
otherwise players will waste time micromanaging cycling among heroes before
the end of the turn.
Mikolaj Konarski Mikolaj changing hero selection takes no time now
Via a tmp hack, until the TODOs below playerCommand implemented.
Mikolaj Konarski Mikolaj the loot of all heroes on the current level now counts for the winnin…
…g score

Only heroes from the current level are taken into account, or leaving
one hero camping near the exit would be a too powerful tactics.
Mikolaj Konarski Mikolaj say which hero selected, instead of the boring fixed message e1914e0
Mikolaj Konarski Mikolaj add '*' and '?' to the list of confimation keys
This is to to let the keys that request (more) information (help screen,
item list for dropping, etc.) toggle display of the obtained information off.
No two keys required ('?' and ' '), just tap '?' once, look, tap again.
Mikolaj Konarski Mikolaj fix a bug with case sensitivity of config; harden code
The bug was wiping out savegame on every other save attempt. I've forgotten
to set case sensitivity in some of the places config is created. Affects only
my branch. With the new code it's much harder to make such a bug again.
Mikolaj Konarski Mikolaj fix a bug where gold can't be dropped under GTK (other frontends are OK) 0340098
Mikolaj Konarski Mikolaj bumping into a hero switches selection to him
TODO: it takes a turn and it shouldn't
Mikolaj Konarski Mikolaj on levels with no heroes monsters now chase each other
Actually, they don't actively follow each other (no monster FOV, so they
can't see each other), but they always attack when adjacent, and not
only when bumping into each other by chance, as on levels with heroes.
To see this behaviour toggle look mode, change level and press '.'.
Mikolaj Konarski Mikolaj fix a bug (regression) where monsters can't open secret doors a82badc
Mikolaj Konarski Mikolaj heroes can now be selected with number keys (top row of keyboard)
TODO: refactor the hero code
Mikolaj Konarski Mikolaj refactor hero selection code; surprisingly small now 11f89ad
Mikolaj Konarski Mikolaj simplify and corret lvlswitch
Now it does not reveal the location of the other end of stairs is look mode.
Mikolaj Konarski Mikolaj highlight the look mode cursor d2b94b6
Mikolaj Konarski Mikolaj illustrate issue #31 with TODO comments 12c64d4
Mikolaj Konarski Mikolaj movement in look mode advances the cursor and describes terrain 4083fc2
Mikolaj Konarski Mikolaj in look mode, describe only terrain explored by the player 7211356
Mikolaj Konarski Mikolaj close #29 (Naming convention for player/hero/party) bf87826
Mikolaj Konarski Mikolaj in look mode, don't focus on hero unless level changed
Plus some refactoring and hardening.
Mikolaj Konarski Mikolaj some extra banter when exiting the program
In the future we can plug in there some extra statistics,
character dump commands, etc.
Mikolaj Konarski Mikolaj debug for keys; update about the vty keypad patch; misc fixes a25dcbb
Mikolaj Konarski Mikolaj killed actors (monsters and heroes) now drop loot uniformly
Plus some cleanup and TODOs.
Mikolaj Konarski Mikolaj misc tweaks 4426842
Mikolaj Konarski Mikolaj implement and set as default: game does not end util at least one her…
…o alive
Mikolaj Konarski Mikolaj monster and hero death now handled right after damage dealt 540f1f2
Mikolaj Konarski Mikolaj ultra-hack: default config file gets included in the binary
In this way, we avoid the usual headaches with paths, OSes and permissions.
At startup it's always parsed, but a user config is used instead, if it exists.
TODO: throughout the code, lookup default values in the default config instead
of specifying them every time an option is queried. In this way, the various
game balance parameters are in sync and all in one place (the default config).
The user configs can be short and modify only some options, the rest is taken
from the default config. Diffs between user and default configs are easy.
The cost of all this is a bit of dynamic typing, and so runtime failures.
Can be limited by defining some types for sets of config parameters.
Mikolaj Konarski Mikolaj level layout config options more readable and now mandatory 304b824
Mikolaj Konarski Mikolaj big fixes to do with look mode and level switching eff038a
Mikolaj Konarski Mikolaj default config now underlies config from savefile and from user confi…
…g file
Mikolaj Konarski Mikolaj defaults no longer needed when querying config
The default config file is now the only source of defaults and we get
an immediate runtime error if the sought option is not found in it
(nor in the main config file carried by the savegame, which may also contain
options from the user config file from the time the game was started).
Mikolaj Konarski Mikolaj add a command to dump current configuration; close #30
Also rewritten the default config file to make diffing with dumps easier.
Mikolaj Konarski Mikolaj config file now always has to specify savegame and highscore paths
Previously, the current directory was chosen if no paths were given,
now it's only when the ~/.LambadaHack directory does not exist.
Mikolaj Konarski Mikolaj make some parameters configurable, as requested in TODOs 59e1577
Mikolaj Konarski Mikolaj running into a monster or hero switches positions 0cd6f38
Mikolaj Konarski Mikolaj simplify moveOrAttack by assuming one moster per tile 910adb1
Mikolaj Konarski Mikolaj factor out the moveOrAttack code dealing with 2 actors a754ad3
Mikolaj Konarski Mikolaj faster, deterministic and better looking extra heroes placement 6c92870
Mikolaj Konarski Mikolaj balance multi-hero mode a bit better d1449bd
Mikolaj Konarski Mikolaj looking at terrain tiles now also mentions monsters
It's out of sync currently, because it erronously takes time,
so monsters can move away before the player reads the description.
Mikolaj Konarski Mikolaj disallow use of some commands when in look mode on a remote level 4288992
Mikolaj Konarski Mikolaj a mock-up of all the commands of the targeting mode e1082a4
Mikolaj Konarski Mikolaj implement the basic targeting mode commands; close #28
TODO: targeting monsters gets broken as soon as monsters change numbers.
Mikolaj Konarski Mikolaj refactor attack code to show a problem with actor representation
See sn issue on tracker with a similar title.
Mikolaj Konarski Mikolaj simplify the Target type b73debe
Mikolaj Konarski Mikolaj drastically simplify targeting mode; no more accept/cancel
KISS above all.
Mikolaj Konarski Mikolaj cursor is now permanent, though visible only in targeting mode 9f11d75
Mikolaj Konarski Mikolaj cursor no longer taken as argument for Actions
Since cursor is a component of state, it should not be duplicated
as an explicit argument of Action functions that have access to state.
Mikolaj Konarski Mikolaj rename the fields of Cursor e0443f0
Mikolaj Konarski Mikolaj tweaks to variable names and UI messages for targeting 7620e9b
Mikolaj Konarski Mikolaj a few changes and a bit of refactoring of targeting d0c1b04
Mikolaj Konarski Mikolaj rename the Monster/Hero type to Movable 41125e8
Mikolaj Konarski Mikolaj simplified the monsterGenChance formula; more monsters at deep levels…
…, too
Mikolaj Konarski Mikolaj add the (AHero n) form of actor; unused yet 8fb5d5a
Mikolaj Konarski Mikolaj bugfix: forbid closing a door with a hero inside 60cf479
Mikolaj Konarski Mikolaj use AHero to avoid duplicating state in combat; close #34
TODO: many minor points described in #34.
Mikolaj Konarski Mikolaj style: change all foldl to foldl'
(I've just read how unfashionable foldl is and at a glance all the functions
are or should be strict, so changing it to foldr would not make sense.)
Mikolaj Konarski Mikolaj gut out Actor module, to avoid cyclic dependencies later aba4fc2
Mikolaj Konarski Mikolaj the splayer field of state is now an actor; close #34 (again)
TODO: simplification and clean-up
Mikolaj Konarski Mikolaj heroes now have names intead of numbers
No more duplication of the number inside the hero and in the index of the
intmap at which the hero is stored.
Mikolaj Konarski Mikolaj more cleanup: Actors instead of Ints, etc. 3d3ac7a
Mikolaj Konarski Mikolaj bugfix: heroes no longer obscured by the targeting cursor 5c8defa
Mikolaj Konarski Mikolaj nontrivial default names for the first few heroes; configurable 734ef8a
Mikolaj Konarski Mikolaj death message includes the name of the actor
Plus lots of renames, layout fixes, various tiny tweaks.
Mikolaj Konarski Mikolaj asdfasdf b880066
Mikolaj Konarski Mikolaj clean-up complete; operations on current level and all levels separated 50f88bf
Mikolaj Konarski Mikolaj target is now an actor, not a number; close #34 (yet again) 8937a50
Mikolaj Konarski Mikolaj monsters stored on intmap, not time-sorted list; close #34 (for the l…
…ast time)

Asymptotic complexity is the same: finding first monster to move is linear,
but previously inserting the monster back into the time-sorted list was linear.
Mikolaj Konarski Mikolaj add darts as dungeon items, a bit more rare than swords 0940258
Mikolaj Konarski Mikolaj implement the simplest variant of shooting darts 477519c
Mikolaj Konarski Mikolaj bugfix: cycle heroes was off by one b1e07d2
Mikolaj Konarski Mikolaj bugfix: game laoding was broken for darts c330edb
Mikolaj Konarski Mikolaj aiming a wand at a monster puts it under player control
TODO: when the fatigue stat is introduced, monster will be released quickly
TODO: I bet it crashes in cases like inventory management, etc.; review
Mikolaj Konarski Mikolaj moved a comment to the issue on the vty github page c244d18
Mikolaj Konarski Mikolaj fix cycling among monsters and heroes
(Was inaccurate, because there are discontinuities in numeration,
especially for monsters.)
Mikolaj Konarski Mikolaj bugfix: correctly calculate the actor at a target location ad8af59
Mikolaj Konarski Mikolaj if target monster not visible, don't fire at all 70bdc0c
Mikolaj Konarski Mikolaj bugfix: off by 1, when cycling heroes fde611f
Mikolaj Konarski Mikolaj rewrite the cursor and location targetting modes
Now the only way to move from cursor to location is via accepting
with the Return key and the '/' key, in targetting mode, returns
the cursor to the target location.
Mikolaj Konarski Mikolaj add the cursor level field 5f4a91c
Mikolaj Konarski Mikolaj add checks of target validity
In particular, the initial cursor position is invalid, so targetting starts
at player position. Cursor positions set at other levels are invalid, too,
but explicit location targets from other levels are accepted.
Dead or invisible monsters are invalid targets.
Mikolaj Konarski Mikolaj highlight player, even if he's a monster f46dafe
Mikolaj Konarski Mikolaj backup savegames in case of computer hardware malfunction
The backups are removed at game over, so permadeath still enforced.
Mikolaj Konarski Mikolaj generalize Hero to Movable in many places to handle player-controlled…
… monsters
Mikolaj Konarski Mikolaj remove the Hero and Monster types
They are almost never used and not enforced (not newtypes).
Mikolaj Konarski Mikolaj move time management to particular actions
Possibly, it's correct now in all cases. In particular, targeting is free.
Mikolaj Konarski Mikolaj move most of Monster.hs to Movable.hs and Hero.hs b13c7e7
Mikolaj Konarski Mikolaj move hero creation code to HeroState.hs 753e2b7
Andres Löh kosmikus Moved Actor type, rearranged some modules.
Heavily edited by Mikolaj for inclusion in master branch.
Mikolaj Konarski Mikolaj move dungeon setup code to DungeonState.hs
The module does not use State yet, but it's close.
Mikolaj Konarski Mikolaj fix highlighting in terminal frontends ff6b65d
Mikolaj Konarski Mikolaj add per-hero perception; unused 41800b4
Mikolaj Konarski Mikolaj helper functions for actors 23ad4e2
Mikolaj Konarski Mikolaj use multiple perception to determine if a monster sees a particular hero b39b854
Mikolaj Konarski Mikolaj don't target and fire at actors others can see/reach, but you can't d178c1d
Mikolaj Konarski Mikolaj player-controlled monster perceives, too; close #31 2edcc2c
Mikolaj Konarski Mikolaj prevent a player-controlled monster from tageting itself
and let it run, despite seeing a monster (itself)
Mikolaj Konarski Mikolaj enable 16 colors and emulate them in gtk with the Linux console set a6f9199
Mikolaj Konarski Mikolaj replace setBold with explicit bright color selection 82dbed4
Mikolaj Konarski Mikolaj hack vty to display bright colors by abusing the bold attribute db72379
Mikolaj Konarski Mikolaj rewrite color handling in curses 15c0482
Mikolaj Konarski Mikolaj rewrite color usage everywhere
TODO: tweak colors a bit and clean up Display2.hs, then differentiate
visited/currently seen/visited dark/illuminated dark dungeon floor.
Mikolaj Konarski Mikolaj remove savefile if corrupted (but backup first) d0e9837
Mikolaj Konarski Mikolaj all monster type data is now in one place cf8765a
Mikolaj Konarski Mikolaj move the State argument to the rear, to work well with gets 2eb1d33
Mikolaj Konarski Mikolaj a quick fix to increase display spead 592c183
Mikolaj Konarski Mikolaj simplify color management even more fb4db25
Mikolaj Konarski Mikolaj clean-up of Display2.hs 1822170
Mikolaj Konarski Mikolaj indicate LOS and light with colors; close #24 11dea08
Mikolaj Konarski Mikolaj move Dungeon type to Dungeon.hs 83c6b31
Mikolaj Konarski Mikolaj move functions from Level.hs to Geometry.hs and others f65ed2f
Mikolaj Konarski Mikolaj move functions from Level.hs to a newly created GeometryRnd.hs 6ead362
Mikolaj Konarski Mikolaj split Level.hs into halves, the other one called Terrain.hs
-- TODO: let terrain types be defined in a config file. Group them
-- and assign frequency so that they can be used for dungeon building.
-- Goal: Have 2 tileset configs, one small, Rouge/Nethack style,
-- the other big, Angband/UFO style. The problem is that the Rogue walls
-- are very complex, while Angband style is much simpler, and I love KISS. Hmmm.
Mikolaj Konarski Mikolaj half of the display frontend no longer accessible outside 61fa355
Mikolaj Konarski Mikolaj move a few functions from Display.hs to Keys.hs; assorted tweaks b551293
Mikolaj Konarski Mikolaj rename a file and a few types to avoid confusion db79784
Mikolaj Konarski Mikolaj refactor dungeon and movable creation 729c0ac
Mikolaj Konarski Mikolaj new heroes can now easily be generated mid-game
Plus assorted refactorings.
Mikolaj Konarski Mikolaj fix and extend HP regeneration 3efa011
Mikolaj Konarski Mikolaj split Item in two, the half containing item definitions is ItemKind 4e344cc
Mikolaj Konarski Mikolaj gather all properties of an item in its definition; close #11 (almost) f618512
Mikolaj Konarski Mikolaj tweak colors for readability d700b77
Mikolaj Konarski Mikolaj rename Attr.hs to Color.hs 0e2905a
Mikolaj Konarski Mikolaj 26 flavours ought to be enough for anybody c5c829a
Mikolaj Konarski Mikolaj create a separate file for in-game effects 7be79d7
Mikolaj Konarski Mikolaj potions now work via effects 20a0752
Mikolaj Konarski Mikolaj in look mode, differentiate between "look" and "remember" 0ec2133
Mikolaj Konarski Mikolaj give newly spawned monsters and heroes fresh indexes
So that, e.g., target at a dead monster does not carry over
to a new monster by chance.
Mikolaj Konarski Mikolaj all physical damage now done through effects
Lots of TODOs generated.
Mikolaj Konarski Mikolaj wand of domination now works through effects c26a3d8
Mikolaj Konarski Mikolaj add 2 scrolls 2ace9a4
Mikolaj Konarski Mikolaj move the implementation of Effects to a separate file d700898
Mikolaj Konarski Mikolaj add potion of wounding 337d9c4
Mikolaj Konarski Mikolaj improve item UI a bit cd77a31
Mikolaj Konarski Mikolaj split ItemAction.hs off of Actions.hs 45cf165
Mikolaj Konarski Mikolaj refactor ItemAction.hs 98af482
Mikolaj Konarski Mikolaj various UI tweaks a345406
Mikolaj Konarski Mikolaj monsters now discover traitors if adjacent
Plus a lot of reindentation and renaming.
Mikolaj Konarski Mikolaj a bugfix and a few tweaks to items and effects 273aa66
Mikolaj Konarski Mikolaj potion of water was boring; tweaked 4d00940
Mikolaj Konarski Mikolaj prevent free monster moves after domination; second part 8dabd75
Mikolaj Konarski Mikolaj changes and additions to dice rolls for items f9d3c84
Mikolaj Konarski Mikolaj blind monsters don't see, but can smell; even under player domination f799aa1
Mikolaj Konarski Mikolaj only gold and gems count for score
Plus a lot of other tweaks.
Mikolaj Konarski Mikolaj merge the V and R commands bd7a498
Mikolaj Konarski Mikolaj change the probability scaled by level to a more intuitive formula e194de9
Mikolaj Konarski Mikolaj add some magical jewelery 899ffb3
Mikolaj Konarski Mikolaj fix a minor bug in item pickup 6a8b25f
Mikolaj Konarski Mikolaj reindent and comment ItemAction.hs before extending it c529e07
Mikolaj Konarski Mikolaj add item choice '_' that picks the first item on the floor
Not perfect, but it can wait until item management is rewritten
with strong invariants.
Mikolaj Konarski Mikolaj fix messages and removing items from a dead hero's inventory a8a3c43
Mikolaj Konarski Mikolaj speed up the gtk frontend
Plus a few fixes and tweaks (too low barehand damage, bright white
status line for curses, and others).
Mikolaj Konarski Mikolaj implement macros (only single mappings, for now) 14ff83f
Mikolaj Konarski Mikolaj mark important choices by turning the screen black and white e2bc759
Mikolaj Konarski Mikolaj fully evaluate macros to catch errors in their definitions early
And simplify keyTranslate in all frontends.
Mikolaj Konarski Mikolaj for in-game help override default keybindings with player aliases 810d6ee
Mikolaj Konarski Mikolaj simplify the frontend interface even more e0ef25f
Mikolaj Konarski Mikolaj a TODO to have multi-char macros 5d5900b
Mikolaj Konarski Mikolaj avoid useless recomputation of the display function in gtk frontend
At the cost of two list lookups, which is totally not worth it,
but I have a plan...
Mikolaj Konarski Mikolaj dramatic speedup of the gtk frontend 1413f3e
Mikolaj Konarski Mikolaj a bytestring optimization of the gtk frontend c32a171
Mikolaj Konarski Mikolaj unify eyes and noses 61f4c69
Mikolaj Konarski Mikolaj bugfix: monster in shadow couldn't see heroes 302d666
Mikolaj Konarski Mikolaj refactor strategy calculations e95f561
Mikolaj Konarski Mikolaj intelligent monsters move even more steady c2286dc
Mikolaj Konarski Mikolaj strategy now contains actions, not dirs a9a016b
Mikolaj Konarski Mikolaj refactor strategies: pickup not an empty move any more 3d69f3e
Mikolaj Konarski Mikolaj let monsters target heroes and prefer their targets b3b5fb2
Mikolaj Konarski Mikolaj bugfix: nose was too common; wrongly copied from old format ea4a7e1
Mikolaj Konarski Mikolaj add "last seen at" field to enemy target 6a595a9
Mikolaj Konarski Mikolaj unify strategy targetting for heroes and for traitor monsters 4c364f8
Mikolaj Konarski Mikolaj let monsters push through actors if chasing a target 0c8d8a9
Mikolaj Konarski Mikolaj simplify debug commands now that time is advanced manually e4e6055
Mikolaj Konarski Mikolaj improve target reset and guard commands that can use items from the f…
Mikolaj Konarski Mikolaj focus on summoned heroes and let a dying monster emit a dramatic yell 52ecc02
Mikolaj Konarski Mikolaj generalize item usage functions to arbitrary actors da2aa2e
Mikolaj Konarski Mikolaj let monsters apply and throw items sometimes 66e9f55
Mikolaj Konarski Mikolaj bugfix: I was not saving some messages to history
Plus rename of the function that wipes out messages so that it's not used
lightly again.
Mikolaj Konarski Mikolaj let applied items be always cosumed, to prevent AI loops e9a9cd4
Mikolaj Konarski Mikolaj bugfix: fast monsters desynchronized the party by attacking not selec…
…ted heroes
Mikolaj Konarski Mikolaj help monsters find room exits and forbid turning around in corridors c3de966
Mikolaj Konarski Mikolaj overhaul combat messages
Item selection generates messages about the source actor,
applying effect of the item generates messages about the target actor.
Mikolaj Konarski Mikolaj make the default config file closer to its dumped form c042c22
Mikolaj Konarski Mikolaj bumping into walls searches surroundings; close #32 bfc4d8f
Mikolaj Konarski Mikolaj update the manual wrt the game and the game wrt the manual f0b24cf
Mikolaj Konarski Mikolaj change the floor item character from _ to -
I've borrowed it wrongly from Angband.
Mikolaj Konarski Mikolaj limit search by bumping only to walls and when not running 2b0954a
Mikolaj Konarski Mikolaj little edits to manuals 4422943
Mikolaj Konarski Mikolaj use the 'P' key in place of 'M'
Neither Angband nor Nethack use 'M'; let's not be original.
Mikolaj Konarski Mikolaj do not let on a secret door position by disallowing search via bumping fc550fc
Mikolaj Konarski Mikolaj drop individual items instead of whole stacks
TODO: dropping all or a given number of identical items would be nice, too.
Mikolaj Konarski Mikolaj the double mystery about potion of water wasn't as much fun as I expe…
Mikolaj Konarski Mikolaj abort some actions with an empty message
In this way, it's obvious when a move accomplished nothing, e.g.,
a diagonal move from a door after a few bumps into walls that left
searching messages on the screen.
Mikolaj Konarski Mikolaj port to GHC 7.0 7ea7803
Mikolaj Konarski Mikolaj secret doors now searchable; close #32 bd2ab29
Mikolaj Konarski Mikolaj grammar fix: replacing "a" by "the" takes into account "an" 9c28d06
Mikolaj Konarski Mikolaj rebalance the frequency of some items d7d8f0d
Mikolaj Konarski Mikolaj make the fast eye the monster focused on a single (not the closest) foe 5fd0b2c
Mikolaj Konarski Mikolaj don't let blind monsters panic and use items when player in LOS 5d1700f
Mikolaj Konarski Mikolaj let waiting take time for AI monsters; close #42 f04d77d
Mikolaj Konarski Mikolaj update the distributed high scores file 6183089
Mikolaj Konarski Mikolaj add LambdaHack.scores to the release files; see #7 on kosmikus/Lambda…

The releases are not very common, so I'd advocate making the high scores
available, so that the players can relate their scores to anything.
Mikolaj Konarski Mikolaj make the beneficial and interesting scroll more common fc61c15
Mikolaj Konarski Mikolaj fix a typo in README 6222c10
Mikolaj Konarski

I see there is a lot of whitespace changes. Sorry about that --- I've spent enough time on the code that reformatting was very worthwhile for me. I think I was consistent in the changes and most of them adhere to one of the styles you used.

Major changes:

  • +effectToAction :: Effect.Effect -> Actor -> Actor -> Int -> Action (Bool, String)
    items could now be defined in a config file, because, when used, they now have Effects instead of causing hard-coded actions; Effects not only can be evaluated to actions, but also have descriptions, AI valuations, different action for different player commands, etc.

  • rework of the modularization (datatypes, location of functions, decision what is content and what is engine code): Level vs Dungeon, Geometry vs GeometryRnd, Foo vs FooState vs FooAction, items vs. item kinds vs. effects, tiles, vs. tile kinds (this one only started), Movable vs. MovableKind vs. MovableAdd,

  • +lheroes :: Party, -- ^ all heroes on the level
    +lmonsters :: Party, -- ^ all monsters on the level
    multiple heroes, next actor to move searched for in the Party data structure, which is no longer a list sorted by times; heroes and monsters now very interchangeable, but still a long way to get PvsP or a bot doing AIvsAI and run LambdaHack as a screensaver, which I will surely try doing at some point and which would prove the code is extremely well structured

  • lvlChange :: VDir -> Action ()
    rewritten level changing; now it's possible to browse levels other than the current level of the player; e.g., level where other heroes reside or any levels in the targeting mode

  • -lookAround :: Action a
    +targetFloor :: Action ()
    +targetMonster :: Action ()
    +checkCursor :: Action () -> Action ()
    targeting mode replaces look around command; it changes behaviour of some actions; in particular checkCursor is a wrapper for actions that do not make sense if the browsed level is not the one with the current player character on it; the scursor component of the state records the position of the targeting cursor and related data; each hero and monster has his own target, set by AI for monsters and via targeting mode for heroes

  • +advanceTime :: Actor -> Action ()
    +playerAdvanceTime :: Action ()
    time is now advanced manually inside action definitions

  • +deleteActor :: Actor -> State -> State
    +checkPartyDeath :: Action ()
    checking monster and hero death now unified and refactored out; surviving heroes carry on

  • +-- | Resolves the result of an actor running into another.
    +-- This involves switching positions of the two movables.
    +actorRunActor :: Actor -> Actor -> Action ()
    also, a hero bumping into another selects him, bumping into a wall performs a search

  • also: colours and keypresses configurable, colormaps change during the game, frontends refactored accordingly, GTK frontend optimized (not quite enough), colours of items generalized to flavours (color + color name + (in the future) extra description), default config compiled into the binary, extended AI (e.g., monsters use and/or throw all items), juggling multiple perception (from multiple heroes and/or player-controlled monsters)

Mikolaj Konarski

About EDSLs for game content, with reflection:

The refactorings of items vs. item kinds vs. effects and the same started for movables and now also started for tiles in the Allure fork, are a first step to have DSLs for building game content. The crucial point is that the game should be able to modify the content and dump the new definitions so that the content can be automatically pre-balanced each time new content is added and also continuously changed in response to player actions. Ideally the game would also be able to load the new definitions without recompiling. Also, ideally the DSLs would be EDSLs. These two minor goals are in conflict, though, because AFAIK Haskell does not have (comfortable) reflection and, anyway, reflection is a dangerously powerful tool.

Edit: make that one DSL with 3 main types, since some effects will be shared, say, flaming sword, lava and fire elemental will share the flame effect primitive (or combinator taking duration, power, etc.).

Mikolaj added some commits
Mikolaj Konarski Mikolaj improve the playing manual 9cfe372
Mikolaj Konarski Mikolaj make ghc 7.3 happy a03cc33
Mikolaj Konarski Mikolaj revert a part of "abort some actions with an empty message"
This reverts q part of commit 3cd423e
concerning running, because the message for the last move of running
was being lost.
Mikolaj Konarski Mikolaj readd the deprecated syntax for quasiquotes, for 6.12.3 compatibility
Since gtk does not work with most 7.*, compatibility with 6.12.3 makes sense,
even at the cost of incompatibility with 8.*.
Andres Löh kosmikus commented on the diff
((23 lines not shown))
--- | Print message, await confirmation. Return value indicates if the
--- player tried to abort/escape.
-messageMoreConfirm :: Message -> Action Bool
-messageMoreConfirm msg =
- do
- message (msg ++ more)
- display
- session getConfirm
+-- | Print message, await confirmation. Return value indicates
+-- if the player tried to abort/escape.
+messageMoreConfirm :: Bool -> Message -> Action Bool
+messageMoreConfirm blackAndWhite msg = do
+ messageAdd (msg ++ more)
+ if blackAndWhite then displayBW else display
Andres Löh Owner

This indicates that it'd be better to have one function

 display :: Bool -> ...

that takes the BW mode, and just pass the argument through.

Mikolaj Konarski Owner
Mikolaj added a note

implemented in 7f49100

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Andres Löh kosmikus commented on the diff
((20 lines not shown))
-- | Set the current message.
-message :: Message -> Action ()
-message nm = Action (\ s e p k a st ms -> k st nm ())
+messageWipeAndSet :: Message -> Action ()
+messageWipeAndSet nm = Action (\ s e p k a st ms -> k st nm ())
Andres Löh Owner

I think the name is too long.

Mikolaj Konarski Owner
Mikolaj added a note

implemented in a6e2b80

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Andres Löh kosmikus commented on the diff
((6 lines not shown))
currentPerception = Action (\ s e p k a st ms -> k st ms p)
+-- | If in targeting mode, check if the current level is the same
+-- as player level and refuse performing the action otherwise.
+checkCursor :: Action () -> Action ()
+checkCursor h = do
+ cursor <- gets scursor
+ level <- gets slevel
+ if creturnLn cursor == lname level
+ then h
+ else abortWith "this command does not work on remote levels"
+updateAnyActor :: Actor -> (Movable -> Movable) -> Action ()
Andres Löh Owner

Why not rename Movable to Actor, and Actor to ActorId?

Mikolaj Konarski Owner
Mikolaj added a note

implemented in a72f566 and 22d6553

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Andres Löh kosmikus commented on the diff
((72 lines not shown))
run :: Dir -> Action ()
-run dir =
- do
- modify (updatePlayer (\ p -> p { mdir = Just dir }))
- moveOrAttack False False APlayer dir -- attacks and opening doors disallowed while running
+run dir = do
+ pl <- gets splayer
+ targeting <- gets (ctargeting . scursor)
+ if targeting
Andres Löh Owner

Think about doing the mode dispatch elsewhere.

Mikolaj Konarski Owner
Mikolaj added a note

Noted as a TODO comment in the code; extended a bit.

Mikolaj Konarski Owner
Mikolaj added a note

Implemented in 1e7daa2. Done in the simplest way. There are better ways, for sure (as the message aggregation proopsed in TODO inside the changed code), but I'd need some more complex messages to evaluate (e.g., missed blows, criticals).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Andres Löh kosmikus commented on the diff
((123 lines not shown))
+ per <- currentPerception
+ let groupName = "sword"
+ verb = attackToVerb groupName
+ sloc = mloc sm
+ swordKindIndex = fromJust $ L.elemIndex ItemKind.sword ItemKind.loot
+ -- The hand-to-hand "weapon", equivalent to +0 sword.
+ h2h = Item swordKindIndex 0 Nothing 1
+ str = strongestItem (mitems sm) groupName
+ stack = fromMaybe h2h str
+ single = stack { icount = 1 }
+ -- The message describes the source part of the action.
+ -- TODO: right now it also describes the victim and weapon;
+ -- perhaps, when a weapon is equipped, just say "you hit" or "you miss"
+ -- and then "nose dies" or "nose yells in pain".
+ msg = subjectVerbMObject sm verb tm $
+ if isJust str then " with " ++ objectItem state single else ""
Andres Löh Owner

Make combat messages less verbose.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Andres Löh kosmikus commented on the diff
@@ -14,7 +14,7 @@ import FOV.Shadow
import Geometry
import Level
-data FovMode = Shadow | Permissive Int | Digital Int
+data FovMode = Shadow | Permissive Int | Digital Int | Blind
Andres Löh Owner

Should this really be an FOV, or a modifier?

Mikolaj Konarski Owner
Mikolaj added a note

Noted as a TODO comment in the code; extended a bit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Andres Löh kosmikus commented on the diff
((42 lines not shown))
+-- | Display inventory
+inventory :: Action a
+inventory = do
+ items <- gets (mitems . getPlayerBody)
+ if L.null items
+ then abortWith "Not carrying anything."
+ else do
+ displayItems "Carrying:" True items
+ session getConfirm
+ abortWith ""
+-- | Let the player choose any item with a given group name.
+-- Note that this does not guarantee an item from the group to be chosen,
+-- as the player can override the choice.
+getGroupItem :: [Item] -> -- all objects in question
+ String -> -- name of the group
Andres Löh Owner

There should be a datatype for item groups.

Mikolaj Konarski Owner
Mikolaj added a note

Fully agreed. Noted as a TODO comment in the code. Extended a bit as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Andres Löh kosmikus commented on the diff
((2 lines not shown))
+import qualified Data.List as L
+import qualified Data.IntMap as IM
+import Color
+import Effect
+import Random
+data ItemKind = ItemKind
+ { jsymbol :: !Char -- ^ map symbol
+ , jflavour :: [Flavour] -- ^ possible flavours
+ , jname :: String -- ^ item group name
+ , jeffect :: Effect -- ^ the effect when activated
+ , jcount :: RollQuad -- ^ created in that quantify
+ , jfreq :: !Int -- ^ created that often
+ , jpower :: RollQuad -- ^ created with that power
Andres Löh Owner

I think jpower should be part of the Effect. It doesn't make sense for all items, and will mean different things.

Mikolaj Konarski Owner
Mikolaj added a note

Noted as a TODO comment in the code; edited and discussed a bit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Andres Löh kosmikus commented on the diff
@@ -0,0 +1,83 @@
+module Movable where
+import Data.Binary
+import Control.Monad
+import Geometry
+import Item
+import MovableKind
+-- | Monster properties that are changing a lot. If they are dublets
+-- of properties form MovableKind, the intention is they may be modified
+-- temporarily, but will return to the original value over time. E.g., HP.
+data Movable = Movable
+ { mkind :: !MovableKind, -- ^ kind of the movable; TODO: make this Int
Andres Löh Owner

Probably not an Int, but ...

Mikolaj Konarski Owner
Mikolaj added a note

Fixed the TODO and added similar for ItemKind (where it's already an Int, but should probably be a newtype of Int).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Andres Löh kosmikus commented on the diff
((18 lines not shown))
data Item = Item
- { icount :: Int,
- itype :: ItemType,
- iletter :: Maybe Char } -- inventory identifier
+ { ikind :: !Int,
Andres Löh Owner

I don't think this should be an Int.

Mikolaj Konarski Owner
Mikolaj added a note

Added the TODO. I think I will fix this together with ActorKind and TileKind at some point. I'm a bit worried about not being able to use IntMap if I make it a newtype instead of Int, but there is a generalization of IntMap, so I may try to use it instead.

Mikolaj Konarski Owner
Mikolaj added a note

Actually, I've manage to do this without the generalization of IntMap, see #13..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Andres Löh kosmikus commented on the diff
((13 lines not shown))
- modify (updateLevel (updateMonsters (const ms)))
- -- place the monster's possessions on the map
- modify (updateLevel (scatterItems (mitems m) (mloc m)))
- handleMonsters
- | otherwise -> -- monster m should move; we temporarily remove m from the level
- -- TODO: removal isn't nice. Actor numbers currently change during
- -- a move. This could be cleaned up.
- do
- modify (updateLevel (updateMonsters (const ms)))
- handleMonster m
+ ms <- gets (lmonsters . slevel)
+ pl <- gets splayer
+ if IM.null ms
+ then nextMove
+ else let order = Ord.comparing (mtime . snd)
+ (i, m) = L.minimumBy order (IM.assocs ms)
Andres Löh Owner

We should replace this structure using a priority search queue/tree.

Mikolaj Konarski Owner
Mikolaj added a note

Fully agreed. Noted as a TODO comment in the code. With some luck such a structure will be updated to 7.4 before I get to it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Andres Löh kosmikus closed this in f618512
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.