Locations, biomes, UI updates, and throwing Tribes whole into the trash
I haven’t posted any groovelet updates since November, mostly because the last big update implied that “tribe goals” were going to be a Big Deal and I wasn’t sure how to write off “tribe goals have been cancelled because they sucked”.
I use this image almost unimaginably often.
I spent a solid six weeks, just up until Christmas, working “tribes” and “tribe goals” into the game code. As I worked on them the slog of i think this might actually be a bad idea intensified. (If that seems like a slow development pace, remember: I have a day job.)
The idea was to have the ability for players to form and join groups; then, having joined up with a few other players, the groups would present shared goals that the entire team could contribute cards towards. Completed goals would benefit everybody in the same group.
The problem of shared group goals is scaling them appropriately.
If goals are too easy to complete, a handful of members of the group can quickly burn through the entire goal tree. If they’re too hard to complete, a whole group working at near-maximum efficiency will barely be able to make progress at all.
Imagining that you have a tribe of either 5 or 20 or 150 or 1000 people, how do you scale a goal so that it’s an appropriate challenge to that set of players? You have no real expectation of how many of those players will be online at any given time - a tribe of 150 might be ravenously online or they might be 5 active players and 145 completely-disappeared players. My plan around this point revolved around measuring how active your group has been just recently and using that as a bellwether to scale goals: if 15 players logged in today and 5 players logged in the last hour, we’d apply a (15*DAY_MOD)+(5*HOUR_MOD) numerical boost to the difficulty of whatever goal needed to be completed.
Thereby, uh, disincentivizing players from logging in unless they’re fully committed to grinding on a Tribe Goal. Uh, wait, that’s awful. I did a bad design.
I think, for this reason, Tribe Goals aren’t the magic bullet of player motivation I’d hoped they would turn out to be. I can still keep Tribes and Goals in my game, but I want the game - despite being multiplayer down to the very core - to still be a satisfying solo and casual experience.
Maybe the solution is to have fixed-size tribe goals; impossible for small tribes, easy for large tribes. It incentivizes tribe growth, which is good, right? And any contribution is welcome in that environment.
Anyways: Tribe Goals. What a slog; Six weeks of development and I hadn’t even touched the UI yet! Turns out the idea of having shared gameplay state that interacts with multiple intersecting games is complicated to manage. who knew? (everybody. everybody knows this.)
Anyways, I kept Tribes in the codebase (probably going to need those anyways) but I’ve buried Tribe Goals in a branch for now, to be resurrected later when I have a better idea how I want them to work and what I want to use them for.
Now this was something I had a pretty well-developed plan for.
The game is intended to take place in a graph of locations:
Each location is intended to have its own forage deck - so you can find different cards in the forest than you would in the mountain.
Some of these locations can be pretty specific; I was thinking that a well location attached to the home and garden nodes might exclusively have “water” cards in the forage deck, which the player could then truck over to the garden to water plants. Maybe the player could construct a watering can to allow them to draw cards from the forage deck in the well faster.
One of the big considerations early on, here, is how to make the map dynamic. Storing a sparse graph like this as a data structure is easy enough - but what if we want to display it to the users?
Well, that’s… graph visualization, and it’s… complicated. Heavyweight. Difficult.
Like, I want the graph to be created on the fly for each user, but I don’t want nodes to overlap at all, and then, once a graph has been created, if we add a new node I don’t want any of the previous graph nodes to change position.
I could also consider, like, just straight-up hard-coding the map. It’s bound to be prettier that way.
My current, temporary solution to this problem is, uh, just to display the node you’re currently AT and a list of connected nodes.
Not much of a map, is it? Anyways, that’s been holding the fort while I’ve been building out a lot of connected Location logic. A Map is created for the user when they start a game; It’s possible in the game to BE in a location. It’s possible to MOVE BETWEEN locations using the “Travel” cards that now spawn in your Backpack.
Locations have a Biome which describes how they look, and the Biome system is tied intimately to the game’s underlying calendar, so now we have seasons and times of day that are all… actually rendered, in gorgeous developer art.
This effect is accomplished with a technique that I keep going back to again and again: stacks of transparent png files.
I’ve also spent some time adjusting the card engine so that certain cards can be restricted to only appear during specific seasons, times of day, or in certain biomes; I can also configure it to remove cards from view and make them unplayable if not in those biomes.
As an example of how this might work, “sleep” is a card that’ll go into your deck at the very beginning of the game, but it might be locked to only appear at “home” and “night”.
Two Small UI Improvements
While I was working on this I added two things that make managing the game’s growing card piles slightly easier.
First of all: when you play a card with requirements, the requirements will be shown in the Turn window next to the card:
Mmm, slightly more intuitive.
And, uh, okay, so, the current set of cards loaded into Groovelet has exactly one card combo in it, a ramp that can be abused to generate dozens, nay, hundreds of pulp cards, log cards, and plank cards.
This is on purpose; there’s not a lot in the game in the way of “goals” but setting up and executing the Unlimited Plank Combo is a bit of a micro-puzzle and kind of a satisfying way to spend 15-20 minutes already. It’s like a hint that my game might just be actual fun if I’m careful. But executing Unlimited Plank Combo creates a truly spectacular amount of cards which make managing your backpack harder, even with the tag-management and paging features I’d already added.
So now, identical cards form themselves into stacks:
… am I just building Cultist Simulator?
With the introduction of “locations” it feels like my fledgeling card engine has almost everything it needs to produce a whole bustling little virtual world of cards and card-interactions.
Which, uh, maybe means I need to figure out what… those cards and card-interactions are going to be.
Like, in my notepad I have “lake” written down, and “fishing?” next to it. How does fishing work? Also, (to the intense dismay of my outdoorsy father) I don’t know anything about fishing, or really care about fishing at all.
Anyways, it means that the next phase of development might involve, like, “writing” and “game design” and “music” and “concept art”.
You know, despite doing all of this programming so that I can eventually get to the writing and game design and music and concept art, I sure am less confident about those things. How does words? What is music?
Some people may say “you should have done all of this way before you went and built an entire engine”, and to those people I say do you want ludonarrative dissonace? Because that’s how you get ludonarrative dissonance. The game and the world and the story and the engine all have to evolve at the same time, so they can be uniformly shitty, together, in a cohesive way.
John Swartzwelder has a philosophy of “getting everything kinda working together, badly, and then fixing it until it’s good”, which actually I think is a good way to describe how I work on complicated systems.
Since writing is very hard and rewriting is comparatively easy and rather fun, I always write my scripts all the way through as fast as I can, the first day, if possible, putting in crap jokes and pattern dialogue—“Homer, I don’t want you to do that.” “Then I won’t do it.” Then the next day, when I get up, the script’s been written. It’s lousy, but it’s a script. The hard part is done. It’s like a crappy little elf has snuck into my office and badly done all my work for me, and then left with a tip of his crappy hat. All I have to do from that point on is fix it. So I’ve taken a very hard job, writing, and turned it into an easy one, rewriting, overnight. I advise all writers to do their scripts and other writing this way. And be sure to send me a small royalty every time you do it.
So, hopefully I have my first trash-pass of Groovelet ready in a couple more months, at which point all I have to do is rewrite all of the work that these crappy little elves did.