Dungeons - simple procedural map generator

If not, maybe include a sample call to the example dungeon to be clear.... A sample call for each function using the getDungeon call as sample data would help me here a ton.

Here’s the API written out with a single example used throughout. I’ve decided to remove the getRooms() and getHallways() calls for now because I don’t think there’s an easy way to make them deterministic (e.g. always return the top left room first) given the code length constraints of the smart contract. May revisit this if there’s alot of demand but it’s fairly trivial for developers to identify rooms from the getDungeon() call.

API

The dungeon contract exposes the following endpoints to allow developers to use and query dungeons in their games and applications.

We’ll use this dungeon for all examples below:

dev-example

Dungeon Geometry

getDungeon() (array) - Returns a 2D array representing all tiles in the dungeon as ascii characters. The array uses a zero-based index and the top left corner of the dungeon starts at (0, 0). We’ll use this dungeon as an example for subsequent calls:

[
['X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'],
['X', 'X', 'X', 'X', ' ', 'i', ' ', 'X'],
['X', ' ', ' ', 'X', ' ', ' ', ' ', 'X'],
['X', ' ', ' ', 'X', ' ', ' ', ' ', 'X'],
['X', ' ', ' ', 'X', ' ', ' ', ' ', 'X'],
['X', ' ', ' ', ' ', 'D', ' ', 'X', 'X'],
['X', ' ', ' ', 'X', 'X', 'X', 'X', 'X'],
['X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'],
['X', 'X', 'X', 'X', 'X', 'X', 'X', 'X']
]

Dungeon Attributes

getName() (string) - Returns the name of the dungeon. In our example: Den of the Twins.

getEnvironment() (int) - Returns the environment of the dungeon. There are six total environments and each affects the color of the original SVG. Developers can choose to embrace or ignore these environments. In our example: 0

numDoors() (int) - Returns the number of doors present in the dungeon. In our example: 1.
Useful for: Querying for dungeons with a specific number of doors.

numPoints() (int) - Returns the number of points of interest present in the dungeon. In our example: 1.
Useful for: Querying for dungeons with a specific number of points.

numFloors() (int) - Returns the number of accessible floor tiles in the dungeon. This includes doors and points of interest. In our example: 26
Useful for: Determining probabilities of objects based on the amount of floor space. Making sure a given dungeon is suitable for a given party size.

numTiles() (int) - Returns the overall size of the dungeon. In this case, we have an 8x8 dungeon, so in our example: 64
Useful for: Querying for dungeon based on size

Specific Locations

getDoors() (array) - Returns a list of coordinates of doors. Coordinates are represented as an array of [x, y]. In our example: [ [4, 5] ]

Useful for: Querying for dungeons that have doors in a specific location

getPoints() (array) - Returns a list of coordinates of points of interest. Coordinates are represented as an array of [x, y]. In our example: [ [5, 2] ]

getTile(x, y) (char) - Returns the character at a specific tile. Characters used are as follows:

'X': wall
' ': floor tile
'D': door
'i': point of interest

I’m also considering converting getDungeon() from an array to a uint256 or string. The int would contain integers to represent tiles (similar to the array) or the string would contain characters to allow us to scale to more use cases (e.g. decorative art).

Reconstructing the dungeon: Because all dungeons are square, you can deduce the size of the dungeon by taking the sqrt() of the string’s length. You can treat the first character as the top left (0, 0). This allows you to create a 2d array in a few lines of code.

For example the above example dungeon would become:
00000000000013100110111001101110011011001112100011000000000000000000000

'0': wall
'1': floor tile
'2': door
'3': point of interest

This is a little bit harder to process but dramatically compresses the amount of data sent over the wire. Because dungeons are always square, it becomes really simple to reconstruct the dungeon as an array from this int.

1 Like

Initial thoughts on drop mechanics here. Would love to hear peoples’ thoughts on introducing an inflationary mechanic that produces new dungeons over time (like a drip feed of content).

