Online gaming makes it easier than ever to join a game. However, real life still gets in the way. Overtime, school assignments, sickness, and family responsibilities all conspire against us sometimes. Maintaining an ongoing, epic campaign can be a quite a challenge. Now, it is a rewarding challenge, and one I would never disparage. But it is a challenge.
This article will discuss an alternative format: ensemble play. It’s certainly not the only alternative, but it may be something to consider if you are having trouble getting enough players for a traditional campaign. We’ll look at the advantages and concerns involved. First, let’s define our terms.
WHAT IS ENSEMBLE PLAY?
In ensemble play, there is no set group of players. Players participate when they can, and your player database will be larger than the actual number of people who come to a session. Sites such as Meetup, Facebook, geek boards, and even your virtual tabletop (VTT) can help you find players and help them sign up for your sessions. Ensemble play does NOT mean that you can’t have some regular players with recurring characters. I love my players and would never give my regulars the boot. Ensemble play merely means that you are flexible in allowing others to sit in to have a full session. Pregenerated characters will help those folks who are sitting in get into play much more quickly.
In ensemble play, most adventures can be completed within a single session. Like old school TV shows, each story is self-contained. Every session should end with the characters accomplishing something, meeting some small goal. This makes it much easier for new players to sit in on a session without having to assimilate into a complicated campaign.
Some formats are well suited for ensemble play. Star Trek is the perfect example. While you may have regular crewpeople (your “every weekers”), you can easily round out the landing party with the guest specialists. Visit a new planet with a new problem each session and you’re set. Star Wars would work as well. Simply station the players aboard a large Rebel ship, and send them out on short missions every session. In a fantasy format, you could situate them aboard a sailing ship to visit a new port or island every session. Matt Neagley has a great article discussing this here. In a horror or modern genre, simply start the team at the site of their investigation. The X-Files is a good example of this, as is, well, Scooby Doo. No one cared where the Mystery Machine went between cartoons.
Ensemble play helps assure that you will have a full table (real or virtual) most sessions. With a large player base, you are not as limited by everyone’s schedules. It gives you the opportunity to play with a wide variety of people, and is a good way to help grow the hobby. You can easily try different genres and games if you like. No need to wait until the next convention to try that idea that is driving you crazy.
It may also be easier for session planning. You don’t need a long story arc or a detailed world. You just need a series of “singleton” adventures, and any travel is assumed to occur between sessions. You can even reuse some of your adventures with different groups of players if needed or if you’d like to fine-tune an adventure. A simpler system may work best for ensemble play. That way you don’t have to worry too much about the rules system or helping players understand them. Simpler systems are also much easier to prep.
For online games, the ensemble format will require a bit more pregame work from the GM. You’ll have to manage how people sign up for your game. Also, you’ll need to spend a little more time making sure they can find your VTT and audio service. At the beginning of the session, you’ll also have to spend some time making sure they know how to use the VTT and deal with any technical issues. You may also wish to discuss any “table rules” at the beginning of sessions as well.
On a social level, you’ll never know how new players will work. It’s a little like a blind date, and that can be fine or go horribly wrong. Also, it may be difficult to build up group comradrie. To prevent some of these issues, you should be very upfront when recruiting players. I make a point of stressing that we run a cooperative game, and that it is mostly rated “PG.” You can do whatever you like in your games, but do yourself and potential players a favor and let them know beforehand.
Another concern is that it can be tough to write single session stories. You’ll need to have some kind of conclusion, even if it means skipping some intermediate scenes. (You can always recycle them for next time). You won’t be able to build a big epic storyline as easily or perhaps at all. This may make some players less invested in the game, and won’t be to everyone’s taste. Also, you can have characters level up, but you’ll need to do more bookkeeping. You may want to have players keep track of how many sessions they have attended or how many experience points they have acrued on their own.
Ensemble play may be an option if you are having trouble getting a consistent group. You might also run some ensemble sessions as a way to “audition” players for a more regular campaign. Given busy adult schedules, it is an option worth considering. Who knows, your ensemble game may morph into something more regular when players keep wanting to come back session after session.
What advantages or disadvantages did I miss? Have you had any experiences (good, bad, or ugly) with ensemble play that you’d like share? Let us know below.
Final Fantasy X-2&#8242;s Brilliant Job System (and a problem I have with it) - by Christopher Gile
Spelling sugestions are displayed in a block.
Have you ever try to get data from your libraries and/or breakpoints in Drupal 8 ? Drupal 8 core does not provide a UI for this information. Â And sometimes is nice to have the ability to know your data from the UI. Instead of trying to hunt down all that information by searching many files. For this reason, I decide to write few modules that will allow you to get some of the libraries and breakpoint information from the UI.Â
- Project Page: https://www.drupal.org/project/libraries_ui
- Module Description: This module will provide a UI to display all libraries provide by modules and themes. Once libraries_ui is been installed visit /admin/config/media/libraries_ui to get all breakpoints information.
- Project Page: https://www.drupal.org/project/breakpoints_ui
- Module Description: This module will provide a UI to display all breakpoints provide by modules and themes. Once breakpoints_ui is been installed visit /admin/config/media/breakpoints_ui to get all
I went to Drupalcon NOLA and was looking for a new way to contribute, since there've been a lot of discussion about the front-end part, and after reading @dries blog post Turning Drupal outside-in I started looking at the field UI. I stumbled upon the core issue titled The options under the Add field drop-down describe the data you want to store, but the user was imagining the widget it would produce and decided that the outside-in approach might be a good approach.
Drupal Code Builder library is the new library which powers Module Builder. I recently split Module Builder up, so Drupal Code Builder (DCB) is the engine for generating Drupal code, while what remains in the Module Builder module is just the UI.
DCB is an extensible framework, so if you wanted to have DCB create scaffold code for a particular Drupal component or system, you can.
DCB's API is documented in the README. It's based on the idea of tasks: for example, list the hooks and plugin types that DCB has parsed from the site code, analyze the site code to update that list, or generate code for a module. There are Task classes, and you call public methods on these to do something.The generators
Broadly, there are three things you want to do with DCB: collect and analyze data about a Drupal codebase to learn about hooks and plugin types, report on that data, and actually generate some code.
The Generate task class is where the work of creating code begins. The other task classes are all pretty simple, or at least self-contained, but the Generate task is accompanied by a large number of classes in the DrupalCodeBuilder\Generate namespace. You can see from the file names that these represent all the different components that make up generated code.
Furthermore, as well as all inheriting from BaseGenerator, there are hierarchies which can probably be deduced from the names alone, where more specialized generators inherit from generic ones. For example, we have:
- API (this one's for your mymodule.api.php file)
However, these hierarchies are only about code re-use. In terms of PHP code, HookImplementation is only related to ModuleCodeFile by the common BaseGenerator base class. As the process of code generation takes place, there will be a tree of components that represents components containing each other, but it's important to remember that class inheritance doesn't come into it.
Also, while the generators in the hierarchies above clearly represent some tangible part of the code we're going to generate, some are more abstract, such as Module and Hooks. These aren't abstract in the OO sense, as they will get instantiated, but I think of them as abstract in the sense that they're not concrete and are responsible for code across different files. (Suggestions for a better word to describe them please!)
The process of generating code starts with a call to the Generate task's generateComponent() method. The host UI application (such as Module Builder module, or the Drush command) passes it an array of data that looks something like this:
[ 'base' => 'module', 'root_name' => 'mymodule, 'readable_name' => 'My module', 'hooks' => [ 'form_alter' => TRUE, 'install' => TRUE, ], 'plugins => [ 0 => [ 'plugin_type' => 'block', 'plugin_name' => 'my_plugin', 'injected_services' => [ 'current_user', ], ], ], 'settings_form' => TRUE, 'readme' => TRUE, ]
(How you get the specification for this array as a list of properties and their expected format is a detailed topic of its own, which will be covered later. For now, we're jumping in at the point where code is generated.)Assembling components
The first job for the Generate task class is to turn this array of data into a list of generator classes for the necessary components.
This list is built up in a cascade, where each component gets to request further components, and those get to request components too, and so on, until we reach components that don't request anything. We start with the root component that was initially requested, Module, let that request components, and then repeat the process.
This is best illustrated with the AdminSettingsForm generator. This implements the requiredComponents() method to request:
- a permission
- a router item (on Drupal 7 that's a menu item, but in DCB we refer to these a router item whatever the core Drupal version)
- a form
In turn, the Permission generator requests a permissions YAML file. You'll see that there are two Permission generators, each with a version suffix. The Permission7 generator requests a hook_permission() hook, which in turn requests a .module file. The Permission8 generator is somewhat simpler, and just requests a YMLFile component.
Meanwhile, the router item requests a routing.yml file on D8, and a hook_menu() on D7.
These two parts of the cascade end when we reach the various file generators: ModuleCodeFile and YMLFile don't request anything. The process that gathers all these generators works iteratively: every iteration it calls requiredComponents() on all the components the previous iteration gave it, and it only stops once an iteration produces no new components. It's safe to request the same component multiple times; in the D7 version of our example, both our hook_menu() and hook_permission() will request a ModuleCodeFile component that represents the .module file. The cascade system knows to either combine these two requests into one component, or ignore the second if it's identical to what's already been requested.
We now have a list of about a dozen or so components, each of which is an instantiated Generator object. Some represent files, some represent functions, and some like Hooks represent a more vague concept of the module 'having some hooks'. There's also the Module generator which started the whole process, whose requiredComponents() did most of the work of interpreting the given array of data.Assembling a tree of components
The second part of the process is to assemble this flat list of components into a tree. This is where the notion of which component contains others does come into play. This is a different concept from requested components: a component can request something that it won't end up containing, as we saw with the AdminSettingsForm, which requests a permission.
The Generate task calls the containingComponent() method on each component, and this is used to assemble an array of parentage data. There's nothing fancy or recursive going on here; the tree is just an array whose keys are the identifiers of components, and whose values are arrays of the child component identifiers.
This tree now represents a structure of components where child items will produce code to be included in their parents. One part of this structure could be represented like this:
- router item
Some components, such as the Hooks component, are no longer around now: their job was to be a sort of broker for other components in the requesting phase, and they're no longer involved. The root component, Module, is the root of the tree. All the files we'll be outputting are its immediate children. (This is not a file hierarchy, folders are not represented here.)Assembling file contents
We now have everything we need to start actually generating some code. This is done in a way that's very similar to Drupal's Render API: we recurse into the tree, asking each component to return some content both from itself and its children.
So for example, the router items contribute some lines to the routing.yml file, which then turns them into YAML. The .install component, which is an instance of ModuleCodeFile, produces a @file docblock, and then gets the docblock, function declaration, and function body from the hook_install component, and glues them all together.
Finally, each file component (the immediate children of the module component in the tree) gets to say what its file name and path should be.
So the Generate task has an array of data about files, where each item has a file name, file path, and file contents. This is returned to the caller to be output to the user, or written to the filesystem. Module Builder presents the files in a form, and allows the files to be written. The Drush command outputs them to terminal and optionally writes them too.Extending it with new components
The best way to add new things for DCB to generate is to inherit from existing basic classes. If these don’t provide the flexibility, there’s always a case to be made to give them more configurable options: for example, the AdminSettingsForm class inherits from Form, but neither of those do very little for the actual generated form class, as the work for that is mostly done by the PHPClass class.
The roadmap for DCB at the moment consists of the following:
- Generalize the injected services functionality that’s already in Plugins, so generated Form classes and Services can have them too.
- Add Forms as a basic component that you can request to generate. (It’s currently there only as a base for the AdminSettingsForm generator.)
And as ever, keep adding tests, keep refactoring and improving the code. But I'm always interested in hearing new ideas (or you know, better yet, patches) in the issue queue.
This module provides an API to interact with the Mandrill Inbound Email
Processing system. Modules are then able to use this API to setup email
patterns to receive emails and callbacks to process them.