All RPGs and Storygames by Tod Foley are now available at DrivethruRPG and RPGnow. Bring these games to your table!
Mojang's digital card game Scrolls is going offline for good this month. The game was up and running for nearly 5 years. ...
This module provides very basic Adobe analytics integration.
Currently this module only:
- Allows customization of which pages analytics are enabled on, via a similar interface to how blocks visibility is controlled.
- Adds the service and accessrights meta tags Adobe analytics requires (other metatags should be set with a module like metatag).
- Links Adobe's custom JS required for your Adobe Analytics account.
DrupalCon has long had a Code of Conduct that we all agree to as part of participating in the event. It was originally derived from the Drupal Code of Conduct and added sections specific to in-person events.
We are constantly striving to improve all that we offer to make DrupalCon a great event for all Drupal professionals and it is now time to make a change to our DrupalCon Code of Conduct.Making a positive change
When I first started at the Drupal Association at the beginning of the year, I was very pleased to discover that the Association staff had already made significant progress on an updated version of the DrupalCon Code of Conduct that included clearer description of what is expected of participants at DrupalCon, where various responsibilities were held for enforcement and what consequences should be expected for falling foul of the code. As the new Community Liaison, though, it was important that I took this work to the Drupal and wider web professional community and gained further insight into producing something that worked for us all.Consulting the community
Having spent time on the Community Working Group, I was aware that consulting the community at large is hugely important but can be a huge undertaking that can potentially become never ending. Indeed, when the original Drupal Code of Conduct was in development, the process took many months to reach a result. Whilst we wanted to involve people, we also wanted to deliver something better than the current Code in time for DrupalCon Nashville 2018.
So, my methodology was to choose eight people from different parts of our community to comment on the draft Code of Conduct, plus ask them to nominate two extra people who I should also ask to make comment. I requested that they nominate someone who they felt would have a similar outlook to themselves and someone they thought might have a different outlook. This meant we had a focused team of people from the community that could work on this over a very short period, but one that I knew wouldn’t be overly influenced by my personal choices. I was also careful to choose people from several continents.
The vast majority of suggestions and comments they proposed were accepted, either directly or with some adjustment by either Association staff or our lawyers. At the end of the day, the code has to be legal, enforceable and protect both conference participants and the project’s legal entities.The New Code
The draft has now been reviewed by Drupal Association staff, Drupal Community members and the Drupal Association Lawyers. It is ready to go and will now be applied to DrupalCon Nashville 2018.
I do want to talk about a few of the improvements we have made, though.Clarity
One of the challenges of the old Code was that, whilst being very positive, it failed to make it clear to all DrupalCon participants exactly what was expected of them. We have taken the time to write about what behaviors are and are not acceptable in the context of DrupalCon. You will also see that we clearly state that the expectations of leaders at DrupalCon are expected to uphold even higher standards.Our actions have consequences
We have also added sections that detail exactly what is expected of people and how failing those requirements will be dealt with.
One of the significant changes here is we separated the responsibilities for dealing with unacceptable behavior from that of supporting participants in resolving conflicts. Who to contact in the case of each is more clearly displayed, along with exactly who will be initially handling reported incidents.Best practices
We didn’t just make all this up. We spoke with many organisations and used well-known best practice where it was available. We have detailed where much of the best practice was found at the end of the Code of Conduct.
We are also sharing the new DrupalCon Code of Conduct under a Creative Commons license, as before. If you are organising a Drupal event, you are very welcome to make use of this and add in your own contact information.Release early, release often
Finally, I want to talk about the future. As mentioned earlier, whilst we consulted members of the Drupal Community, we were not able to incorporate all their comments at this time. Some comments would simply not have met our objectives to protect the Community and the Project but others, whilst beneficial, require further development that would mean we would not be ready for Nashville. There are also other initiatives taking place within the overall Drupal Project, like the refreshing of the Drupal Project’s value statement and a Drupal Community Code of Conduct, that we would want to incorporate back into the DrupalCon Code of Conduct. I’m sure the aforementioned best practices will evolve over time, too, and I want a mechanism where we can take advantage of that.
Well, we already have an established (and, I feel, successful!) process in Drupal Core; which now makes releases on a regular schedule. I propose that we make an annual DrupalCon Code of Conduct release, at this time each year. I will be setting up a project to manage this. So, if you believe there are ways we can still improve our Code of Conduct, there will be a mechanism to achieve it.
In part 2 of this three-part series, we showed you how to set up you config management flow. In this part we’ll be looking at some use cases and common issues related to config management.
Starting on a new issue, or finishing one
There is an important must-do before you start developing on a new issue, after you’ve pulled the latest code with Git. Don’t forget to always do an import of the configuration first! It should become second nature to do a “drush config-import -y” or shorthand “drush cim -y” just after a Git pull or checkout.
When you finish one, you should do a “drush config-export -y” or shorthand “drush cex -y” and check the exported files before committing your changes.
To set live-specific configuration, you have two options:
- Set the config using the settings.php file directly on that environment
- Make split that is active on that environment
The general rule is to export your configuration in the sync folder and override for the environment that differs.
The following example should make this a bit clearer. Imagine you have an API that you need to connect to. Your local, development and staging environment should all connect to the development version of the API, while the live environment should connect to the live API.
If you have a lot of configuration to do for your API connection, you can choose to use config split to solve your problem. We can state that most environments need to connect to the development API; therefore this config should be stored in the sync folder, so it gets imported onto all environments. We then need to override that config for the live environment by using a config split that is only active on the production environment.
In practice, you would go about it in the following way:
- Make sure you have set up your environment settings files as described above
- Configure the dev settings in the configuration form
- Use “drush cex” to export all updated configuration
- Check Git if your changes have been added to the sync folder
- Go back to the config form and configure the live settings as if you were on a live site
- Use “drush csex live” to export your updated configuration only to your live split folder based on the live split settings.
- Check git if your changes have been added to the live sync folder
- Commit all your changes
- Use “drush cim” to import all the config again according to your currently active splits
Important: Make sure your drush version is higher than 8.1.10 or it won’t pickup the splits if you use drush cex or drush cim. Be aware that you still need to use csex and csim if you want to export or import from specific splits.
If you are just creating new functionality and some of the configuration should be ignored or split. Beware that on the first import you do on other environments the config that should have been ignored or split won’t be.
This is because the newly added config to the Config Ignore or Config split module has not been taken into account yet. Sometimes, this can be to your advantage - but more often, the contrary is true.
The way to get around this, is to manually add the “Config Ignore” or “Config Split” config to the environments where you want to deploy or take a two-step approach at deployment.
Avoid changing your default language
Changing your default language after you’ve already been exporting and importing your config can result in some very strange side effects with translations.
If you ever find yourself in the situation, a good fix is to manually change the langcode in the yml files in your sync folder to your default language again. Also make sure that the strings you’ve used are in the same language as defined by the langcode.
A good rule to bear in mind: Make sure all your config exports are done in the same language. This sometimes leads to errors, because it uses the language defined by the language negotiation plugins. If you only use Drush to import and export your config, this module can help enforcing a specific language. It will force all your Drush commands to be done in a language you define. The Dropsolid dev team be working together with Bart (Xano on Drupal.org) to see if we can help him get the module to a stable release.
Config translations can be tricky
You can easily translate your configuration using the Config Translation module from core. This sometimes can lead to unexpected side effects if you consider translations to be in the grey zone between config and content.
The issue here is that config translation and interface translation sometimes overlap - take for example the name of your content type. It is stored not only in config translation, but also in string translation.
When you do an import, it will by default overwrite the translation you’ve set in interface translation. This is because the locale module has a subscriber that imports those strings on the import event. (See this issue.)
Be aware that this can even happen to custom translated strings that you use in your own code. If there happens to be a same string that is used in config, it will get overridden. In this case you can always assign a context to your translated string so it doesn’t get overridden.
For those cases where you can’t set a context on the translated string, we’ve developed and contributed the Locale: Config import module. This module will let you change the behaviour of how the translated config gets imported.
The module shows the following options:
Agreeing on best practices for those grey areas for content
As a team of developers, you should agree in advance on a couple of best practices concerning content grey areas. Below I’ve listed a few rules that we’ve been playing with at Dropsolid:
- If you create a custom block plugin, use translatable markup with context for titles.
- Initially, treat Roles and permissions as config, until you go live. Next, configure the Config Ignore module to ignore them and update them through update hooks.
- Always treat webforms as if they are content. Deploy changes through update hooks
Working towards a better flow
I hope this three-part post has provided you with some valuable insight!
This article has been a true team effort, so thanks to everyone who contributed (most notably Brent, Marek, Laurens, Kevin, Thomas and Nick). Together, we can make configuration management a little bit clearer for everyone who uses it!
No doubt this article will be changing through the coming months as everyone - including the team here at Dropsolid - is still looking to find that perfect workflow.
In the first part of this three-piece blogpost, we explained the existing options for managing your configuration across environments. We also shed some light on grey areas between configuration and content. In this part, I’ll be showing you how to set it all up.
Setting up configuration management Configuring the splits
Start by installing the config split module, available here.
We like to keep our splits simple and clear. Currently, have four splits:
- Blacklist: A split that doesn’t have a folder configured, so it doesn’t end up in our Git repository. This split usually has the same configuration as the config ignore module. The reason why will be explained in the part about config ignore.
- Dev: A split that is used for our development environment-only configuration
- Staging: A split that is used for our staging environment-only configuration
- Live: A split that is used for our live environment only-configuration
Our blacklist configuration looks like this:
If you don’t fill in the folder name, the Config Split module will export the config to a table in the database. That way, it doesn’t pollute your Git commits. For our other splits we use a folder outside our docroot for security reasons - e.g. for a dev split: ../config/splits/dev
Another important value here is the weight of the split. This weight will be used when multiple splits are active. The weight defines the order in which conflicting settings from splits get resolved. I will explain this in the part about the settings files, a little further down this post.
For the active checkbox you can choose whatever you want, because we’ll overwrite it later using the settings.php file.
We’ve only been actively using the complete split configuration because it is pretty straightforward in how it handles your configuration. The additional configuration is handy because you can use wildcards. In the case of our blacklist, for example, we wanted to exclude everything from webform by using “webform.*”
We haven’t come across any use cases where we needed the conditional split, because we have a split active on every environment or the environment just needs the configuration from the sync folder.
If you were to use it, the following use case would be perfect for it. For instance, you have some configuration you need on all environments but you want it to be different on one environment. In our example we want a different email to be set in the reroute e-mail settings on the staging environment. You would change it in the interface and then do a “drush csex staging” to export it to the config split staging folder. This will allow the config file to be present in the sync folder and in the split folder.
First, install the config ignore module.
The important thing to know about this module is that it only ignores config on import. This is why we have currently set up a blacklist split. A new module called Config Export Ignore (available here) is also at your disposal, but we haven’t used it in our workflow because it doesn’t have a stable release yet. We will look into this in the future though, because the “blacklist” split feels like a hack in some way.
Our default config ignore settings look like this:
As you can see, you can also add some special rules to your ignore settings. The only downside is that config split does not support these special rules. You’ll have to tweak your blacklist split a little bit and make your peace with the added files in your repo, until we find or create a solution for this.
The settings files
To get this working across all environments, you need to have a settings file that is aware of its environment. This can be done using an environment variable that you check or use different files that get deployed based on the environment. There you set which config should be active on which environment. Sometimes it happens that you need multiple splits to be active on a single environment. You need to consider these splits as layers of config that you want to manage across environments.
Our settings.php file on our development environment is identical to our local environment. It contains the following lines:// Set your config directory outside of your docroot for security $config_directories[CONFIG_SYNC_DIRECTORY] = '../config/sync'; // Configure config split directory $config['config_split.config_split.blacklist']['status'] = TRUE; $config['config_split.config_split.dev']['status'] = TRUE; $config['config_split.config_split.staging']['status'] = TRUE; $config['config_split.config_split.live']['status'] = FALSE;
You might think that setting the staging split to true on the dev/local environment might be a mistake, but this is very intentional. As we are mostly using the complete split settings, this means that a config file can only be in one place. So we leverage the weight of the splits to also have certain staging config on our dev/local environment active.
For instance, if we only want the reroute e-mail module to be active on local/dev/staging environments, we would add it to the complete split settings of the staging split.
Our settings.php for our staging environment will look as follows:// Set your config directory outside of your docroot for security $config_directories[CONFIG_SYNC_DIRECTORY] = '../config/sync'; // Configure config split directory $config['config_split.config_split.blacklist']['status'] = TRUE; $config['config_split.config_split.dev']['status'] = FALSE; $config['config_split.config_split.staging']['status'] = TRUE; $config['config_split.config_split.live']['status'] = FALSE;
Consequently, the settings.php for our live environment looks like this:// Set your config directory outside of your docroot for security $config_directories[CONFIG_SYNC_DIRECTORY] = '../config/sync'; // Configure config split directory $config['config_split.config_split.blacklist']['status'] = TRUE; $config['config_split.config_split.dev']['status'] = FALSE; $config['config_split.config_split.staging']['status'] = FALSE; $config['config_split.config_split.live']['status'] = TRUE;
Our Rocketship install profile (blog post in Dutch) has all these things preconfigured, which enables us to create more value for our clients.
When you want to deploy changes to your environments, the only thing you need to do is make sure the config files that you’ve exported using ‘drush config-export’ are on the environment you want to deploy. Using a versioning system like Git can greatly help you manage those files across environments.
When you are ready to deploy your changes, just run the “drush config-import” command on that environment. Settings up drush aliases can save you a lot of time when you want to execute drush commands on remote environments. Read more about them here on this Drupal.org page.
Once you have this in place, you’ll be able to easily manage your configuration across environments. Go check out part 3 if you want to explore a couple of real world use cases and issues we’ve encountered.
This is the first of a series of three config management blog posts. In this series, we’ll help you set up a good starting point and provide you with a few solutions for everyday configuration issues. The first part of this multi-part blog post will provide you a bit of context. The second part goes into the nitty gritty of configuration management, and the third part demonstrates some concrete use cases, pitfalls and their solutions!
Features and configuration management
Drupal 8 has been around for a while now and at Dropsolid we have substantial experience with large projects that use both the contributed Features module and the core configuration management system.
Essentially, Features leverages the configuration management system to package configuration with your module and overwrites certain rules for importing config from a packaged module after first install.
Config split lets you set up rules for splitting your configuration per environment. Config ignore lets you ignore certain configuration to be imported.
The way you handle configuration fundamentally differs between both solutions. Features lets you whitelist the configuration you want to import. Configuration management from Drupal 8 core with addition of the mentioned contributed modules works more like blacklisting the configuration you don’t want to import. As a developer I have always found it easier to narrow down what I want to have control over, instead of what I don’t want to have control over.
We’ve come to the conclusion that the latter option actually works faster, which means more value for the client, but only if you have a good configuration to start from. As it turns out, configuration that you don’t want to control, is more often shared between different projects than config that you do want to control.
Content and config: blurred lines
One of the most wonderful things about Drupal 8 is config entities, a uniform way of creating and saving configuration throughout your site. It has been leveraged by many contributed modules to give end users a great experience in configuring their website.
The downside of these configuration entities is that they often cross the line between what is considered content and configuration. We consider content as everything a client needs to be able to change. A good example of this are webforms. Every webform you create is an instance of a configuration entity - whereas the submissions of the webform are instances of a content entity. If you want to know more about the difference between config and content entities, I advise you to read this article by Acquia.
We want clients to have full control over the kind of webforms they create, so they can use them effectively across their site to gather leads.
This brings us to the following issue. As a company we believe that a website is an ever-changing platform that grows over time. To have it grow at the speed that customers require, we need to work on multiple features with multiple teams at once. It needs to be stable and traceable.
Part of this stability and traceability is having what we developers define as structural configuration being versioned (git) and easily deployable, all without hindering the client to keep on working on their content.
Thanks to configuration management, config split and config ignore we’ve been able to achieve all this for Drupal 8!
Ready to set up your configuration? Read on in part two of the blog post series!
Yesterday, your CTO mandated that all new CMS builds would on Drupal 8 and that all existing CMS platforms would be consolidated to Drupal within the next three years. Great! Time to start prioritizing sites, hiring teams, and planning development and launch schedules.The old methods of release planning don’t work anymore
Most enterprise IT organizations are used to a “development” cycle followed by a “maintenance” cycle, at which point you start over again and rebuild with a new development cycle. This type of planning (which Dave Hansen-Lange called the “boom-bust cycle”) led to poor user experiences with Drupal 7 sites as they became stale with time and is impossible to use for a Drupal 8 site.
Drupal 8 has a different release cycle compared to previous Drupal releases. For example, Drupal 7 was released in January 2011, and ever since has only had bug fixes (with the occasional developer-only feature added). Drupal 5 became unsupported, and Drupal 6 entered it’s last phase of support (until Drupal 8 was released). Product owners of sites big and small found this release process stifling. The web is a very different platform today compared to January 2011—although Drupal 7 is pretty much the same. The slow release cycle also reduced willingness to contribute directly to Drupal after all, why spend time writing a new feature you can’t use until you migrate to Drupal 8?
Part of why Drupal 8’s development took the time it did was to allow for a faster release cycle for features. Now, new features are added in point release (while code compatibility with prior Drupal 8 releases is broadly maintained).
Furthermore, security updates are only reliable for the latest minor release. After a minor release, such as Drupal 8.4, security issues in the prior minor release (such as Drupal 8.3) will only be patched for a few weeks, if at all. In other words, to keep your sites secure, you have to be on the latest point release.
Upgrading your site every six months is a cost of using Drupal 8.
However, it’s not just Drupal that requires more frequent upgrades. Docker, NodeJS, and PHP itself all have more aggressive support schedules than similar software may have had in the past. Here lies the core of release planning: synchronizing all of these release schedules with your business.1. Build a schedule of key dates for your business
In the publishing industry, tentpole events such as tournaments, live events, or holiday specials drive production deadlines. In addition to tentpole events, identify conferences, retreats, and other dates where your team may not be available. If they overlap with an EOL of software in your stack, you can try to schedule an upgrade ahead of time.
There are two reasons to identify these early and socialize them with the rest of the business. First, these are times when you don’t want to schedule maintenance or deployments if you can help it. Second, these key dates are times to be prepared and aware of security release windows. For example, Drupal core security releases are usually on the third Wednesday of the month. If this overlaps with a high-traffic event, having a plan to deploy and test a security patch before the patch is issued will ensure your site is kept secure, and that technical teams aren’t stressed out during the process.2. Build a schedule of your stack and its support windows
Too often, we see organizations mandate a specific tool (like Drupal or Docker) without budgeting time and money for recurring, required upgrades. Maintenance often means “respond to bug reports from our team and handle outages,” instead of “incrementally upgrade software to keep it in supported releases.”
Before development begins, teams should gather a list of all key software used in their expected production stack. Then, go to each software release page, and find out the start and end dates of support for the current and next few releases. Use this to create a Gantt chart of support windows.
Here’s an example of one I created for a client that was deploying Drupal 8, PHP, Nginx, nodejs, Docker, and Ubuntu for their sites. In their case, they weren’t using Ubuntu packages for any of the other software, so they had to track each component directly.undefined
Having such a chart makes prevents surprises. For example, if a site is using nodejs 6.x, we can see that it’s going to EOL just after Drupal 8.5 is released. It would make sense for a developer to work on upgrading to nodejs 8.x over the December holiday break so that the team isn’t juggling upgrading two core components at the same time.
This type of chart also gives teams the power to know if a given technology stack is maintainable for their organization. If it’s a small team maintaining a large Drupal site, they may not have the bandwidth or expertise to keep up with updates elsewhere in the stack. That may mean they have to stick with LTS releases, or avoid software without an LTS available.
For Drupal 8, that may mean that it is not a fit for your organization. If your budget only allows an initial build and then very minimal maintenance, Drupal 7 or another CMS may be a better fit (at least until Drupal 8 has an LTS). Or, for event and marketing sites, consider using a static site generator like Jekyll, so that when development ends the site can be “serialized” into static HTML and served with a basic stack using LTS software only.3. Have a top-down process for handling security and feature updates
Many times we see software update requests coming from the development team, and then bubbling up to product owners and managers, meaning management will often prioritize new features with immediate business value before critical updates. Of course, this ignores the fact that a functioning and secure website is the foundation for addressing the needs of the business. And, it places developers in an awkward position where they are responsible for cleaning up any security breaches that occur.
Instead, software updates should be visible to and scheduled by the project managers, ensuring that time is available in the right sprint to test and deploy updates, preventing the development team from being overcommitted or opening your site up to a security breach. For example, let's say a team is using two-week sprints, with a sprint set to start on February 19, 2018. A quick look at the release cycle overview for Drupal 8 shows that 8.5.0-rc1 will be tagged on February 21st. Creating a ticket for that sprint ahead of time will ensure the upgrade won’t be forgotten.
It can be more difficult to handle software—like Drupal contributed modules or npm packages—that doesn't have a defined release schedule. In those cases, having a recurring “update everything” ticket can help. Assuming one team manages an entire deployment, a successful schedule might look like:
- Sprint 1: Update all Drupal contributed modules
- Sprint 2: Update all npm packages
- Sprint 3: Update all system-level packages
- Sprint 4: Update all Drupal contributed modules
- … etc.
Remember, just because you schedule software updates doesn’t mean that you have to deploy them to production if QA goes poorly. But, if you do find issues, at least you can try and address them before, and not during a security patch.4. Promote the new features you deploy to your colleagues and users
After doing all of this work, you should tell your end users and stakeholders about the gains you’ve made in the process. Show editorial users how Drupal 8.4’s Inline Form Errors gives them a better display of form errors on content they write. Tell your stakeholders how your API servers respond 15% faster to mobile clients. High-five your developers when they can remove a patch they’d been manually applying to the site.
For larger teams, newsletters and blogs are a great way to communicate these improvements. They are especially useful for core development teams, who write and maintain software shared throughout an enterprise.
With a solid grasp of how upstream release schedules affect your product, you will be able to reduce the need for unexpected delays and budget requests. If you’re interested in exploring this further with your team, we’d be glad to help.
This module allow administrators to configure a prioritised list of fallback languages per language. The fallback languages are used for entity view / entity upcast.REQUIREMENTS
- Drupal 8.3 or later.
- Language module.
Install as you would normally install a contributed drupal module. See: https://www.drupal.org/documentation/install/modules-themes/modules-8 for further information.
Nothing fancy today, just a list of dungeon descriptors, helpfully listed in d100 format. Oftentimes I find myself wanting to make a new dungeon or area and am short on ideas. This list is useful for inspiration, kickstarting design with an idea or two about which ideas can be formed. Alternately, you can pick one or two as overarching themes and then flavor smaller areas with another selection. Of course you may need to get creative if you end up with conflicting descriptors that make no sense together, but if it’s too bizarre you can always ignore the one you like least and/or roll again.
Here’s an example: We’ll go with an area with two random descriptors and three sub areas each with an additional descriptor of it’s own. Our rolls* are 9, 53 , 51, 14, 90. That gives us main traits of Icy and Rectangular rooms. So we have a start of an idea. Rectangular rooms is pretty standard dungeon stuff. Icy implies cold or ice creatures and a certain environment. Maybe this is high in the mountains, deep underground, a magical cold, or far to the north/south. We’ll decide later. Our three sub zones are Large scale, Geothermal, and Non-euclidean. Giant is easy. So we have a giants’ castle in the high mountains covered in frost and ice. Under the castle we’ve got a series of geothermically active caverns. We could go fire elemental here, but I like making the geothermal energy a power source for the giant’s castle better. So the castle has steam driven gates and other cool steam type devices, as well as few “ice giant engineers”, although no steam heat. In the caverns themselves, there are a few ice giant taskmasters (nearly naked because of the heat) and a bunch of slaves that maintain the steam pipes. Beyond the castle, carved into the mountain is a series of rooms with odd magical geometry. Let’s combine that with the ice to have sliding traps and block puzzles that rely on the non euclidean nature of the space, placed to protect some appropriate artifact. On advice of my test audience, we’ll also add some man sized blind penguins and ice-template gibbering mouthers to this area. That even gives us three adventure hooks: against the giants, free the slaves, capture the relic.
- Wet: Moldy – damp, and mold grows everywhere
- Wet: Flooded – ankle to waist deep water everywhere
- Wet: Underwater – entire place is underwater
- Wet: Rotten – sodden, and everything is ruined, turning into mush
- Dry: Crumbling – dry rot, crumbling stone
- Dry: Dusty – a layer of dust and grit cover everything
- Dry: Parched – dry air that makes you thirsty and uncomfortable
- Dry: Dehydrating – moving air the pulls moisture away, full of mummified husks of small creatures, etc…
- Cold: Icy – covered with a layer of ice, formations on walls and ceiling
- Cold: Clammy – cold and damp air, works through your clothes
- Cold: Glacial – biting cold, walls of ice
- Cold: Crisp – cool but invigorating
- Hot: Smoldering – piles of still warm ash, may have low oxygen levels
- Hot: Steamy – geothermal vents, geysers, etc…
- Hot: Magma – flows of magma (1500k about 3 times as hot as a campfire, 500k) in large rooms, heat may dissipate enough to approach, in small rooms maybe not
- Hot: Warm – general warmer temperature
- Live: Positive aura – depending on the strength, area may be covered in growth or items may animate or burst into frantic activity
- Live: Swarming – filled with large swarms of vermin
- Live: Live rock – dripping mineral water creates slow growing formations
- Live: Genius loci – a spirit caretaker oversees the area
- Dead: Bodies – corpses litter the area
- Dead: Negative aura – may cause a feeling of illness or unease, bolster undead or even damage the living
- Dead: Ruined – once worked the area is falling apart
- Dead: Eerie – feelings of being watched, prickling of the skin, etc…
- Vegetation: Overgrown/roots – plant growth and hanging roots block passages and cluster about the ground
- Vegetation: Flowering – strange cave flowers grow or sprout from bushes or vines
- Vegetation: Fungus/mold – large fungi or molds grow throughout the area
- Vegetation: Gardens – carefully tended (once?) gardens dot the area
- Natural: Solution caves – caves formed by minerals dissolving, often wet
- Natural: Lava tubes – formed by magma flowing out of a space, stone is hard, rooms are tunnel like
- Natural: Fracture caves – full of debris, layers of rock collapse to form caves
- Natural: Erosion caves – made by action of wind or water wearing down rock, may have strong winds or high tide
- Manufactured: Hewn – crudely carved out of rock, surface still shows tool marks
- Manufactured: Supported – soft stone supported by columns or beams
- Manufactured: Rough Brick – simple stone bricks carved from rock shore up and finish walls
- Manufactured: Advanced Brick – smaller, fancier, or simply better made stone bricks
- Sounds: Whistling – sound of wind forced through tight passages or over odd formations
- Sounds: Rumbling – perhaps an indication this area is unstable or of seismic activity
- Sounds: Battle noises – inhabitants often get in noisy conflict
- Sounds: Moaning – the wind? or something more sinister?
- Smells: Decay – death, decomposition, mold
- Smells: Dirt – the smell of earth and dirt
- Smells: Chemicals – strange acrid brews, sickly sweet tangs, some kind of strange chemicals are on the air
- Smells: Metal – the distinct smell and taste of metal, is this a metallurgists, a mine, or just an ore rich area?
- Denizens: Beast – area is populated with animals, predators, scavengers etc…
- Denizens: Lowlives – slimes, fungus monsters and insects
- Denizens: Magical – elementals, undead, constructs and other unnatural things
- Denizens: Humanoids – primitive or advanced humanoid tool users
- Scale: Tight – small rooms, tight passages, crawling and squeezing through tunnels
- Scale: Standard – normal room and passage scale
- Scale: Large – larger passways, huge rooms, perhaps natural or built by giants
- Scale: Mixed – a mix of scales, often natural but also a characteristic of an area inhabited by different sizes of creature
- Shapes: Rectangles – standard square and rectangular rooms
- Shapes: Ellipse – circles and ellipses
- Shapes: Angled – angled rooms other than squares and rectangles, triangles, hexagons, unusual shapes…
- Shapes: Natural – caves and natural passages
- Maintenance: Maintained – the area is being maintained, passably clean and repairs are made
- Maintenance: Expanding – the area is maintained and new areas are being built on the edges
- Maintenance: Abandoned – no one is doing maintenance, most things still work but some don’t and wear is obvious
- Maintenance: Collapsing – no one has done maintenance for a long time, few things work, most are broken, missing, or destroyed
- Airy: Strong winds – winds howl through the rooms and halls, light items are blown away, doors may be flung open or characters pushed down
- Airy: Cavernous – huge open caverns with vaulted ceilings
- Airy: Chasms – deep chasms voids and pits
- Airy: Open – one monstrous cavern with discrete areas within, sneak a little overland into your dungeon
- Architecture: Monolithic – huge construction from large slabs of rock
- Architecture: Sparse – clean unadorned construction
- Architecture: Embellished – covered with engravings, runes, patterns, etc…
- Architecture: Stylistic – an unusual or alien style
- Obscured: Foggy – mists, steam or fog blanket the area
- Obscured: Screened – webs, vines or other obstructions shroud the area
- Obscured: Magic darkness – rooms or the entire area is covered in magical darkness
- Obscured: Twisty – no special obstruction, just very few straight passages so vision only extends to the next bend
- Size: Small – your classic 5 room dungeon
- Size: Medium – larger complex, 5-15 rooms
- Size: Large – larger yet, 20-50 rooms
- Size: Extra large – sprawling multi-“zone” area
- Unique: Architecture – contains a unique piece of architecture, statuary, or other landmark
- Unique: Foe – contains a unique monster, NPC or the like
- Unique: Magic effect – contains a special magic effect, either an aura over the whole area or a specific feature like a magical portal or pool
- Unique: Treasure – has a special one of a kind treasure that may have its own backstory or associated quest
- Danger: Hazards – venomous critters, naturally occurring rockfalls, pits or fire gouts
- Danger: Traps – area is/was home to a trap builders and has many traps
- Danger: Monsters – area full of deadly monsters
- Danger: Curses – area holds curses or other magical dangers
- Treasure: Coin and items – standard treasures
- Treasure: Raw ore/gems – area has been or can be mined for raw ore and gems
- Treasure: Art – area has art objects that can be looted as treasure
- Treasure: Goods – not much in the way of treasure, but area has trade good that can be sold
- Magic: Changing – shifting walls, moving rooms and other tricks
- Magic: Non-euclidean – the area has a definite arrangement but its full of portals, bends in reality or other weirdness that make it difficult to map
- Magic: Wild – magic in this area acts unpredictable
- Magic: Null – magic in this area is suppressed or nullified
- Crystal: Studded – walls are studded with raw crystal
- Crystal: Monsters – monsters in this area are weird crystal versions or crystal themed monsters
- Crystal: Walls – this area is carved from a massive crystal deposit, glass or obsidian
- Crystal: Items – furniture, decorative items, tools, and weapons in this area are all made of crystals
- Technology: Stone – denizens of this area use stone age technology
- Technology: Bronze – foes in this area use bronze or another soft metal
- Technology: Steel – this area has steel or another hard metal technology
- Technology: Steam – this area features early steam tech
*Using my Polyhero Wizard dice, because they’re what I have on hand. Now I can use the old “mad wizard” excuse when players look at me funny.
Delete entity (node) revisions, but keep "important" ones.
In heavy editorial environments, revision enabled entities may end up having many very similar revisions. Over time, as the database grows, the value of these revisions diminish. This module will delete these 'lesser valued' revisions by comparing revisions from a set of parameters: