Category Archives: Games

What is D&D (Dungeons and Dragons)

D&D resembles the imaginative pretend play we did as children: Cowboys & Indians, Cops & Robbers, etc. Yet while that kind of play often became undirected and arbitrary, the D&D rules provide consistency that centers the play within a semi-realistic fantasy world. The rules are not guardrails that keep you on a road that directs your travel. The D&D rules don’t direct play, but merely define a consistent world, within which is a wide range of imagination and adventure.

D&D play consists of campaigns. A campaign is a series of adventures that unfolds as the game is played. Yet adventures where? About what? Key to the game is a participant called the Dungeon Master (DM for short) who prepares the campaign, the world in which it happens, and brings to life the characters in that world.

The interactive story is the heart of the game. A D&D module is a chapter in the campaign, the outline of a open-ended story that could unfold in many different ways, depending on what the players do. Each module is prepared by the DM in advance, including locations, plots, characters, monsters, magic, treasure, etc. The DM has a good idea of all the various things that could happen and how it might end, yet the players determine this through their actions.

D&D does have complex rules, including several books and a variety of dice. Each player’s character may have pages of detailed information. Many things that happen are determined by dice rolls in cross-referenced lookup tables. How does all this not suffocate imagination, adventure and fun? The game avoids that by placing this burden almost entirely on the DM. The players take on the persona of their characters and role play according to their imagination and common sense. Dice rolls are based on probabilities that are not completely random, but reflect the characters and situations in the game. The DM applies the rules to translate player actions into the game and determine the effects.

In explaining what D&D is, it’s also useful to describe what it’s not. D&D is not a reality or combat simulation. Given its topic of magical fantasy adventure, a realistic simulation would be absurd. D&D is a game to stretch the imagination while creating an interactive story of adventure. The DM’s role is to incorporate a degree of realism, just sufficient to ground the game with enough plausibility to allow the suspension of disbelief.

D&D Character App

Introduction

Like many nerds my age, I played D&D back in the early 80s. I started with the Basic and Expert rules, playing with my brother and sister. Somebody had to be the Dungeon Master (DM) and that ended up being me because I liked systems of logical rules, enjoyed imaginative thinking, and was fascinated by this unusual game.

A year or two later we were still playing. I had gotten more into the game which meant moving up to the “Advanced” rules called AD&D, which became the original canon as the popularity of other rules faded away. I saved up my allowance and bought the “holy trinity” of rulebooks: the Players Handbook, Dungeon Masters Guide, and Monster Manual, which were published in the late 1970s. And I invited some friends to play. In 7th through 9th grade the school librarian let us use the private conference room during lunch, which we did at least a couple times per week.

This was before computers were in common use. My family had a TRS-80 which I used and learned to program, but most families did not have a computer and kids still wrote homework and essays by hand. We played D&D old-school with paper and pencil. One of the challenges was keeping track of characters with all their attributes, equipment, etc. which was constantly changing as they adventured. I always wanted to write software to track characters, but the complexity of the data and relationships made this difficult. Rainbow magazine published a variety of programs every month (given as code listings to be typed in!), which once included a D&D character app, but it was over-simplified and unable to handle all the aspects of a character.

Later when I learned relational databases I thought they would be ideal for storing D&D characters. Yet even then, the relationships would be difficult to model. It’s not only 1:M and M:M, but also hierarchical, and relationships that are conditional based on several other attributes, with plenty of exceptions.

In the 1990s I wrote an app in C++ that ran in OS/2 using Borland OWL. It was an exercise in learning OO programming and using several Design Patterns. But I only got this app about 90% complete, since my D&D gaming was already tapering off.

Fast forward a couple of decades to late 2008 and D&D play had faded from my life. It is time consuming (especially for DMs, which was always my role) and after college it got replaced by so many other things that were happening in life, and also with my friends – jobs, marriages, kids, travel, etc. Meanwhile, Java 1.5 had been released which included Generics, a major improvement to its data modeling, followed by 1.6 which had major performance improvements. In order to bone up on this new tech, I decided to finally write the D&D character app that I always wanted. And to use these capabilities to make it fully capture all aspects. I still had over 100 characters (as paper character sheets) from old campaigns and the test would be whether I could fully store them in the app, with all their details and quirks.

