Giter Site home page Giter Site logo

bluetyson / adnd1e-random-dungeon-generator Goto Github PK

View Code? Open in Web Editor NEW
2.0 2.0 1.0 2.46 MB

Convert DMG tables to maked 2d and 3d dungeons, completely stocked with accounting

Python 100.00%
dungeons-and-dragons procedural-generation random-generation advanced-dungeons-and-dragons dnd dnd-tools

adnd1e-random-dungeon-generator's Introduction

Advanced Dungeons & Dragons style random dungeon generator

Convert DMG tables to code to do for wandering around and down to make a dungeon.

Setup

  • simulation is a current dev branch

Environment

  • Only non-standard type libraries used are numpy and pandas [the latter to do dungeon accounting csv, not necessary for dungeon generation]

Running

  • So converting to something else will just need something that can do char/string arrays

  • At the moment it is just run for a number of 'rolls' - PERIODIC CHECK can set in code

    • or overide on command line to do 3 rolls for example:
    python dungeon.py 3
    • If you want to see lots of debugging type help and get the dumped dungeon pickle files - and the downlist for doing a 3D dungeon prototype.
    • You can pass a second 'flag' - 1 is VERBOSITY on, 0 is off - the default. So the below is 20 periodic checks with verbosity on.
    python dungeon.py 20 1  
    • More esoterically there are ROOM CHECK and LEVEL CHECK flags 3 and 4 - note that these ignore PERIODIC CHECK numbers
    • You can try things like 'generate until 365 rooms'
     python dungeon.py 20 0 365 0 
    • note that this may get more than 365 as in room exit secret door checks it can generate more rooms and this flag does not check for that
      • so if looking to get actually 365 for example, may want to experiment with runs with smaller numbers than 365
    • Less interestingly, 'generate until 5 levels'
     python dungeon.py 20 0 0 5 
    • with traps and things, you can get more with elevators parts in them, in this case
    • Or, 'generate until 32 rooms and 4 levels'
     python dungeon.py 20 0 32 4 
    • see caveats above

Binder

  • click the below to fire up a web container environment that lets you run this in your browser
  • you get jupyterlab, just click on the terminal link at the lower left and then type 'python dungeon.py 1' [or however many rolls as you like] and the files created will also be in the main directory, one for each dungeon level. Binder

Binder Example

image

Work in progress

Building things as I go - just using a one roll test for now to see how it goes.

  • Generates monsters in rooms
  • Generates treasures in rooms
  • Rolls for gems and jewellery
  • Generates an in lair roll
  • Generates basic individual treasure
  • Does dungeon accounting - adds up treasure and some XP metrics and traps, wet monsters
    • Outputs this to a csv when run
  • Links to each level are at the bottom of each Dungeon Level html page
  • Keys are now just for the specific level
  • an example Dungeon with lots of Chasms https://bluetyson.github.io/ADnD1e-Random-Dungeon-Generator/dungeon_4.html
  • now uses facings, so should be a bit less wandery and somewhat more square at times, e.g. can get long angles etc.
Monster Total XP:71798

Monster Total Treasure:{'copper': 6000, 'silver': 6000, 'electrum': 42558, 'gold': 53794, 'platinum': 29000, 'gems': 29, 'jewellery': 12, 'magic': 0}

Monster Total Valuations:{'gems': [110.0, 800.0, 5.0, 12.0, 500, 16.0, 500, 1000, 120.0, 20, 100, 25.0, 50, 120.0, 8.0, 14.0, 1000, 20, 110.0, 800.0, 5.0, 12.0, 500, 16.0, 500, 1000, 120.0, 20, 100, 25.0, 50, 120.0, 8.0, 14.0, 1000, 20, 10, 65.0, 100, 100, 5.0, 2000, 200, 50, 50, 500, 90.0, 10, 65.0, 100, 100, 5.0, 2000, 200, 50, 50, 500, 90.0], 'jewellery': [4000, 6000, 300, 1000, 4000, 1200, 4000, 500, 4000, 1600, 900, 9000], 'magic': [], 'magic_xp': [], 'magic_values': [], 'magic_list': []}

