Skip to content

Releases: arpeggiorpg/arpeggiorpg

Dev Log 3: mobile, performance, panning/zooming, map annotations, White Plume Mountain

19 May 03:41
Compare
Choose a tag to compare

P&T Dev Log 2017-05-18

Yeesh, it's been about a month and a half since my previous dev log. I admit, development has slowed in that time period, but a lot of features and fixes have still accumulated. Here's what I'll cover in this log:

  • Volume/Area effects
  • Map navigation with mouse and mobile touch
  • Improved mobile UI
  • Map notes and highlighted map tiles
  • Optimizing Elm programs
  • Implementing White Plume Mountain in P&T

What is P&T?

P&T (name to be changed) will be an extensible digital game system for table-top roleplaying.

What does that mean? Well, think about Pathfinder, HERO, or Dungeons & Dragons: traditional table-top roleplaying games. Now, imagine that all of their features and systems are implemented as an app on your laptop, phone, or tablet. P&T aims to be something like that.

It's important to note that P&T is not an implementation of some existing ruleset: it's a completely new system. In fact, it's not even really a game system, but a game engine that systems can be built on. The games will come later. Let me reiterate: P&T is not an implementation of D&D, Pathfinder, or any other system, and it doesn't aim to support those systems.

P&T is really very early in development. It can't be used to run games by itself, but it offers useful campaign-management tools and a tactical battle map, which I'm already using in practice.

Recent Developments

Volume/Area effects

Summary: Basic AoE abilities are now possible with a volume-targeting system.

Abilities that affect an entire volume of space are an important part of tabletop role-playing. The "Fireball" spell is a classic example. I spent a lot of time implementing these and, to some extent, polishing the UI for activating them.

In P&T, Creatures have Abilities, and Abilities have a TargetSpec, which defines how targets must be specified when using that ability. The most commonly used TargetSpecs are Melee and Range(Distance). There's also Actor TargetSpec for abilities that only target the user. Since the last update, I've implemented AllCreaturesInVolumeInRange{volume: Volume, range: Distance}, which makes it possible for an ability to have its affects applied to all creatures in an arbitrary volume.

But what is Volume? Right now, I've only implemented Sphere(radius: Distance) (e.g. Fireball), but LineFromCaster(range: Distance) will be an important one to implement for abilities like Lightning Bolt. Others might be VerticalColumn(range: Distance, radius: Distance) for an ability like "Blast from the heavens", or Line(range: Distance, max_length: Distance) for an ability that lets you conjure an invisible wall.

Another important type of TargetSpec will be TargetSpec::Volume{volume: Volume, range: Distance}. This will allow defining abilities that affect volumes themselves instead of creatures within a volume. This is for persistent area effects like oil-slicks or magical grasping vines. Still TBD, though!

Area-effect UI

As usual, implementing the UI took longer than the game logic, but I'm happy that I have a fairly usable interface with good visible feedback. Here's a video of me using Silmarillion's Fireball ability.

Demonstration of Area Effects in P&T

Things you might notice in this demo:

  • After you click or tap a target, it shows both the area affected in pink, and highlights the creatures in that area in red.
  • You can then decide to click somewhere else, before confirming the ability, to affect a different area.
  • The fireball can affect tiles through unpassable terrain. I still need to implement line-of-sight checks to determine where these AoE abilities "spread". I'll also probably need to implement different TargetSpecs for AoE abilities that can spread around corners (like fireballs classically do) and others which don't (like a blinding flash ability).

Map navigation with mouse and touch controls

Summary: It's now possible to easily drag the map around with your finger or mouse, thanks to svg-pan-zoom.js and hammer.js.

I had been thinking about this and evaluating different ways to do it for quite a while. For some time I was considering implementing this behavior from scratch in Elm, but there are just too many concerns to make that feasible, so I ended up using the excellent SVG Pan & Zoom JavaScript library. This required understanding how Elm/JavaScript interaction worked to a reasonably low-level, especially since this library deals with the DOM nodes that my Elm code renders. I also had to incorporate Hammer.JS to support touch screens.

This was pretty tedious to implement, since it involved testing on a number of platforms, where I saw differences in behavior in each one. The browsers I tested were Firefox (Windows), Chrome (Windows), Chrome (Android), and Safari (iOS). In the end I wrote a small JavaScript module (PanZoom.js) and Elm module to interact with it (PanZoom.elm).

I had to work around some tricky issues with JavaScript event ordering, especially since the SVG which I'm applying the pan/zoom code to also wants to handle clicks (for example, clicking a character to move it, or clicking a tile to target a spell). The note in PanZoom.js, linked above, describes that in more detail.

All that done, it's working quite nicely now! Here's a demo:

Demonstration of panning and zooming in P&T

