Code Collaboration

Some context:

Semi-recently we formally "open sourced" the base game content for King Arthur's Gold. The game itself isn't free, but the source to all the game's scripts, art assets, and configuration files are now available on github for contribution and investigation.

To give you an idea of the scale of the repository, there's about 55k lines of code (not including comments and blank lines) across about 500 scripts. Not huge, but it's pretty much all business logic. All the framework stuff is in the engine, which is in a different (closed) repository.

The outcome has been good for the game so far. People now have access to the previous state of things, so when a mod breaks they have a better chance of figuring out what went wrong. They have eyes into what is being worked on, when, by whom. Motivated users can issue pull requests for whatever "dumb stuff" they'd like to see changed, and we've actually given some of the more productive contributors access to our internal repositories as well.

I want to talk about some recent thoughts about collaborating as programmers. It got quite long, so let me know if a further-distilled version would help you.

I'm writing from the perspective of an indie used to working in very ad-hoc circumstances, with some recent exposure to more formal open source practices. I'm quite used to small teams, everyone being able to push to master, onboarding developers infrequently and informally, and code review being a post-hoc blame game. We do at least use proper version control though, so there's some hope yet!

I'm likely showing my hand even further in talking about the following as if they're shifts in perspective, but I hope they might help other indies and small time devs think about their workflow. I'll briefly define any potentially unfamiliar or vague terms.

Pull Requests are Good

Github has a half-decent explanation of pull requests here.

There's nothing worse than days where "Someone broke the repository" or "We have to hold a release because this feature isn't done yet". Even worse, changes that you didn't really pay attention to having some nasty gotcha that you find out only in production. Pull requests are a front-line defence against these situations.

Pull requests mean that at least someone has to check over anything coming into the repo. They encourage developing features and fixes in separate branches rather than all in one big always-merged master branch, as this makes it much easier to issue sane pull requests. Pull requests give you a good place to say "not yet" or provide constructive criticism on someone's changes, while allowing the contributor to address your concerns by adding more changes or explaining any misunderstanding. It's all very collaboration-y.

Anecdotally, it seems that there's also fewer "oops typo" style commits - perhaps because you want to be pretty sure something's going to work before pushing it into a pipe that might not get back to you for a day or two!

This is one of those super-obvious things that open source and big organisation folks definitely "already know". It seems like a workflow a lot of indies could benefit from. For those unwilling to go the whole way, working on everything in branches and discussing any merges to master ahead of time would get you at least half way there.

It's not all gravy, but bad experiences I've had with this so far are probably my fault. We don't have a PR template to guide people towards making good pull requests, and a lot of the community are more or less "jumping in" without really having used git or any kind of source control before. A lot of assumptions they make about how something "might work" are faulty and that can lead to frustration or at least confusion. We probably need a good place to point new developers and better resources about getting started with our particular codebase.

Code Review is Good

By Code Review, I mean the process of one or more developers formally checking over changes before they're merged into the master branch. Ideally this is carried out by developers who were not responsible for the changes in question.

Pull Requests require some code review, minimal though it may be. It's technically possible to just smash the merge button, but there's plenty of good reasons to be cautious when pulling in unknown changes from some person on the internet.

This kind of seemed like busywork at first, because it eats some poor developer's time (mine) checking over what someone else has spent time writing, but so far I'd say it really saves on integration pains and ensures that there's more than one person who knows what's happening with each commit.

It's the classic "spend a penny, save a pound" investment. More eyes on each piece of code means fewer bugs and fewer headaches down the pipe - and if something looks awry, code review means you have a chance of catching it before it gets merged. Most people don't check in crap on purpose, and it helps to have someone catch when we make mistakes.

I'd love a model that encouraged code review for all our internal contributions too, at least for day to day stuff (maybe not for urgent 2am hotfixes). The only problem is that I'm the only really active developer left with full repository access on KAG, so noone's around to review my code, at least before it hits the repository. I wish that weren't the case.

Instant Messaging is (often) Bad

By Instant Messaging here I mean basically any real-time text-based messaging system, but particularly channel-based group-chat always-on systems like Slack or Discord or Mattermost (or IRC!)

Sure, it's not all bad. It can be really good for hashing out something quickly, or figuring out what someone "really means".

However, a lot of the public development discussion has been happening informally on our community discord, and things really easily get lost or repeated or mixed up with other stuff. A lot of our internal development chatter currently happens on mattermost, which has the same problems, but has fewer voices to talk over each other at least.

I don't have a great solution for this for us... Our forums for bug reports and suggestions aren't great, though we do have templates, and at least forums are threaded. Issues on github would probably be better (?), but most of our players do not have github accounts. We use asana for internal tracking but I don't think there's a way to make it public, and there's a lot on there that's either irrelevant or even shouldn't be seen by a casual bystander. Separate (internal and public) trello boards might work OK for that? Maybe?