Drop Structure

There are 9000 Dungeons. 8000 are gated to loot holders at 0.02ETH. 1000 are available to the public at 0.1ETH (to allow for lower entry). Loot holders have 72h to claim their dungeon before the drop opens to the public.

After this, one dungeon will release per week to a random Loot holder. The loot holder will need to pay 0.1ETH to mint this new dungeon.There are 9000 Dungeons. 8000 are gated to loot holders at 0.02ETH. 1000 are available to the public at 0.1ETH (to allow for lower entry). Loot holders have 72h to claim their dungeon before the drop opens to the public.

After this, one dungeon will release per week to a random Loot holder. The loot holder will need to pay 0.1ETH to mint this new dungeon. If the dungeon goes unclaimed for 72h, it becomes available to mint by anyone for 1ETH.

I hope that this will create a cadence of new content that gets released. The dungeon will be made available for minting with a seed based on the tokenId. This means that future dungeons can be predicted, just not claimed until they are released.

I hope that this will create a cadence of new content that gets released. The dungeon will be made available for minting with a seed based on the tokenId. This means that future dungeons can be predicted, just not claimed until they are released.

Love this idea! Once Dungeons is shipped, what do you think of collaborating on a new entity that uses both Dungeons and Monsters (for Adventurers) to create ‘quests’?

Each Monster is randomly generated and is weak to a single weapon type (e.g. Books, Long Swords, etc.) There are a getWeakness(), traitsOf(), and canSlay() functions you can use to determine if dungeoneers can slay a Monster. Monsters (for Adventurers)

Monster stats can be generated from a combination of the Dungeon attributes and Monster traits. The canSlay() result can give adventurers a bonus or Critical against that monster.

Happy to collaborate on a future proposal that combines Dungeons and Monsters.

Once again, very cool stuff!

1 Like

I think instead of using a string of ints something like comma separated ints or another longer ID may make more sense. With ASCII you may run out of characters if you want to add future primitives or “space types” to the dungeon format in the future. Assuming I’m understanding what you’re asking here.

Great point. I didn’t think about the fact that others might want to expand this spec and add more types.

I suspect we could use a string for this. I’ll look into memory limitations (e.g. for 35x35 dungeons).

I’ve updated the above spec accordingly.

1 Like

I like your use of color in defining this new archetype, it adds flavor. You’re right that there’s certainly a higher-order structure which combines Dungeons and some manner of foe into a larger experience.

Your description of a Monster functionally beckons other supporting systems, like a Damage Model with immunities/weaknesses, a Poison / DoT Module, and racial traits.

In the interest of interoperability It may be helpful to think in terms of defining the elemental primitives that are exclusive to a Monster in the same way that threepwave has defined the elemental primitives that are exclusive to a Dungeon.

Just caught up on the thread! Chiming in to once again voice support for the direction you’re taking this, with such emphasis on interoperability.

I also think the drop mechanics are fair! The .1 eth for non loothodlers to claim seems right to me. Low barrier to enter for those who are early.

For the weekly drops, might I suggest dropping two per week? The first claimable for the initial lootholder, @ .1eth, but then the second available for new entrants @ 1 eth? Once the value of dungeons rise above .1, I don’t see a world where the lootholder fails to mint at .1.

Perhaps you could even consider releasing them with a bonding curve? Like how moonshot bots launched?

By using a bonding curve, mint price over time could reflect general market price as it rises! (Also could allow a portion of mint price to flow to an organization/Dao to fund/seed projects that are built on top of dungeons!)

Feel free to message me on twitter if you want to chat more! @russmatthews32

1 Like

Great idea on the drop mechanics and good point that we should offer drops to non-loot holders from the get go. I like the idea of two per week and wonder how we can keep it simple. Bonding curves become challenging over time. Would love to kick off a dutch auction every week but I want to keep this incredibly simple.

Let me think about how to make that fair.