Improved Narrow UI

Summary: The UI now renders differently on narrow screens, making the experience on portrait-mode phones much better.

I spent some time improving the UI, since I noticed it was pretty terrible, especially on a portrait-mode phone. When the screen width is lower than a threshold, the view switches from having the map in the "background" with a tabbed sidebar, to making the "sidebar" fill the entire screen and move the map into a tab. I had to learn about CSS's transform: scale() directive, and this article by Chris Coyier on CSS-Tricks was very helpful to me. Not only did I make the sidebar fill the entire width of the screen, I scaled up the content inside of it so that it was actually legible/navigable.

Here's the demo!

Demonstration of the narrow mobile UI in P&T

"Special" map tiles & annotations

Summary: It's possible to put colored tiles with notes on your maps, visible to your players or just the GM.

One of the features I talked about wanting to work on in my last dev log was "Map annotations", and I'm happy to say that I've now implemented them. When editing a map, the GM can paint "special" tiles instead of just the usual terrain. When painting a special tile, you can choose the color that it will be rendered as, and whether it should have a note attached to it. In addition, you can specify whether it should be visible to the GM only, or All Players. This is helpful if you need to keep track of secrets in your maps.

The UI is still extremely primitive, and there's a lot of rework I want to do here. Here's a quick demo.

Demonstration of Painting and viewing special tiles in P&T

These special tiles don't affect whether terrain is open or not, so you can put them both in inaccessible parts of the map, or on top of open terrain that the players can walk through. As the video shows, players can click these tiles to show the annotation.

Optimizing Elm UI

Summary: I made the UI much faster.

A couple weeks ago, I was getting extremely frustrated with the performance of the P&T UI. After spending a ton of time figuring out the extremely under-documented and hacky "lazy" VirtualDOM system that Elm provides, I realized that the biggest part of my performance problems were because I was using the "Elm Reactor", a development tool that automatically recompiles code when it changes, which is very handy. The problem was, it also enables some very high-overhead debugging code when you're running your app -- it keeps track of all model changes while your app is being used. This means that for every letter you type into a text field, it's doing a lot of extra work with your model state.

Once I realized that it was slowing my app down significantly, I wrote my own custom file-watching build tool that takes advantage of the excellent watchexec tool, which is written in Rust and supports all the major desktop platforms.

However, I was still running into some performance issues. To understand why, it's important to know how Elm (and other model-view-update frameworks) work. Basically, every time your model changes, the entire view is re-rendered with a pure function. This is an elegant system in that it avoids any kind of accidental statefulness in your UI widgets, but it also means that you might be re-rendering parts of the UI that are completely unrelated to a model change. Since even things like text entry strings are stored in the model, every time you type a letter into any text box, the entire app's view is re-calculated. My SVG-based map can get into the tens of thousands of nodes, and even though Elm makes use of a Virtual DOM, it was still taking a lot of time to evaluate all of those nodes, just so that they could be thrown away since they were equal to what was already in the rendered DOM.