Wandering Monster Total XP:829030

Wandering Monster Total Treasure:{'copper': 427, 'silver': 234, 'electrum': 0, 'gold': 733, 'platinum': 42, 'gems': 35, 'jewellery': 0, 'magic': 0}

Wandering Monster Subtable:['monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'human', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'character', 'monster', 'monster', 'monster', 'monster', 'dragon', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'character', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'dragon', 'character', 'monster', 'monster', 'dragon', 'dragon', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'character', 'monster', 'monster', 'monster', 'monster', 'dragon', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'character', 'character', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'dragon', 'character', 'monster', 'monster', 'dragon', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'monster', 'character', 'monster', 'monster', 'monster', 'dragon', 'monster', 'monster', 'monster', 'character', 'monster', 'monster']

Room Total Treasure:{'copper': 132200, 'silver': 65400, 'electrum': 48525, 'gold': 15750, 'platinum': 3030, 'gems': 33, 'jewellery': 0, 'magic': 3}

Room Total Gems:5453.0

Room Total Jewellery:0

Room Total Magic:20400
Total Treasure: {'copper': 138627, 'silver': 71634, 'electrum': 91083, 'gold': 70277, 'platinum': 32072, 'gems': 97, 'jewellery': 12, 'magic': 3}
Coins: 445088.17
Gems: 20633.0
Jewellery: 15180.0
Magic: 20400
Total Gold Equivalent: 501301.17
  • Does basic Human and Character subtables (for running into adventuring parties)
1 : {'class': 'THIEF', 'level': '1', 'race': 'Human', 'multi': 'N', 'magic_items': []}
2 : {'class': 'FIGHTER', 'level': '1', 'race': 'Gnome', 'multi': 'N', 'magic_items': []}
3 : {'class': 'woman-at-arms/henchwoman'}
4 : {'class': 'woman-at-arms/henchwoman'}
5 : {'class': 'man-at-arms/henchman'}
6 : {'class': 'man-at-arms/henchman'}
7 : {'class': 'woman-at-arms/henchwoman'}
8 : {'class': 'woman-at-arms/henchwoman'}
9 : {'class': 'man-at-arms/henchman'}
  • Dragons
monster:{'level': 10, 'type': 'Dragon-Copper:2', 'No': '2-2', 'XP': 0}
treasure:{'type': {'copper': 23100, 'silver': 0, 'electrum': 0, 'gold': 0, 'platinum': 0, 'gems': 0, 'jewellery': 0, 'magic': 0}, 'gems_list': [], 'jewellery_list': [], 'magic_list': [], 'magic_xp': [], 'magic_values': [], 'store': 'Bloody Great Chests', 'protection': 'guard', 'guard': 'Blade: across inside'}
  • They are given a basic set XP value. Have not found a table where someone has worked out every age combination and XP as yet.

  • Same goes for generic adventuring parties.

  • Adventuring parties at lower levels with henchpeople

monster:{'level': 9, 'type': {1: {'class': 'CLERIC', 'level': 9, 'race': 'Human', 'multi': 'N', 'magic_items': [['1 JAVELIN +2'], ['1 MACE +1'], ['1 SCROLL: protection from magic'], ['1 SWORD: +3 (no special abilities)'], ['1 FIGURINE OF WONDROUS POWER: serpentine owl']]}, 2: {'class': 'BARD', 'level': 9, 'race': 'Elf', 'multi': 'Y', 'multi_no': 3, 'magic_items': [['1 SCROLL: protection from magic'], ['2 POTIONS: super-heroism, animal control'], ['2 POTIONS: extra-healing, polymorph (self)'], ['1 SCROLL: 3 Spells, level 2-9 or 2-7'], ['1 bracers of defense, armor class 4']]}, 3: {'class': 'CLERIC', 'level': 9, 'race': 'Human', 'multi': 'N', 'magic_items': [['1 MACE +1'], ['1 RING: protection +1'], ['4 BOLTS: +2'], ['1 WAND: illusion'], ['1 RING: protection +3']]}, 4: {'class': 'FIGHTER', 'level': 9, 'race': 'Human', 'multi': 'N', 'magic_items': [['1 SWORD: +4, defender']]}, 5: {'class': 'MAGIC-USER', 'level': 9, 'race': 'Human', 'multi': 'N', 'magic_items': [['1 JAVELIN +2'], ['1 RING: protection +1'], ['10 ARROWS: +1'], ['2 WEAPONS: crossbow of speed, hammer +2'], ['1 bracers of defense, armor class 4'], ['1 pipe of the sewers']]}, 6: {'class': 'CLERIC', 'level': 3, 'race': 'Human', 'multi': 'N', 'magic_items': [['3 javelins of lightning']]}, 7: {'class': 'FIGHTER', 'level': 3, 'race': 'Human', 'multi': 'N', 'magic_items': []}, 8: {'class': 'MAGIC-USER', 'level': 3, 'race': 'Human', 'multi': 'N', 'magic_items': []}, 9: {'class': 'FIGHTER', 'level': 3, 'race': 'Human', 'multi': 'N', 'magic_items': [['1 SCROLL: 1 Spell, level 1-6'], ['2 POTIONS: human control, levitation']]}}, 'No': 9, 'XP': 0}
treasure:{'type': {'copper': 25300, 'silver': 0, 'electrum': 0, 'gold': 0, 'platinum': 0, 'gems': 0, 'jewellery': 0, 'magic': 0}, 'gems_list': [], 'jewellery_list': [], 'magic_list': [], 'magic_xp': [], 'magic_values': [], 'store': 'Sacks', 'protection': 'hide', 'hide': 'Secret: Disguised as other'}
  • No retracing steps logic as yet for dead ends to block etc.
  • See issues for things to do [lots of minor things]

Bugs

  • Will be quite a few I imagine, mostly minor or things to do with set facings or placements.
  • Most of the data should be ok now.

Output to screen for checking purposes

  • Makes a basic html map for a level in dungeon_1.html

    • if there are other levels, dungeon_2.html etc.
    • number the rooms basically
  • the current legend, in code

  • these get concatenated to the base type, C, R, D

  • treasure gets some color coding

  • outputs room data

  • outputs relevant room key

  • gives a treasure total accounting at the end

legend_dict['O'] = "Outside Entrance"
legend_dict['C'] = "Corridor/Passage"
legend_dict['R'] = "Chamber/Room"
legend_dict['D'] = "Dead End"
legend_dict['CH'] = "Chasm"
legend_dict['ri'] = "river"
legend_dict['br'] = "bridge"
legend_dict['bo'] = "boat - opposide side"
legend_dict['bn'] = "boat - near side"
legend_dict['L'] = "Lake"
legend_dict['P'] = "Pool"
legend_dict['W'] = "Well"
legend_dict['S'] = "Shaft"
legend_dict['d'] = "door"
legend_dict[':'] = "direction of Door"
legend_dict['wm'] = "Wandering Monster"
legend_dict['sd'] = "Secret Door"
legend_dict['st'] = "Stairs"
legend_dict['ch'] = "Chute"
legend_dict['cm'] = "Chimney"
legend_dict['td'] = "Trapdoor"
legend_dict['pi'] = "Pit Trap"
legend_dict['pt'] = "Pit Trap: Secret Door"
legend_dict['ps'] = "Pit Trap: Spikes"
legend_dict['pc'] = "Pit Trap: Crushing Walls"
legend_dict['el'] = "Elevator Trap"
legend_dict['ar'] = "Arrow Trap"
legend_dict['sp'] = "Spear Trap"
legend_dict['df'] = "Door Falls Trap"
legend_dict['sf'] = "Stone Falls Trap"
legend_dict['gs'] = "Gas Trap"
legend_dict['bw'] = "Blocked Wall Trap"
legend_dict['ol'] = "Oil Trap"
legend_dict['m'] = "Monster"
legend_dict['t'] = "Treasure"
legend_dict['p'] = "Pool"
legend_dict['c'] = "Treasure: Copper"  
legend_dict['s'] = "Treasure: Silver"
legend_dict['e'] = "Treasure: Electrum"
legend_dict['g'] = "Treasure: Gold"
legend_dict['p'] = "Treasure: Platinum"
legend_dict['G'] = "Treasure: Gems"
legend_dict['j'] = "Treasure: Jewellery"
legend_dict['M'] = "Treasure: Magic"

Example html testing output

Level 1

image

Level 2

image

Level 3

image

Level 4

image

Dungeon level html now include a basic key output dictionary e.g. basically using this while I work on things: Below is an example unrelated to above plots.

Key: 1

Data: 23
{'shape': 'R', 'size': [1, 2], 'contents': {'monster': {'level': 8, 'type': 'Xorn', 'No': 5, 'XP': 0}, 'treasure': {'type': {'copper': 0, 'silver': 0, 'electrum': 0, 'gold': 2200, 'platinum': 0, 'gems': 0, 'jewellery': 0, 'magic': 0}, 'gems_list': [], 'jewellery_list': [], 'store': 'Sacks', 'protection': 'hide', 'hide': 'Secret: Loose stone - in wall'}, 'secret_door_dict': {}, 'secret_door_count': 0}, 'exits': 0, 'secretdoors': 'check', 'exitlocations': {}, 'exitdirections': {}}

Key: 23
monster:{'level': 8, 'type': 'Xorn', 'No': 5, 'XP': 0}
treasure:{'type': {'copper': 0, 'silver': 0, 'electrum': 0, 'gold': 2200, 'platinum': 0, 'gems': 0, 'jewellery': 0, 'magic': 0}, 'gems_list': [], 'jewellery_list': [], 'store': 'Sacks', 'protection': 'hide', 'hide': 'Secret: Loose stone - in wall'}

Level 1 html example

<html>
<head>
<title>DUNGEON</title>
<style>
    table,
    th,
    td {
        padding: 10px;
        border: 1px solid black;
        border-collapse: collapse;
        width:auto
    }
    .red_background {
            background-color: red;
        }
    .green_background {
            background-color: green;
        }
    .gray_background {
            background-color: gray;
        }
    .grey_background {
            background-color: grey;
        }
    .brown_background {
            background-color: brown;
        }

    .blue_background {
            background-color: blue;
        }
    .black_background {
            background-color: black;
        }

    </style>
</head>
<body>
<table>
<TR><td class="black_background">B</td><td class="green_background">O</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td></TR><TR><td class="black_background">B</td><td class="red_background">st</td><td class="black_background">B</td><td class="black_background">B</td><td class="red_background">cm</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td></TR><TR><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td></TR><TR><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td></TR><TR><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td></TR><TR><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td></TR><TR><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td></TR><TR><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td></TR><TR><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td></TR><TR><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td></TR><TR><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td></TR><TR><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td></TR><TR><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td></TR><TR><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td></TR><TR><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td><td class="black_background">B</td></TR>
</table>
</body>
</html>

#3D View example - 200 Periodic Check Dungeon image

Future possibilities

  • See issues

  • Filling in is more complicated take the exit stack, follow them - if get to a bounds, stop, take the next exit?

  • Level "N"

    • there is a flag Level that if you set to "N" if won't go down past the first level
    • no checking to see if it gets stuck though, which could happen e.g. if script is running for 30sec+ it probably has
      • no flags for this as yet, but you can just change the "Y" to "N" in dungeon_simulation.py

References

adnd1e-random-dungeon-generator's People

Contributors

bluetyson avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar

Forkers

w0rt0x

adnd1e-random-dungeon-generator's Issues

Room stack

with contents etc. for output/plotting

trap stack?

Room contents

all the stuff in and exits - should that be returned in shape dict or be placed?

Dungeon Dressing

See Alex Schroeder's Hex Describe and similar for possibilities.

A further down the track once it is working addition.

Fancy rooms

Not implemented - all rooms currently rectangular

Random Monster Table to do

Level stack

Add level st ack from level amd traps that go down

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.