I was thinking that a dutch auction would make sense, but couldn’t figure out how you might be able to write that into the smart contract!

I also am not that advanced w/ solidity :smiley:

I’ve created separate thread with a ‘final’ API proposal to signal boost and get more feedback: Input Needed: API Design for Dungeons (which could inspire future lands, town, etc)

The document is more comprehensive and also has an updated project overview. I’ve also published this to a github repo where i’ll also share the source code once the contract has been published: https://github.com/threepwave/loot-dungeons

1 Like

Migrating @IraFudmore’s response here:


**Mint Allocation Details**
There’s likely to be a gas rush. You could go the contributory meritocratic route and do a pseudo-timestamp model for who contributed before Dungeons were cool. Dungeons Hipsters, as it were.

You could also keep a few pre-emptively set aside for a mini-grant that you use to sell for liquidity to incent other modules to integrate the project.

**Acknowledgment**

* Acknowledging OG Loot holders
  * For inclusion consider mLooters get some middle pricing – like 0.05 or something
* That .1 Eth is brutal for normies… But also not insignificant for VC posers, so maybe I like it…

I know some don’t like or even dislike the mLooters but by giving them a middle tier you acknowledge them while still acknowledging they’re not OGs. It’s your choice ultimately, I’m not married to the idea.

**Inflation / Deflation**
You create a constant expectation of inflation. I really had to think about that.

That makes me think the asset price wont balloon because users know their item loses value
daily.

However, it also makes me think that you have a content factory constantly cranking out new stuff. The content production pipeline is the lifeblood of live operations; staying ahead of player behavior is what passes or fails live games. Players always find a way to stay ahead – but it’s a motherfucking boolean for Dungeons lol.

Provided that we get people onboard integrating the Dungeons into some form of consumable content I have 0 concerns. Hell, maybe if someone “beats” a dungeon (however that manifests) it gets retired from the list somehow. Narratively: “the dungeon is cleared and no longer a threat”. Functionally: we get persistent consistent inflation plus a straightforward potential deflationary mechanism.

It’s edgy, and requires work, but I like it.

**Inflation / Deflation: Part Deux**

> After this, two dungeons will release per week:
>
>
>
> One to a random wallet that holds OG Loot. The loot holder will need to pay 0.1ETH to mint this new dungeon. If the dungeon goes unclaimed for 24 hours, it becomes available for mint by anyone for 1ETH.
>
>
>
> One open to anyone for 1ETH. This will allow new users to have a chance at owning a dungeon.
Like the required activity / lotto; and it functionally encourages holding. This synergizes with the inflation well, since it removes liquidity without encouraging sells.

Is 2/10000 daily odds good for a lottery?

I want to say so but interested in hearing others’ thoughts. My only gambling is crypto and honestly if you read a lot the odds are pretty good.

BIG ALSO: this is new code outside of the template.
I don’t know solidity, but in my experience this is the kind of thing someone would find an exploit for to give themselves all the things and fuck the project.
For anything non-standard I would request for an audit early, possibly pre-mint.

How are you surfacing that someone has the golden ticket and wins the weekly prize?
A readContract function call would be the simplest way I can think of.

Again the pricing! 1 Eth for the newbies HOLY. I get it though. Bloody moneygrubbing VC moochers (whom are admittedly some of my irl friends but still). An intermediary element here would be a mid-tier for alt-loot projects at .66 ish.

**Your Alt-Loot Thoughts**
…How do you actually feel about xLoot/mLoot/SynthLoot/etc. ? I view them as a second-class citizens in a first world nation; they deserve the worst of the best. Non-holders on the other hand are foreigners and should pay hefty taxes to live in OUR GREAT NATION. This becomes more pronounced as time passes and the alt-loots progress to a price floor similar to the current Loot price floor.

Migrating thoughts from @matto-matto