Frameworks like [React](https://facebo...

Read more

The Second One

27 Mar 20:29
Compare
Choose a tag to compare

P&T Dev Log 2017-03-27

Summary

Over the last couple of weeks I have been hard at work on the campaign management tools in P&T. I pretty much covered what that means in the previous dev log. In this update I'll show what I've done with campaign management and saved games, and also talk about some implementation details of pathfinding and folder layout.

What is P&T?

P&T (name to be changed) will be an extensible digital game system for table-top roleplaying.

What does that mean? Well, think about Pathfinder, HERO, or Dungeons & Dragons: traditional table-top games. Now, imagine that all of their features and systems are implemented as an app on your laptop, phone, or tablet. P&T aims to be something like that.

It's important to note that P&T is not just an implementation of some existing ruleset: it's a completely new system. In fact, it's not even really a game system, but a game engine that systems can be built on. The games will come later. Let me reiterate: P&T is not an implementation of D&D, Pathfinder, or any other system, and it doesn't aim to support those systems.

P&T is really very early in development. It can't be used to run games yet, though I am using its campaign-management and tactical map features in my weekly D&D games as a way to eat my own dog food.

Recent Developments

Campaign Management

Since the last update, I've completed the folder-organized campaign management system to a functional prototype level. Click the image below to see a video demonstration.

Demonstration of P&T campaign manager

In addition to what's shown here, there's also support for creating textual notes in folders.

Saved Games

I finally added a very basic save/load system which allows saving to files in a folder on your hard drive. With this, I can finally use P&T for my own long-term campaign management, and I've already begun laying out maps for my group's adventure next month.

Miscellaneous battlemap improvements

In support of my weekly campaign, I added a few features to the tactical map. Most important was the ability to mark creatures as hidden from players, so that I can set up a scene with a bunch of enemies just around a corner, and only show them when the player characters actually get a chance to see them. This is much quicker than having to add them to the scene manually during play! However, while this will probably always be a useful feature, it's a far cry from the dynamic line-of-sight support that I ultimately want to implement.

Implementation Details

Here I'll cover a bit about the implementation of the game, with links to the open source code, written in Rust and Elm.

Pathfinding

Even though I haven't been working on it recently, I wanted to write a bit about the pathfinding support in P&T.

Video of P&T's pathfinding and automatic movement destination calculation

Above is a video that shows what happens when you move a creature in P&T. One piece of functionality I'm happy with is the way that all possible movement destinations are shown to you when you initiate movement. Then, all you have to do is click where you want to go and the pathfinder takes care of the rest.

I had to spend a bit of time optimizing this code -- my first naive implementation took a noticeable amount of time to calculate all possible movement destinations. I eventually hacked apart the A* implementation from the pathfinding crate to support searching for multiple destinations without having to recalculate the entire path every time. I'm pretty sure this code is still nowhere near optimal, since I basically knew nothing about pathfinding before implementing it, but the basic way it's implemented is:

  • get a list of all points that are "open" (i.e. those which aren't filled with blocking terrain) within some distance of the current mover. (code)
  • run the pathfinding algorithm to all of those points (code)
  • the pathfinding algorithm uses one single HashMap to keep all the paths to all of the destinations. At the end, we go through all of the destination points and construct the paths from that map. (code)

The main way in which I changed the code which I copied from the pathfinding crate was to keep that "parents" HashMap for multiple searches, and then reconstruct all the paths from it at the end. While there's still probably a lot I could do to speed this code up, this optimization brought it to the point where I could comfortably use it in P&T.

Campaign Object Ownership

As I mentioned in last week's dev log, one thing I was struggling with was how to structure the data in the campaign folde, and correspondingly, how to expose this structure to the user. The question was whether the Folder structure should "own" the data that it contains, or whether that data should be separate and only provide links to the data.

I ended up keeping my data in separate collections in the top-level Game struct(code), and then have the folder tree just link to those objects by ID. However, instead of exposing the "linkiness" of the folder structure to the Remote Programming Interface/user interface, I hid that entirely. So even though it could be possible to have multiple links to the same data in a folder structure, I hid this functionality so the UI code only things from a folder-ownership perspective.

I also had to spend quite some time ensuring that the folder structure and the flat object store at the root wouldn't get out-of-sync. As one example, any time you delete an item, it scans the entire folder tree for any references to that item to make sure they get cleaned up (theoretically this shouldn't be necessary, since we could pass in the folder path in order to name the resource during deletion, but I wanted to make sure to account for any bugs that might leave extra links throughout the folder structure).

This goes extra for things which can be referenced from other places. For example, Creatures can be referenced from Folders, Scenes, and Combats, so I have to scan and clean up all of those things upon deletion. This scanning is arguably horribly inefficient, but I think it would require quite a huge campaign structure to make the inefficiency noticeable. That said, this could certainly be improved, either by implementing some stronger abstractions (like what a hard drive filesystem might have), or by just switching storage to a relational database and taking advantage of relational consistency features.

FolderTree

In support of the campaign tree, I implemented a fairly generic FolderTree data structure. I may publish it as a separate crate some day, if I get some time to polish it up (and convince myself that other people might find it useful).

Where from here?

While my next big goals remain the same as what I described in the previous dev log (support for Adventure Modules and doing some game system prototyping), there are a few things that I might end up tackling before/during that work, in support of my day-to-day use of the battle map for my D&D game.

Map annotations: It would be very handy to have highlighted and annotated spots on the tactical maps. This would let me represent notable features of the environment to my players, and with access-control, also allow me to provide notes to the GM about things like traps and whatnot.

Creature Size: Right now, creatures are represented only by their position on the grid, and it is assumed that one creature fills up exactly one grid square. This is problematic for a few reasons, most importantly because there are larger and smaller creatures in the games I want to run. But there's another reason that I think this could be helpful.

One thing that I would like to do once this is implemented is to make the "default" creature size larger than the grid size, probably by one size increment (so a creature takes up four grid squares). This would allow for much "smoother" edges in non-rectangular environments. One reason this is particularly important is how pathfinding around corners works. Naturally, we don't want to allow going around corners to be as easy as moving at a diagonal, since you would probably clip your shoulder into the wall. But the scale at which creatures and grids align mean that a diagonal wall can only be represented by a series of corners. This means moving along a diagonal wall takes up quite a lot more movement than it should. So scaling down the grid size relative to the creature size would mean I could have much more natural distance used.

Of course, making the grid size finer-grained is probably going to put a lot more strain on my pathfinding algorithm, so I may be forced to spend more time optimizing it.

End

Thanks for reading, if you have! If you have any interest in a project like this, either as a writer, artist, system designer, programmer, or playtester, please give me a shout at [email protected].

The First One

19 Mar 05:54
Compare
Choose a tag to compare

P&T

P&T (name to be changed) will be an extensible digital game system for table-top roleplaying.

What does that mean? Well, think about Pathfinder, HERO, or Dungeons & Dragons: traditional table-top games. Now, imagine that all of their features and systems are implemented as an app on your laptop, phone, or tablet. P&T aims to be something like that.

It's important to note that P&T is not just an implementation of some existing ruleset: it's a completely new system. In fact, it's not even really a game system, but a game engine that systems can be built on. The games will come later. Let me reiterate: P&T is not an implementation of D&D, Pathfinder, or any other system, and it doesn't aim to support those systems.

Status

P&T is really very early in development. It can't be used to run games yet. Still, I've been working on it for a while now, nearly full-time, and I've decided to start making releases mostly as a way to have a dev blog of sorts -- I wanted to start documenting my progress both for my own amusement and motivation, and to maybe drum up some interest in my project.

Recent Developments

Campaign Tree

Most recently I have been working on the "Campaign" view -- this is going to be the main way that a GM organizes and finds things in their games. All battle maps, scenes, creatures and notes will be laid out in a folder tree in this view.

There's still a lot of work here, and a lot to figure out. Right now, the folder tree doesn't "own" the objects that it contains -- everything is sitting in a big pool elsewhere, and the campaign tree just "links" to those maps, scenes, creatures etc. That means that all of those things can be linked at multiple places in the tree, or even nowhere at all. This may need to change, either by really making the folder own the objects (to avoid confusion about things being linked in multiple places, or unlinked but still existing), or by making the linking system less error-prone (don't allow deleting the last link to an item, make sure the user really wants duplicate links if they're trying to do that).

Screenshot showing the new Campaign tree

In addition to that, I have the following things on my todo list related to campaigns:

  • create creature in a folder
  • delete/unlink things from folders
  • edit notes in folders

Other Developments

Campaigns have been taking my time for the past several days, but since this is my first dev log, I figure I should include a basic rundown of what P&T can do so far.

  • Creatures: Creatures have names, health, movement speed, conditions, and classes.
  • Conditions: Conditions are a set of specific modifiers that apply to a creature, such as:
    • damage boost (not implemented)
    • recurring effect applied on every one of the creature's turns (implemented)
    • health buff (not implemented)
  • Classes: A class defines what abilities a creature has, can also include a set of permanent conditions.
  • Abilities: An Ability has a target "specification" (melee, ranged(500), etc) and an associated Effect to apply to their target.
  • Effects: An Effect is some specific thing that can happen to a creature, such as Damage, Heal, or Apply Condition.
  • Scenes: A scene is the combination of a battle-map and a set of creatures. Combat is also scoped to a scene, so a combat can only take place in one scene at a time.
  • Battle Maps: There is a terrain map system with a super-basic grid of 1x1 meter squares which creatures can occupy. The terrain system is currently 2d and only supports one bit of info: passable or non-passable.
  • Pathfinding: There is a pathfinding system implemented, so you only have to click your character and then click where you want it to move. One part that I'm particularly proud of is that when you click a character, it calculates all possible movement options for you and highlights them so you know where you can move. This is based on the creature's speed.
  • Combat: There's a combat system with turn orders, very basic action economy (Abilities can consume Energy which is restored on your next turn), and movement economy (you can move up to your speed).
  • Multiplayer network communication: The web interface has push notifications and players can log on and be granted control of their creatures so they can move them in and out of combat, and all of actions are synchronized in real time with the other clients.

That's pretty much it.

Where from here?

There's an unimaginable amount of work left to do on P&T before it's ready to run an actual game, though I have started using it solely for its battlemap during my traditional tabletop RPG games to put it through its paces.

Modules: Once I'm done with campaign management and it seems usable, I'd like to add a system for "Adventure Modules", which are basically a way to bundle up a campaign as a reusable thing and distribute it to GMs.

Game System Prototyping: I'm really not much of a game designer, but I have a number of actual game features that I'd like to implement, mostly as a way to ensure the flexibility of the core engine. For example: a "sneak attack" ability that grants a bonus to damage if an ally is flanking your enemy. This will require extending Effect execution to allow it to query the map, which is currently impossible. Or a "rough terrain" system which makes movement through certain squares slower than others (which should have interesting effects on pathfinding).

End

Thanks for reading, if you have! If you have any interest in a project like this, either as a writer, artist, system designer, programmer, or playtester, please give me a shout at [email protected].