Precis: the App

The app is in my public GitHub, open source under the very permissive MIT license. Anyone can download, build and run it using any version of Java 1.6 or later, on any computer (Linux, Mac or Windows). The app GUI is Java Swing. This gives it a vintage 1990s look but makes it functional and easy to program. I found Swing to be well designed and better than other GUI systems I learned in the past, including Microsoft Windows programming (with all those WM_ messages), MFC and Borland OWL.

The app not only stores characters that you create, but also generates characters. Auto-generation creates the character essentials and leaves it to you to fill in details. These essentials are a moving target as I occasionally enhance the program, but include:

  • Ability scores (generated by rolling 4d6 for each and taking the 3 highest)
  • Auto-generating all ability score adjustments.
  • Choosing the best class based on ability scores.
  • Choosing race consistent with class.
  • Choosing alignment consistent with class.
  • Auto-generating all class & race abilities & languages.
  • Randomly assigning gender, name, height, weight, etc.
  • Auto-generating starting wealth based on class.
  • Equipping the character randomly yet based on class, including armor & weapons.

The app also prints characters using a simple 2-column format. It uses the Java print service which abstracts the printer and works on any printer, on any operating system.

Much of what the app does is based on data config text files. This includes ability score adjustments, saving throws by class and level, default equipment lists (for auto-generated characters), and spell usage by class and level. Thus, some of the app behavior can be changed simply by editing these text files.

App Usage Details

The app is self-explanatory, a simple UI of tabbed panels. Yet it has some capabilities that require explanation.

The GUI layout is dynamic. As you resize the app, GUI elements may shrink, grow or move. If you find layout errors (such as text fields that are truncated), this is usually a limitation of Java Swing dynamic layout and resizing the app fixes them (grab a window corner and drag it).

All entry fields accept strings. While any text is accepted, some fields (such as ability scores and hit points) expect integers. If they are not integers, the app will still function but it won’t be able to automatically set adjustments.

Command Line Parameters

A typical app invocation looks like this:

java -jar DnD.jar

This assumes that an appropriate version of Java is in the path and you are in the app’s bin directory which contains its config files.

All of the parameters below can be combined.

Font Size

Java Swing was originally designed 20 years ago when a 1600×1200 monitor was considered high resolution. Consequently, the font size and overall GUI may be too small for modern monitors. To accommodate this, the app has a command-line parameter to adjust the font size, which also adjusts the rest of the GUI.

For example, to adjust the font 2 points larger than normal:

java -jar DnD.jar -font +2
File to Open

If you want the app to open a character file when it starts, use the -file parameter:

java -jar DnD.jar -file CHARACTERFILE

Disk Format

The app stores characters on disk using a compact binary format. A typical 1-5 level character takes about 2 kB of storage – more for higher level and multi-classed characters, but there is no arbitrary limit to the size. The first data it writes is a storage version number, for future compatibility. If I ever change the data format, this will enable future versions of the app to recognize and load characters stored in older formats.

The app remembers the last directory used to save or load a character. This is convenient, since when loading a file you only have to navigate through directories once. This also applies when you load a character on app startup.

Apply / Revert

The app uses a Model-View design. The Apply and Revert buttons transfer data between the model and view. For example, if you change the character’s name, it doesn’t apply until you click the Apply button. If you click the Revert button, it restores the UI to the state of the model, which reverses all changes you made since you last clicked Apply.

Apply and Revert buttons have different scopes. On each panel they pertain only to that panel. To do this globally, use the app menu: Edit|Apply All, Edit|Revert All.

Lists are an exception to this behavior. Changes made to lists take effect immediately.

Red Buttons

Red buttons indicate actions that might change or override user-entered data. They are used to automatically set adjustments for ability scores and classes.

For example, suppose a character earns 750 XP on a campaign. Enter 750 into the XPoints field and click the red Add XP Points button. The app will add any XP bonuses (for example, 10% bonus makes it 825), add the XP to the character’s total, and if it bumps him up a level, the app will change the level and apply relevant adjustments (new hit points, saving throws, spells, powers, etc.).

Equipment

Character equipment is modeled using a Composite design pattern. It is a tree that can be nested to any depth, indicating which items are contained within other items. Moving, copying or deleting any item affects all other items it contains.

