Pathfinder Bots: Simulation

@FightBot1 and @FightBot2 are Twitter bots that battle each other with randomly-generated level 1 Pathfinder Fighters.

Pathfinder’s combat rules are very complex, so I knew implementing the whole thing was impractical. I chose to exclude spells and skills, and as many special attacks and activated abilities as possible.  Thus I chose the Fighter class, the simplest class that just uses weapons.

Usually, Pathfinder has a Game Master, who has final say on anything that happened in the simulated world.  Players announce what they intend their characters to do, but the GM can modify, interrupt or ignore those actions when necessary.  When playing over Twitter, there is no GM, just the two players passing messages back and forth.  Thus, any action that interrupts another action, as well as hidden information that can affect the outcome of a player’s action, is no good.  That means anything that provokes attacks of opportunity (casting spells, firing ranged weapons, performing combat maneuvers, managing inventory, drinking potions, or even moving) was excluded.

Position and movement gave me trouble as well.  Pathfinder is based on a grid of 5-foot squares (actually cubes, when the game remembers the third dimension). Level 1 fighters can’t fly, so I could ignore height.  Should I simulate a 2d arena? Should it be a featureless square, or circle, or have terrain? What happens if a fighter runs into a wall? Into a corner?  Maybe a one-dimensional position, just a distance from opponent, would be sufficient to let ranged weapons, reach weapons, and normal weapons seem different.  If the fighters never take actions that provoke attacks of opportunities, they won’t get interrupted.  But knowing when a fighter is threatened requires knowing what the enemy is wielding. So I decided to only use melee weapons, and ignore positioning altogether. If one character has a reach weapon, just pretend that the the fighters are making 5-foot steps each round.

So fighters can only perform melee attacks.  What races are allowed, and what equipment and feats will they use? I used only items from the Core Rulebook, not the innumerable books released since.  The CRB has seven races.  Only feats available at level 1 that affect health, initiative, or melee attacks are relevant.  Fighters are proficient in all armor, shields, and simple & martial weapons, so those are in as well.

In subsequent blog posts, I’ll explain the procedural generation of characters & descriptive text, and how I integrated with Twitter.

Building a simulation: what is vs. what should be

When I find something that is fun to do in life, I want to make a game out of it so I can share the experience with others.  But when I closely examine the systems and rules that the world runs on, I realize how messed up they are, and that makes me sad.

I want to build a conflict resolution system where violence is optional and body language is significant.  I look for examples of tense situations that didn’t result in violence and remember some stories my friends told on Twitter.  I am sickened to discover that I’m about to gamify my friends’ trauma, because those stories were about street harassment.  I don’t want to mine the pain of people I care about for a game.  I don’t want to make a game that makes people relive that pain.  But if I accurately simulate human interaction, there will be situations where “don’t make eye contact & hope not to die” will be the ideal response, because those situations are common in real life.

So replicating the awful systems of real life seems cruel, but changing the systems seems dishonest.  All simulations are simpler than the real thing, so I’m required to choose some elements to keep and some to discard.  This is why people say that all games are political.  The game maker decides what parts of reality to consider important, or worthy.  Even if I don’t want that responsibility, I have it, because I can’t replicate a system completely.  Even if I make those choices unthinkingly, I’ve still made them.

Another example is cosplay photography.  I think a board game about managing time and energy while trying to do photoshoots during a convention would be really fun.  Photographers with different styles and goals could be different playable classes.  Seems good, but some photographers seek social capital at the expense of others.  Some exploit minors.  Some won’t shoot men, or black people.  Do I offer these as options for players to choose?  Do players want these options?

More subtly, the resources I picked for a photographer to manage are artistic fulfillment, friendship, and fatigue, because those are the most important factors to me when I photograph a convention,  But my priorities and experiences are not universal.  Other photographers have different priorities, good priorities, not the awful goals from the last paragraph, just different priorities.  So what should I include in my game?

If art is self-expression (that’s a whole blog post by itself) and the game is my art, then I should make systems that appeal to me. Sometimes that will make the fictional world operate the way I think the real world should operate.  Sometimes that will make the game operate in ways I think are mechanically interesting, without regard to real-life applications.

But if the art in games comes from player expression, then the players are limited to the tools i provide them, and I will deny some of them tools they deem important, since people are diverse and I can’t predict what everyone will need from my game.

Procedurally-generated bodypaint

It’s text, but NSFW text.  Procedural Paint-Job Generator.

This idea came to me in the wee hours of the morning.  I got out of bed, coded all morning, and went back to sleep after publishing it.

I’ve been creating a vocabulary to describe the body paint at the Fremont Solstice Parade for a while.   I planned to use that in some sort of database-driven visualization for Solstice Parade photos, somewhat like Atlanta Fashion Police.  I still plan to do that, but this project goes the other way.  Instead of describing an existing paint-job with the vocabulary, I use the vocabulary to create a description of a hypothetical paint-job.  The plausibility of the paint-jobs varies, but that’s part of the charm.I used Kate Compton’s Tracery to generate the descriptions.  I started by adding all the words I could think of, grouped logically into colors, color modifiers, patterns, animals, vehicles, and so on.  Then I built phrases that combined those elements, built the phrases into clauses, and then into sentences.  It can suggest individual paint-jobs as well as groups, and pluralizing complex phrases is tricky!  The following sentences have identical meanings, but must be modified differently to be pluralized.

  • green and bright yellow giraffe
  • green giraffe with bright yellow spots

Putting an “S” at the end of the phrase doesn’t always work.  There are also things that are always plural, like “roller skates”.

  • You get your roller skates.
  • You get your bicycle.
  • You rent roller skates for your team.
  • You rent bicycles for your team.

