An essay on how previously squashed bugs become unsquashed.
We start with basic software version control. As software engineers, we like to be able to keep track of the work that we've done. We like to be able to see what changed between versions of code, and sometimes we prefer to make changes away from the main development because they might be lengthy or experimental and prone to breaking, and it's somewhat unfair if everyone is making changes and constantly breaking the build for everyone else. So we have the concept of branch-and-merge. Depending on your version control software, the ease of use and level of automation will vary.
The terminology for branching comes from that of a tree. The main thrust of development is on what's known as the trunk. If you want to get the latest and greatest you'll be picking up the HEAD revision, which is generally on the trunk (but not always) and generally expected to build (but not always). If you want to make a change away from the trunk -- which is what will often happen with bugfixes -- you take what's effectively a snapshot of the code and 'branch' it off. The work you're doing is now only visible on that branch. Branches can still be shared between developers, so if you're implementing a feature that requires modifications to code, scripts, assets, etc. all stakeholders can do their work on that branch. Branches can be branched. When you're done making your changes, you've tested your branch (hah!) you 'merge' it back into its parent branch (which could be the trunk). This process is hard to automate because while you were making your change, the parent branch has probably moved on. If someone else has done work on code (etc.) that you've touched, your version control software will metaphorically throw its hands up and say "I don't know how to resolve this, because both of you have changed the same thing". This requires manual intervention, so the developer will have to attempt to sew the two sets of changes together by hand. Ugh.
So, software is this big complex thing that lots of teams are working on and trampling all over. But it gets more complex. When, say, Frontier released version 2.1 of Horizons, they will have taken a snapshot of that release and called it a 'release branch'. The main software thrust continues but there's a chance that someone will spot a bug that needs to be fixed in the released version of code. But not only that, the fix will need to be introduced into the mainline code also. So the developer needs to decide first whether to make the change on the release branch and merge that fix into mainline, or to do the work on mainline and merge into the release branch. They'll probably pick the former as mainline might have moved on a lot. In some cases the bugfix may not even apply to mainline due to refactoring (reimplementing something to make it better or cleaner) or the bug may have moved around.
There are many things that can now go wrong, because there's a human involved. They might forget to merge the bugfix that's present on the release branch into the mainline trunk. So when the next release comes, voila! the bug is back. They might merge the fix, but in the meantime someone has copied and pasted the offending code elsewhere, and voila! the bug is back (albeit maybe slightly differently). They might do the fix correctly in both places, but someone else might merge their branch (which still contains the bug) back, encounter a conflict and their manual merge might trample all over the bugfix and voila! the bug is back.
The way to catch this happening (because you can't stop it) is to implement a good set of regression tests for bugs. Write a test (preferably automated) that fails if the bug is still present. Unfortunately this is hard, requires a very structured approach to software development -- difficult when you're deadline driven -- and still doesn't cover every contingency, such as the case where a copy-paste proliferates the bug. [Obviously in this case, the developer doing the copy-paste probably ought to have factored that code into a function and so the bug fix would have applied everywhere, but again when working to deadlines sometimes the instinct to do it quickly can override the instinct to do it right.]
All I can say is that bugs happen. They can be esoteric, hard to track down (or really obvious once you've found them) and especially so in software as complex as this. I'm happy to criticise the SC project for its failures, but I *will* sympathise with their developers who are doing a hard job and where their mistakes are seen and mocked by the world.