The GUI is a drag and drop panel. Any item can be dragged and dropped anywhere else. This can also be used to reorder items at any level. The item and everything it contains comes with it. If you hold down the CTRL key while dragging, it makes a copy instead of moving it.

Class Info

The app has a panel for each of the 5 basic classes: Fighter, Cleric, Magic User, Thief, Monk. Each panel has a checkbox indicating whether it applies to the character. If it is not checked, the tab for the panel is greyed out (yet not disabled, so you can still click it). If a character already has a certain class, toggling the checkbox to disable does not delete it, but only flags it. If you disable it by mistake, simply check it again to enable it and no data will be lost – so long as you didn’t save the character or make other changes while it was disabled.

Class data starts as a zero-level placeholder. It does not become real until you set the level to some value 1 or more. Data for placeholder classes is not saved or printed, so if you enable a class for a character but you don’t set the level, that class data will not be saved or printed.

Each class has a name, which by default is the name of the Java class used to model it. You can (optionally) set this name to anything you want. If the name you use happens to be a subclass of that class, this subclass will be used in the data model. Subclass names include:

  • Ranger (subclass of Fighter)
  • Paladin (subclass of Fighter)
  • Druid (subclass of Cleric)
  • Illusionist (and MagicUser are both subclasses of MUBase)
  • Assassin (not yet implemented)

With these subclasses, the model handles a total of 9 character classes – and various combinations. Multiple class tabs can be enabled and each operates independently. For example, Fighter-MagicUser or Thief-Illusionist. However, each character can have only one of each base class, so Fighter-Ranger or Cleric-Druid is not possible (nor would it make sense).

When you give your own user-defined name for a class, your name does not have to match any of these. In this case the base class is used. For example, you could name a Cleric as “Shaman” and it would be modeled as a Cleric.

When first adding a class to a character:

  • Click on the class tab
  • Click the Enabled checkbox
  • Enter a name (optional – if you want a subclass or custom name)
  • Click the Reset/Init button (needed only if you are using a custom name)
  • Enter a level of 1 or more
    • Unless you are creating a multi-class character, in which case see below
  • Click the Level button

When you take that last step, if the level you entered is different from what was there before, it will change data on this tab, as well as on other tabs. For example, it will assign hit points and saving throws which you will see on the Combat tab. These changes apply directly to the model and cannot be reverted (which is why the buttons labels are red).

Multi-Class Characters

Multi-class characters are supported, including auto-generation of hit points and save throws. To create a multi-class character:

  • For each class tab:
    • Click on the tab
    • Click the Enabled checkbox
    • Optional: enter a custom name and click the Reset/Init button
  • After all classes have been enabled, apply all (menu Edit|Apply All)
  • Visit each class tab
    • Enter a level of 1 or more
    • Click the Level button

Hit points for multi-class characters are computed as follows: for each class, for each level, determine the hit points, add any constitution bonuses, then divide by the total number of classes. Round this number to the nearest integer (it may go up or down, depending on the fraction).

Each save throw for a multi-class character is the best (lowest) across all classes (per level of each individual class) for that category.

Class Abilities

Every class has certain abilities, which are stored in this list in the upper left of the panel. Some may be auto-generated by the app, others may be user-defined. The prefix “AG: ” (for auto-generated) is used to differentiate them. Any item that has this prefix is auto-generated. The app may remove or change it. Yet when the app manipulates this list, it ignores all items not having this prefix. This way, the app preserves any user-defined items in the list.

Spell Use

The app tracks how many spells can be cast daily by class and level. For Clerics and Druids, it also applies Wisdom bonuses. The casting of spells is different from the availability of spells. Clerics may pray or meditate for more spells than they can cast each day. Magic Users and Illusionists may know spells that aren’t in their spellbook, and memorize each day more spells than they can cast.

The casting of spells is stored in the upper Class Abilities list and the app automatically sets it.

The availability of spells is stored in the lower Spells list left for users to define.

The app configures spell use based on the class name and reverts to the default. For example, suppose the character has Cleric enabled yet named “Shaman”. The app doesn’t have a spell use config for that name, but the class is of type Cleric, so it will default to Cleric spell usage. The user can override default spell usage in the app (don’t use the AG: prefix), or he can create a data file called spells.Shaman.dat to define how he wants Shaman spells to be allocated by level. If this file exists, the app will use it to allocate spell usage for Shamans.