English is tricky!

Whenever the generator recommends a pattern, it may recommend two patterns instead.  Those two could also recommend two more, so there’s no guarantee the recursion ever ends.  Browsers have a lot of memory, text doesn’t take much memory, and it’s funny to get a big paragraph recommending 20 different patterns in a single paint-job, so I leave it in.

The paint-jobs produced by this generator are by turns absurd, practical, amusing, and shocking.  What more could a procgen system strive for?

A simple game

Most of my game ideas are too ambitious to start.  I want to make games with procedural footprint generation, 3D traversal with encumbrance and different terrain types, or tons of dialog and subtle human reactions.  This means most of my games don’t progress past text files,

While watching AGDQ 2017, I realized that people love simple games, like the ones that fit on an NES.  The graphics are simple, there are only a few stages, enemies, and powerups, but that’s enough.

So I’m going to make an NES-style game, with one twist.  The main interaction is moving antagonists around, not destroying them.  The player fends off fans who rush a celebrity’s limousine with oil slicks, velvet ropes, and other cartoony tools.

I looked around for a game engine to use and settled on Godot.  In YouTube tutorials, some people pronounce it “Guh-doh” like the play, and others say “Go Dot”. The official site’s FAQ does not address the pronunciation.

Now that I have a game engine and can start writing code RIGHT NOW, I realize how many decisions need to be made before I start.  I don’t want fans getting to the limo, but how exactly does that work?  Do fans stop the limo, and the player fails if the limo is late?  Does the celebrity inside the limo have an annoyance gauge that increases as fans touch the limo?  If the fans have limited acceleration and turning speed, I can make more interesting traps that spin them around or slow them down.  Can I knock people down?  Are they injured by jumping in front of the limo?  Boss fights are traditional, but what is a ‘boss’ in this context?  A really big fan?  Do the different tools act like different weapons in Mega-Man, Contra, or Metal Slug?  I’m sure the answers will change as I go, but here is my first attempt.

Main game loop:

Top-down, real-time, 2D game.

A limo moves through a city on a pre-determined path.  It stops whenever a fan touches it.  The level ends in success when the limo reaches the end of its path.

When the limo stops, the celebrity’s annoyance increases.  The level ends in failure when the annoyance gauge is full.

The player controls a bouncer who moves independently of the limo on foot.  The bouncer can’t move out of sight of the limo.

Fans scattered around the level will try to get to the limo.  Fans activate when the limo moves inside a certain radius.  Fans give up and go home when pushed a certain distance away from the limo.

Possible types of fans:

  • Normal fan: default speed
  • Big fan: can break through velvet ropes
  • Quick fan: a bit faster
  • Screaming fan: can stop and scream, which summons more fans
  • Paparazzi: can upset the celebrity from range

Possible tools:

  • Bouncer’s glare: freeze a fan on the spot for a short time
  • Velvet rope: blocks a path.  Force fans to go around
  • Autograph:  Throw autographed merch.  All fans near the merch’s path will chase it.
  • Spring trap.  When triggered, push back everything in its path
  • ice or oil:  slows fans moving through the area

Possible levels

  • An actor goes to a shooting location
  • A singer goes to a concert
  • A celebrity goes to an award show
  • A politician goes to give a speech.

Gallery Aggregator roadmap

When I return from a convention, I scour the internet for photos from the event.  Many convention-goers do the same, as evidenced by the many “looking for photos” threads on forums and social networks.  I’m building a searchable list of galleries from many different events  that is more permanent and easier to search than those “looking for photos” threads.

Here’s the current version

I’d rather have other people do my work for me, so I built a public page where people can submit galleries.

Check it out, and please add a gallery or two.

People would rather have a machine do their work for them while they are doing my work for me, so when someone submits a link to  a Flickr album, the website uses the Flickr API to pull in the rest of the data.

The main functions of the site (submitting, moderating, and displaying) are all working and stable, so now I can think about improvements.

  • Integrate with other sites’ APIs

Flickr is not the only image host with an API.  I should integrate with SmugMug, Imgur, and Facebook.  Automating data entry makes it easier for users to submit galleries, and makes the data submitted by users more reliable.  It’s good for both of us.

  • Make the site prettier

The styling on the site could charitably be described as “basic” because I  focused on functionality.  User experience is important, so I should make the site smooth and pretty.

  • Label NSFW content, and galleries that require logging in

If a user can’t view a gallery, a link to that gallery is a waste of time.  Some image hosts, like Facebook and Flickr, may require users to log in before they can see the gallery, so I need to warn users before they click.  Users hsould also be informed before clicking on links to NSFW photos.

  • Allow users to report dead/bad links

Sometimes links go dead, or domain names expire and are taken over by squatters.  Anyone who finds a dead link should be able to report it, so I can remove it.  This saves me the effort of periodically checks all the links, and lets users help make the site a better place.

  • Rating system

Someone who doesn’t have time to look through 100 galleries from a certain event may want some way to decide which few to look at, and user ratings are one way to provide that.  I think that “popular” and “good” often diverge, so I’m unconvinced that directing people to popular galleries is a good idea.  I could curate my personal favorites, but since what I like and what the masses like are different, that feature may not be useful to the users.

  • Add more content

I have added hundreds of galleries already, but I’ve been collecting galleries for a long time, so I have many more to add.  The more content is on the site, the more useful to visit, which means more people who like it and may contribute.  It snowballs.

  • Get other people to use the site

All this information is only useful when people know about it and use it.  After each event,  I’ll post in the various “looking for photos” threads encouraging people to use the site.