I am probably an outlier in that I would distribute heavily to non loot holders and make everything much cheaper. There’s a big rich get richer dynamic and all the loot is getting into hands of speculators not builders or players. If everything just gets air dropped to the rich few this community dries up imo. I think we need new things to bring new people into the community, not reward the very small group who either got in early or could drop 30k worth of eth on secondary.

Migrating comment from @bobolo333

I was thinking something similar about the inflationary/deflationary dynamic–if the use of Dungeons is expanding, adding new dungeons consistently seems great (kind of like Nouns project–the number that will be added is consistent and known by the community), but also I was curious about adding a “deflationary” element, where old dungeons are retired/burned so the supply doesn’t get too big. (but also having new elements to play with is just great.)

Also, I am a total noobie without Loot, and I agree that even the initial .1 entry will actually still be high for a lot of people. I wonder if there are ways to make Dungeons accessible to individuals who just missed the Loot boat but are interested in the community while avoiding gas wars/VC/flippers…though that seems like an issue all projects are facing right now

Migrating my response to @bololo333

I am viewing dungeons a bit like ‘Land’ in that hopefully collecting them will generate value over time (e.g. perhaps you earn AGLD when people visit your dungeon?) If this is the case, even 0.1ETH should be trivial compared to the monthly earnings possible from a dungeon.
I’m trying to learn from what I’ve seen with Art Blocks pricing over time - scarce resources quickly become impossible to enter for anyone and even new mints result in insane gas wars because the upside to flip/sell is so high.
2 Likes

I’ve taken another swing at the drop structure based on feedback. Adjusted to focus less on ‘cost of mint’ and more on ‘generate long term value (for users and developer):’

Drop Structure

There are 10000 Dungeons. 7777 are gated to whoever owns OG Loot with no fee beyond gas. 2000 are available to the public at no fee beyond gas (to allow for new entrants). The remaining 233 are reserved for those who worked on the project. Loot holders have 72h to claim their dungeon before the drop opens to the public.

After this, two dungeons will release per week:

  1. One to a random wallet that holds OG Loot. The loot holder will only pay gas to mint this new dungeon. If the dungeon goes unclaimed for 72 hours, it becomeos available for mint by anyone for 0.1ETH.
  2. One open to anyone for 0.1ETH. This will allow new users to have a chance at owning a dungeon.

I hope that this will create a cadence of new, interesting content each week and create incentives for game designers and developers to continue supporting these new dungeons.

We will reserve 233 dungeons and take a 1% fee of aftermarket sales to cover development costs and fund future marketing/development expense.

4 Likes

This is my favorite version so far.

1 Like

Yea! This looks great! Any idea when you’ll likely drop this?

I think it’ll still be a bit (sadly)!

I want to hear more thoughts on the API (@matto-matto has already raised really good points I need to figure out if/how to incorporate). @IraFudmore is helping iron out names/locations.

After that, need to port everything to solidity and solve two technical challenges:

  1. Proper random number generation (being discussed in the builders thread)
  2. How to do timed releases (vs everything available at once)
2 Likes

Is there an expectation that the dungeon rooms should all be connected by hallways? How is one supposed to travel between disconnected rooms?

Does it make sense to create an entry point tile as well?

love the concept of dungeons being like ‘land’–and yes, .1 ETH looks like a tiny amount in that context.

and yeah, in Loot world especially, prioritizing user/player ownership and access seems extra vital–since the worlds vitality requires ongoing use, development and engagement in a way that art pieces don’t

1 Like

Currently, the dungeon rooms are not all connected to allow for things like secret passage ways, treasure rooms, etc.

My expectation is that by not placing an explicit entry/exit, game designers and developers can place entries/exits based on what makes sense for their game. E.g. They may spin the map 180 degrees, place entrance/exit on the same tile… or do something totally different.

I’m hoping to leave this up to the interpretation of the encounter designer (and envision another entity called ‘encounter’ that sits on top of this to determine spawn points, monsters, rewards, etc)

2 Likes