Paladins and Rangers gain spells only at higher levels (8th and above). Because Rangers gain two kinds of spells, Druid and MagicUser, they have 2 config files: spells.Ranger.Druid.dat and spells.Ranger.MagicUser.dat.

Printing

To print a character, use File|Print from the menu. A print dialog will appear, showing all available printers (both local and network). The printed character sheet is organized into sections and uses 2 columns. It defaults to 8.5″ x 11″ paper with 0.25″ margins, though users can change this in the print dialog.

Notes and Limitations

Assassins are not handled. They have been rare in my games (at least as player characters) so I deferred them to last and haven’t gotten around to it.

Paladins can turn the undead upon reaching 3rd level, and cast Cleric spells at 9th level. The app will show these GUI elements for characters of the appropriate level.

Rangers gain both Cleric and Magic User spells at 8th and 9th level respectively. Their spell usage will appear automatically under Ranger special abilities. When this happens, the corresponding spell lists will also appear in the GUI.

Druids cannot turn the undead, but have abilities that are otherwise the same as clerics. When the class Druid is used, the app will remove the portion of the GUI that shows turning undead.

The app GUI is dynamic, adding or removing elements as needed for the given character. This relies on Java Swing’s built-in dynamic layout. If the GUI elements don’t look right – such as squished text entry boxes – resizing the app window triggers the dynamic layout and usually fixes the problem.

Bluetooth in a Windows 10 VirtualBox VM

Introduction

While all of my computers run Linux, sometimes it’s useful to have Windows – fortunately, not often. Due to the long wet grey dreary winters here in the WA state Puget Sound area, I recently got an indoor cycling trainer. You can use lots of different software with these. The software emulates rides in either the real world (based on video & GPS tracks) or the virtual world (like a video game). It connects to the trainer using Bluetooth or ANT+ to dynamically control the resistance (simulating hills) and measure the rider’s power output.

The only software I could find that runs natively on Linux is very basic and not well supported. These include Auuki and Golden Cheetah. I wanted something more full featured. The next best thing would be Android.

Android?

Most of the popular apps (Zwift, MyWhoosh, Rouvy, Kinomap, icTrainer, etc.) support Android. MyWhoosh was out of the question because it consumed 7 GB of space on my tablet before it could even start running. It is a big, slow, steaming pile of bloat-ware. Most of the others are too expensive for my frugal nature. So I started with icTrainer, which is less well known. At $30 per year, it is the least expensive of the non-free apps. They had great support, promptly answering a couple of questions I emailed them. Their Android app ran just fine on my old slow tablet. The rides I downloaded are huge since they have full video, and icTrainer stored them on the external SD card, which was a nice plus.

So far, so good. But I wondered if I could run indoor cycling software on my laptop, which runs Ubuntu 22. This would give me a bigger screen, and the ability to drive an even bigger external monitor. But it would require getting Windows to work.

Windows 10

First I installed VirtualBox on my Ubuntu 22 laptop, then unearthed an old Windows 10 installer ISO file and unused license key I had hanging around. The Win 10 install went fine and I installed the icTrainer Windows app, which also went fine. The problem was: how to get the Windows 10 VM to use the laptop’s Bluetooth so icTrainer could control the trainer?

I’ll cut to the chase. Start by ensuring that the Win10 VM is shut down.

First, shut down Ubuntu’s bluetooth service, so it releases the computer’s Bluetooth hardware.

sudo service bluetooth shutdown

Next, find the computer’s Bluetooth hardware. It’s considered a subset of the USB system, so list the USB devices:

lsusb

In the list, look for an entry related to Bluetooth. On mine, it is this:

Bus 001 Device 003: ID 8087:0a2b Intel Corp. Bluetooth wireless interface

Next, start the Win10 VM and then log into it.

In VirtualBox, go to USB Devices, look for that same device in the list, and check the box so VirtualBox so it can make it available to the VM.

Now in Win10, confirm that it’s there by going to “Device Manager” and finding the Bluetooth section. If it doesn’t appear, try rebooting the Win10 VM.