However, for projects in general: use one of those task tracking things (ideally have it integrated in your repo like github's issues) and stick to it. Avoid fostering a culture of always being available on IM. Keep discussion threaded where you can, and try to write up summaries of anything that happens in real-time both for people who weren't there, and for yourself in two weeks time.

Others (devs and conventional media) have written about this a lot, so I guess it's maybe common knowledge? Receiving bug reports, feature requests and documentation corrections as incredibly terse PMs from unfamiliar users on an IM platform really hammered this home for me though.

Clean Paper Trails are Good

By a Paper Trail, I mean any easily-accessible documented history of development events. Please don't physically print your git logs!

More information left behind about how, when, and why something was developed? Yes please. This includes basic stuff like meaningful commit messages and not cramming a heap of unrelated changes into one commit or branch/PR - but also includes meta things like tagging releases, keeping discussion on issues an PRs on topic, and making clean changeset summaries. Making it clear what's happening and why is both a boon to your collaborators and your (probably confused, sleep-deprived) future self.

A tag in a repository means that a modder who's code has become incompatible can easily diff the last known working build and the current state of things to see change may be causing them grief. Splitting up changes "properly" rather than cramming them all in at once means that if (when) there's a problem, it's much easier to play detective. All the meta stuff also saves time when someone wants to help out/clarify something/understand what's new, and you have a sane place to link them.

This is something that needs teaching to developers, and could probably be helped by firm, clear guidelines on how to contribute.

Onboarding Contributors is hard

There's a lot to learn. A lot of the code is messy. I just wanted to change that one thing, but now I'm jumping from script to script trying to find a needle in an impossibly large haystack. Surely they've written this down somewhere?!

Discouraged New KAG Contributor, 2017

The frustration above is partly a symptom of a legacy codebase written by average developers in a hurry. It's hard for us to find stuff sometimes! It's also partly a symptom of many of our contributors being gamers with an interest in helping with the code, rather than programmers with an interest in helping with the game.

...Honestly though, it's moreso a symptom of not having to onboard people often, and always having some immediate way to help them through it in the past. We're both out of practice and entering a new paradigm. It's probably time to read more of what others have to say about this. Feel free to hook me up with any good advice of how to handle this!

The next point might help, we'll see.

Documentation is Important

A pattern you might have noticed above is that there's probably not enough about this project in writing. That piece of information you need is often floating about in someone's head.

We do have some formal documentation for some objects, but it's patchy and hard to navigate. We do have some guides and writeups on how to get started, but they might be out of date or written from an outside perspective. We do have "getting started" documentation for working with the internal repositories but they don't touch on the now-open repository much, because it's still "new".

This could all be improved, and having public scrutiny really emphasises where (almost everywhere) and why (because it currently sucks).

Answering the same question multiple times sucks, and dealing with the same misunderstandings multiple times sucks - but I'm sure it sucks even more for the person on the other end who just spent a day scratching their head. Seems like the only way to cure that headache for everyone is to write it down.

This is like the paper-trail point, but less about the business of the day and more about big scope stuff, getting up to speed and how to do something rather than how something was done. Both seem important.

Ideological Differences are Hard

People have opinions. Programming paradigms are a contentious issue, especially in languages that enable a wide spectrum of "expression". Differences in behaviour across cultures can take some getting used to, especially when collaborating remotely. Political and philosophical opinions come up surprisingly often in the workplace, and programmers have a tendency to think that they're right. Tabs vs spaces is a thing.

These issues are manageable in a small, tight knit team talking every day. It gets harder when you have drop in and drop out collaborators, or new collaborators with a lot of baggage, or even collaborators that need to be brought up to speed technically AND might be hard to get along with.

The best way to move forward is probably to have as many of these things as possible codified for your particular project. It's probably also important to carefully choose any long-term contributors not just for their work output but also what they value, and how they collaborate. There seems to be a movement in tech towards this last part, which I hope continues.

Games are Messy, but That's a Bad Excuse

I've honestly been fairly embarrassed writing this. Compared to a comparable-size open source project or anything run by a bigger organisation, our projects have always been pretty slapdash, but I'm aware of a lot of other indies who run things in a similar way.

Moving fast and breaking things is all well and good for prototyping, but this game is now over 6 years old. Dragging that prototyping mentality through a long-term project is counter-productive.

Improvement is Worth It

This seems like a lot to take in at once. To me, it often feels overwhelming, how much work we would need to do to make everything "perfect".

However, Perfect is the enemy of Good. Each step of improvement can make someone's life easier and happier - maybe even mine! If you're reading this and thinking that maybe some of this could help your project, but that it's too much work, just pick whatever seems easiest to tackle. See if it helps. If it does, see what else might help.

Creating Things is Fun

Thankfully, while there's a lot to sort out, the last few months working on KAG has maybe felt a little creative again. It's a been a while.