At this point, the Win10 VM has access to the computer’s Bluetooth and any apps that use Bluetooth (such as indoor cycling training programs) should work.

Scrabble on Mobile

I’ve been playing Words with Friends with family, both near and far, for the past year or so. It’s similar to Scrabble but the scoring and rules are different enough I wanted to try good old fashioned Scrabble. I discovered that Hasbro and Electronic Arts collaborated to create a mobile version of Scrabble where the gameplay is similar to Words with Friends.

What’s Wrong with WWF?

The Words with Friends rules favor frequent players, which can be unfair. For example, it has short 5-move games you can play with its AI, and doing this earns you credits you can use to buy swaps and other advantages when playing other people. Also, WWF is generally easier than Scrabble encouraging crazy big plays. For example, every time you prepare a move it shows a bargraph showing how good that move is compared to the best available, so you know whether there’s a bigger scoring move, how much bigger it is, and whether it’s worth taking more time before submitting your play. Finally, the Scrabble app uses the official built-in Scrabble dictionary, where WWF has its own dictionary that is frustratingly inconsistent.

Scrabble is available on iOS and Android and it has the same rules & scoring as the good old board game you remember. And the familiar consistent dictionary. Once you get it set up and you log in, it works quite well. But getting there is much more difficult than it needs to be.

Where Are My Friends?

Installing is easy enough. But once installed, if you want to play with your friends, you all need to create accounts. Scrabble offers Facebook, but since I don’t have a FB account, I used the alternative option to create an Electronic Arts (EA) account.

I did this for both Michelle and myself. Then in the app I clicked “New Game”, then “Play with Friends”. The list of friends was empty, as expected since this was my first time. I tapped the “Find player” searchbox to enter her username but the phone’s keyboard didn’t appear, so I couldn’t enter anything. This was confusing: what is the point of a “Find player” search box, if it doesn’t let you type in anything to search for? I tried this on Michelle’s phone too, same behavior.

Then I googled the problem. Apparently, lots of people encounter this problem. With further reading and experimenting, here is the workaround that I cobbled together:

Key Facts

  • There is a site called Origin, owned by Electronic Arts.
  • When you create an EA account, it is also an Origin account.
  • In Scrabble, you can only play with people you have befriended on Origin.
  • Origin is both a web site, and a fat client application on Windows and Mac.
  • Finding and befriending other players can only be done in the application, not on the web site.

Workaround Steps

  • Point your browser at EA create a user account.
  • Point your browser at Origin and download the fat client (Windows or Mac).
    • Since I run Linux, I used my Windows 10 VM running on VirtualBox.
  • Install the client app, run it, and log in as your EA user.
  • In the app, use the “find friends” feature to find your friend(s).
    • You need to know their username or email.
  • For each one, click on them and send a friend request.
  • Your friends must follow the above steps, then accept your friend request.

After the above is complete, run Scrabble on your device. Pick “Create New Game”, then “Play With Friends”. Your friends should now appear in the list. Pick one and play!

Why Can’t I Submit my Move?

I’m in a game with Michelle and I submit a move. The submit button transforms to say “waiting”… and the app just hangs. A few minutes goes by, nothing. I close the app, open it again, and my move is gone as if I had never made it. I make the same move again, and submit it. Same behavior.

Long story short, the app had logged me out. But it didn’t tell me. And it just stopped working without any error message or indication why. Poking around, I went to settings and happened to see that I wasn’t logged in anymore. I logged in again. Then the app started working.

So, the app occasionally logs you out without telling you, and misbehaves for no apparent reason. Keep that in mind. If the app every acts strangely, go to settings and double-check your login status.

Conclusion

What’s really frustrating about this process is how obscure it is. The average person:

  • Won’t know why the app “Find player” search box doesn’t work.
  • Won’t know that EA is associated with Origin.
  • Won’t know that they can only find friends on Origin.
  • Won’t know that this feature only works in the Origin app, not the web site.
  • Won’t know that the app occasionally logs them out.

None of this is explained in the app or in help that I could find online. The first part is a one-time setup thing so that’s no a problem if you know to do it. The second part you just need to know about. But once you get past these, the app is pretty good. It’s fun to play old-fashioned Scrabble without any player aids which is more balanced and fair.