十字軍之王3開(kāi)發(fā)日志#92 | 4/6 游戲剖析:從報(bào)告問(wèn)題到解決問(wèn)題

牧游社 牧有漢化翻譯
CK3 Dev Diary #92: Anatomy of a Game: From Report to Resolution
jakeowaty, Captain
Hello, everyone, and welcome back the Dev Diary. Let's have a little talk about the Anatomy of a Game (Development)! I'll be your host for today, @jakeowaty, current QA Lead on Crusader Kings 3, and I'm joined by Elisabeth, known as @PDXOxycoon in these here parts - a wonderful programmer, a gentlewoman and a scholar, who you may have seen a few times already! (Editor's note: Can I mention the raw onion story?)
大家好,歡迎回到開(kāi)發(fā)日志。我們來(lái)稍微剖析一下游戲(開(kāi)發(fā))吧!我是今天的主持人@jakeowaty,CK3現(xiàn)任QA主管,另外還有伊麗莎白,也就是@PDXOxycoon,也一同參與,她是一位杰出的程序媛、優(yōu)雅的淑女以及學(xué)者。你們可能已經(jīng)見(jiàn)過(guò)她幾次了?。ň幷咦ⅲ何夷苷f(shuō)說(shuō)那個(gè)生洋蔥的故事嗎?)
Today we are here to tell you about the process a bug goes through from being reported to being resolved and put into an update. Grab yourself the beverage of your choice, and enjoy this little expose on how we go about resolving bugs on Crusader Kings 3!
今天我們想跟大家介紹一下,一個(gè)bug從被報(bào)告上來(lái)到被解決再到更新修復(fù)的歷程。各位拿好心儀的酒水飲料,聽(tīng)聽(tīng)我們講在CK3中修bug的故事吧!

Bug report forum
Bug報(bào)告論壇

Whenever you launch the game, get yourself a your favorite gamer juice and steel your resolve for a few good hours of managing a medieval kingdom, there is a lot of stuff that happened behind the scenes to make it a memorable experience, free from issues. For a game as complex as Crusader Kings 3, this is even more important, and as the features get added to the game, it becomes more and more complicated, like a careful balancing act between economy, AI, warfare, interactions - all to ensure the experience you receive in the newest update is something worth waiting for!
每當(dāng)你打開(kāi)游戲、喝著快樂(lè)水、運(yùn)營(yíng)著中世紀(jì)王國(guó)的時(shí)候,在游戲的幕后都存在著大量的工作,只為了讓你享受到難忘的、不存在問(wèn)題的游戲體驗(yàn)。對(duì)一個(gè)像CK3這么復(fù)雜的游戲來(lái)說(shuō),這就顯得尤為重要。例如,小心翼翼地平衡經(jīng)濟(jì)、AI、福利、交互——一切都是為了確保新版本的游戲體驗(yàn)是值得大家的等待的!
We are but a few humble people, whose job is to find out what works and what doesn’t and report any and all issues to the team before the game hits your platform of choice. But what happens when sometimes issues do remain hidden away and they will take spitting behind your shoulder 3 times on a 3rd fortnight of a 5th month on a leap year, during a full moon while dancing hokey-pokey to uncover?
我們幾個(gè)庸人的職責(zé)是找出哪些運(yùn)行得好、哪些運(yùn)行得不好,然后在游戲登上平臺(tái)發(fā)售之前把所有的問(wèn)題報(bào)告給開(kāi)發(fā)團(tuán)隊(duì)。但是有的時(shí)候仍有問(wèn)題漏網(wǎng),直到很久很久以后才被發(fā)現(xiàn),這可怎么辦呢?
This is where you can come in and help! We can get rid of serious, big issues, find them ahead of time before you even realize they existed in the first place, and try and deliver a polished product. For anything else - well, it's the economy of scale. With the variety of systems, languages, experiences, playstyles - YOU are the biggest help of all, in how a game can be shaped. And for that we have a special platform, called Bug Report Forum, where you can air out your grievances, provide feedback, reproduction steps and situations that irk you on the constant, so that our QA team can go through them much more efficiently and supply the team with a steady stream of new bugs to iron out for the next bug fix patch or release.
如果發(fā)生了這樣的問(wèn)題,你就可以來(lái)找我們幫忙了!我們可以解決嚴(yán)重的大問(wèn)題,在你們還沒(méi)意識(shí)到問(wèn)題存在之前就把它們就出來(lái),嘗試著把產(chǎn)品打磨地更好。除此之外的話,就是規(guī)模效應(yīng)了。這么多的系統(tǒng)、語(yǔ)言、經(jīng)驗(yàn)、玩法——你們才是塑造游戲的過(guò)程中最大的幫手。為此目的,我們有一個(gè)特殊的平臺(tái),叫做Bug報(bào)告論壇,在其中,你們可以發(fā)泄不滿、提供反饋、再現(xiàn)產(chǎn)生問(wèn)題的情景。然后我們的質(zhì)保團(tuán)隊(duì)就可以瀏覽大家的報(bào)告,更加高效地向開(kāi)發(fā)團(tuán)隊(duì)穩(wěn)定地匯報(bào)新bug,為下個(gè)補(bǔ)丁版本解決好問(wèn)題。

Verification
驗(yàn)證

[Comic on logging][關(guān)于記錄日志的漫畫(huà)]
Once you take your valuable time to report the issue that ruins your mojo when playing Crusader Kings, it lands on our Forum as a thread. We then take turns, employing QA power to go through the forums and reproduce them locally on our machines to ensure if the issue is serious, or perhaps we can offer support by providing advice on how to avoid it.
在大家花費(fèi)寶貴的時(shí)間匯報(bào)了破壞游戲體驗(yàn)的bug時(shí),就會(huì)在我們的論壇上形成一個(gè)串兒(帖子)。然后我們就輪流派遣QA人員來(lái)瀏覽論壇,在我們自己的機(jī)器上復(fù)現(xiàn)bug,看看這個(gè)問(wèn)題是否嚴(yán)重;或者,我們也可以向大家提供如何避免問(wèn)題的建議。
Once the ticket is verified internally, using your reproduction steps, your description, screenshots, crash logs and saves, we then take the time to translate it into a language that our internal team can understand - Jira.
一旦我們按照你們的描述、截圖、崩潰日志和存檔成功復(fù)現(xiàn)了報(bào)告的問(wèn)題、形成內(nèi)部ticket之后,就會(huì)將其翻譯為一種只有我們團(tuán)隊(duì)內(nèi)部能夠理解的語(yǔ)言——Jira。
There's an art to this. Jira is an extremely helpful and smart tool to use, and QA by nature becomes naturally adept at using it skillfully. It's usually the QA who does project-wide database evaluations, scrubbing it from obsolete tickets and updating any and all lingering ones to make sure the project team can focus on what's important - making more fun stuff!
這也是有竅門(mén)的。Jira是一個(gè)非常好用的智能工具,而QA人員天生就擅長(zhǎng)使用它。QA常常會(huì)進(jìn)行全項(xiàng)目組范圍內(nèi)的數(shù)據(jù)庫(kù)評(píng)估,把過(guò)時(shí)的ticket清理或者升級(jí)。這樣,項(xiàng)目組才能集中在真正重要的東西之上——制造出更多有趣的東西!
Wait… Obsolete? You mean you just CLOSE old tickets?
等下……過(guò)時(shí)的?你是說(shuō)你們會(huì)把舊的ticket直接關(guān)閉掉?
We do… sometimes. For example, if we had an issue lingering around in some hidden away system for a long time (and sometimes not even you, our community, are able to find it for years on end) - the issue becomes obsolete - either we just make the bug into a feature, or because we change a system entirely - it becomes changed so it's not even a problem anymore. Happens on occasion, and even we are quite surprised that some bugs that linger for long never get picked up by the players, but hey - bugs are features too! Right?
確實(shí)……有時(shí)。打個(gè)比方,假如某個(gè)犄角旮旯的機(jī)制里有個(gè)問(wèn)題藏了很久(有時(shí)候甚至玩家社區(qū)的大家好幾年都發(fā)現(xiàn)不了)——這個(gè)問(wèn)題就成了過(guò)時(shí)的——要不我們直接把bug整合進(jìn)特性里,要么我們完全把機(jī)制改掉了——這個(gè)問(wèn)題也就不再是問(wèn)題了。有時(shí)候我們自己都感到驚訝,有些bug一直存在,玩家卻永遠(yuǎn)發(fā)現(xiàn)不了,那句話怎么說(shuō)來(lái)著——沒(méi)有bug,只有特性嘛!對(duì)吧?
Riiiiiiiiiight…?
對(duì)吧……?

Jira - or how I learned to stop worrying about my mental health and learned to embrace the madness
Jira——我學(xué)會(huì)了不再擔(dān)憂心理健康,而是擁抱瘋狂

[Excerpt from "How to JIRA" guide][“如何JIRA”指南中的節(jié)選]
Now that might look like a lot, but trust me - there's a way to learn this. First of all, it's pretty straight forward; complex, but not complicated. We have been campaigning for the team to use Jira tickets efficiently. For example, if we get a ticket that says "Fix the thing we talked about yesterday" and there is nothing else in it, how can we remember what we have done, what needs to be done and how do we go back to it to retest? And again - fast-forward time to a month later and believe me - nobody will remember what in the world such a ticket meant.
雖然看起來(lái)很難,但是相信我——學(xué)習(xí)的方法也是有的。首先,它很直接、復(fù)雜但不繁復(fù)。我們已經(jīng)讓整個(gè)團(tuán)隊(duì)熟練地使用Jira處理ticket。例如,如果我們收到一個(gè)ticket,上面除了一句“修復(fù)我們昨天提到的那個(gè)東西”就什么都沒(méi)有了,那我們又怎么能記的得之前做了什么、還要做什么、再測(cè)試該怎么進(jìn)行呢?再說(shuō)了——快進(jìn)到一個(gè)月之后,就再也沒(méi)人能看得懂這個(gè)ticket到底說(shuō)的是啥了。
As a result, making sure all the fields are appropriately filled out is paramount to an efficient use of the database, and to make our team's lives just a little bit easier when having to deal with a big pile of bugs that come from you or from our internal reporting.
因此,將所有的框框都正確地填滿,對(duì)數(shù)據(jù)庫(kù)的高效使用是至關(guān)重要的,也讓我們團(tuán)隊(duì)處理來(lái)自大家和來(lái)自?xún)?nèi)部的大量bug的工作稍微簡(jiǎn)單了一點(diǎn)點(diǎn)。
If everything is sorted, and everyone is on the same page, it makes it a lot easier for the producers to schedule when and how to report. And the upvoting on the forum? That's an incredibly powerful tool to let us know which tickets need to be prioritized and fixed, no matter what. That's how we can influence what is important to be fixed first.
如果所有東西都分好類(lèi)了,所有人說(shuō)話在同一個(gè)頻道上,會(huì)對(duì)處理者安排報(bào)告的時(shí)間和方式有很大幫助。那在論壇里點(diǎn)贊頂帖呢?這種方式可以很好地幫助我們知道哪些東西需要優(yōu)先處理和修復(fù)。我們可以通過(guò)這種方式影響需要優(yōu)先處理的事項(xiàng)。

[QA chasing the Programmers]
[QA追著程序員]

The (un)lucky Programmer/Designer
(不)幸運(yùn)的程序員/設(shè)計(jì)師
Once the bug has been verified, put into Jira, assigned a version and prioritized, a Developer can pick the bug up for fixing. This is typically either a Designer or a Programmer, depending on where the bug originates. In some cases the bug is reassigned to another role if the bug is found to be caused in another part of the game. Now that we know what the issue is and how it's experienced, we need to investigate the how and why it happens.
當(dāng)確認(rèn)bug后,放進(jìn)Jira,分配版本并優(yōu)先處理,開(kāi)發(fā)者會(huì)拿到bug并開(kāi)始處理。有可能是設(shè)計(jì)師或者程序員來(lái)處理,取決于bug是怎么產(chǎn)生的。有時(shí)候,如果bug是其他部分原因產(chǎn)生的,bug會(huì)被重新分配給其他人。現(xiàn)在我們知道了問(wèn)題是什么和其效果,就需要調(diào)查它怎么樣和為什么發(fā)生。
As an example of this, let us look at the recently fixed issue where the Holy Orders would raise themselves and immediately disband if they were called into a war. This issue was a side effect of letting Holy Orders raise themselves for Great Holy Wars: whenever a Holy Order is at war as an ally (which they qualify as during the Great Holy Wars), they would raise their armies.
下面是一個(gè)例子,讓我們瞧瞧最近修復(fù)的“如果騎士團(tuán)被召入戰(zhàn)爭(zhēng),會(huì)召集并立即解散自己”的問(wèn)題。這個(gè)問(wèn)題是騎士團(tuán)為大圣戰(zhàn)召集自己的副作用:當(dāng)騎士團(tuán)作為戰(zhàn)爭(zhēng)中盟友時(shí)(在大圣戰(zhàn)中符合這一條件),會(huì)召集自己的軍隊(duì)。
We start by looking at why the Order is disbanding the armies. If they're raised, they must have something to fight against, right?
首先我們看看為什么騎士團(tuán)會(huì)解散自己的軍隊(duì)。他們都集結(jié)起來(lái)了,肯定需要和什么東西打一仗,對(duì)不對(duì)?

[Code controlling if a order's armies should be disbanded][控制騎士團(tuán)解散軍隊(duì)的代碼]
Through developer magic known as debug mode and source code, we can step through each individual function call to see what's going on. Stepping through this function leads us to finding that the war they are fighting in is not relevant to them, causing them to disband. Looking at the enemies in the war they're in, none of them are of a hostile Faith. We also see that they are hired by the Grandmaster of the Order, so the Order itself decided to raise their armies, not another character hiring them.
通過(guò)開(kāi)發(fā)者神奇的調(diào)試模式和源代碼,我們可以遍歷所有函數(shù),看看發(fā)生甚么事了。通過(guò)遍歷,我們發(fā)現(xiàn)他們正在進(jìn)行的戰(zhàn)爭(zhēng)和他們無(wú)關(guān),所以他們解散了??纯此麄兘粦?zhàn)的敵人,沒(méi)有一個(gè)是敵對(duì)信仰的。我們同時(shí)發(fā)現(xiàn)他們被騎士團(tuán)大團(tuán)長(zhǎng)雇傭,所以騎士團(tuán)自己決定集結(jié),而不是其他雇傭他們的人。
Holy Orders will not fight in wars where the opposing side does not have any participants of hostile Faith. Because we found the Holy Order disbanding due to being raised against an irrelevant enemy, we must look at the logic which controls how they are raised.
騎士團(tuán)不會(huì)參加沒(méi)有任何敵軍是敵對(duì)信仰的戰(zhàn)爭(zhēng)。因?yàn)槲覀儼l(fā)現(xiàn)騎士團(tuán)因?yàn)楸徽偌瘜?duì)抗不相關(guān)敵軍而解散,我們必須檢查控制其被征召的邏輯。
I will spare you the initial dig down the AI code, but the short of it is: if a Holy Order can be raised, raise it. So we need to see why the Holy Order can be raised when it clearly should not be able to. We arrive at the following function.
我會(huì)挑出挖到的原始AI代碼,但簡(jiǎn)要概括:如果騎士團(tuán)可被召集,便進(jìn)行召集。所以我們需要研究為什么騎士團(tuán)會(huì)在顯然不應(yīng)該被召集的情況下可被召集??匆韵潞瘮?shù)。

[Code to check the Holy Order can be hired by a Character][檢查騎士團(tuán)可被角色雇傭的代碼]
This logic checks if the Order can be hired by a character. This goes for any character looking to use the Order in question, even the Grandmaster of the Order. The Grandmaster of the Order is part of the war, so let us see where it leads us. Starting from the top, we check if the character can use the Order. Let us take a look at how that goes.
這是檢查騎士團(tuán)可被角色雇傭的邏輯。這會(huì)檢查所有希望雇傭騎士團(tuán)的人,甚至包括騎士團(tuán)大團(tuán)長(zhǎng)。騎士團(tuán)大團(tuán)長(zhǎng)是戰(zhàn)爭(zhēng)的一部分,所以讓我們看看這會(huì)導(dǎo)致什么。從最上面開(kāi)始,我們檢查角色是否可使用騎士團(tuán)。讓我們看看這怎么進(jìn)行。

[Code to check if a character can use the Holy Order][檢查角色是否可使用騎士團(tuán)的代碼]
This is the code that checks if a character can use a Holy Order. When the Holy Order joins a war on its own, pCharacter is the Grandmaster, which is the Owner of the Holy Order. Makes perfect sense that the Grandmaster can make use of his own Holy Order. But, make notice further down: there is a check there, verifying if the character is in a relevant war. This is the same function that caused the army to disband earlier.
這段代碼檢查角色是否可使用騎士團(tuán)。當(dāng)騎士團(tuán)自己加入戰(zhàn)爭(zhēng)時(shí),pCharacter是騎士團(tuán)的所有者大團(tuán)長(zhǎng)。理所當(dāng)然大團(tuán)長(zhǎng)可以使用自己的騎士團(tuán)。但是,繼續(xù)向下看:這有個(gè)檢查,確認(rèn)角色是否在相關(guān)的戰(zhàn)爭(zhēng)中。這同樣是導(dǎo)致軍隊(duì)提前解散的函數(shù)。
Returning back to the function which checks if a Holy Order can be hired by our Grandmaster.
返回到檢查騎士團(tuán)是否可以被我們的大團(tuán)長(zhǎng)雇傭的函數(shù)。

[Code to check the Holy Order can be hired by a Character 2][檢查騎士團(tuán)是否可以被大團(tuán)長(zhǎng)雇傭的代碼 2]
To simplify things, I have collapsed all the irrelevant parts; contained within each "if" section is something which will cause the function to fail, and not allow the Grandmaster to hire their own Order. Let's go through these relevant parts. We don't run afoul with the hire limit, as we don't hire any other Holy Orders as the Grandmaster of one. We are not already hired by someone else, so we skip that part. We own this order, so we don't touch the third "if" statement. Finally, we can afford to hire our own Order. Look at that, this means we can hire the Holy Order!
為簡(jiǎn)便起見(jiàn),我折疊了所有不相關(guān)的部分;每個(gè)“if”里包括了導(dǎo)致函數(shù)失效,不允許大團(tuán)長(zhǎng)雇傭自己騎士團(tuán)的條件。讓我們看看有關(guān)的部分。雇傭限制沒(méi)有沖突,因?yàn)闆](méi)有雇傭除了大團(tuán)長(zhǎng)的騎士團(tuán)外的騎士團(tuán)。我們沒(méi)有被其他人雇傭,所以跳過(guò)這部分。我們擁有這個(gè)騎士團(tuán),所以不觸發(fā)第三個(gè)“if”。最終,我們可以負(fù)擔(dān)得起雇傭自己的騎士團(tuán)??纯窗?,這意味著我們可以雇傭這個(gè)騎士團(tuán)!
But returning back to the finding that the Holy Order would immediately disband because we're not in a relevant war. This is where we find our solution: if we own our own Holy Order, we can always use it, but because of this we will not look if the war we are in is relevant at all. So we have a very simple solution to the problem.
但回到發(fā)現(xiàn)騎士團(tuán)會(huì)因?yàn)樘幱诓幌嚓P(guān)的戰(zhàn)爭(zhēng)而立即解散的問(wèn)題。我們?cè)谶@里發(fā)現(xiàn)了答案:如果我們擁有自己的騎士團(tuán),我們總是可以使用它,因此我們不會(huì)檢查戰(zhàn)爭(zhēng)是否與我們相關(guān)。所以對(duì)這個(gè)問(wèn)題,我們有一個(gè)非常簡(jiǎn)單的解決方案。

[Solution to preventing the Holy Order from being raised][防止騎士團(tuán)被召集的解決方案]
We know that the check for relevant wars is only skipped if we are the Grandmaster of the Order, we don't need to check the faith of our own Grandmaster, so this is what we're left with: if the one who wants to hire the Holy Order is the Owner of the Order, check if they are in a relevant war or not.
我們知道跳過(guò)檢查戰(zhàn)爭(zhēng)相關(guān)性?xún)H會(huì)在我們是騎士團(tuán)大團(tuán)長(zhǎng)的情況下跳過(guò),我們不需要檢查自己大團(tuán)長(zhǎng)的信仰,所以我們?cè)谶@里增加了:如果希望雇傭騎士團(tuán)的人是騎士團(tuán)的所有者,檢查他們是否在相關(guān)的戰(zhàn)爭(zhēng)中。

The merge request process - everyone judges you
合并請(qǐng)求的過(guò)程——所有人都要評(píng)判你
When the fix has been created, it is put into what is called the merge request; this is the step before the fix is put into the upcoming build. Before it gets merged, there are a bunch of steps. It starts with one or more members of the team of appropriate discipline reviewing the changes being applied. This is the first step to spotting any unintended side effects that may occur with any given fix. The scrutiny of these reviews increase drastically with several more steps if the fix will go into an upcoming release.
當(dāng)bug修復(fù)被制作完成后,會(huì)將其放入一個(gè)叫合并請(qǐng)求的東西里。這是把修正加入未來(lái)補(bǔ)丁前的步驟。在合并前,有好幾個(gè)步驟。剛開(kāi)始是團(tuán)隊(duì)的一到多名相關(guān)專(zhuān)業(yè)成員審核改變了的內(nèi)容。這是發(fā)現(xiàn)任何可能產(chǎn)生的無(wú)意的副作用的第一步。如果修正在即將發(fā)布的版本內(nèi),那么審核力度將大幅增加,并會(huì)多幾個(gè)步驟。

[Merge request overview for Preventing Holy Orders from raising themselves in irrelevant wars][防止騎士團(tuán)在無(wú)關(guān)戰(zhàn)爭(zhēng)中自行出征的合并請(qǐng)求概覽]
Merge requests have a template that must be filled in when filed. This process gives both the fixer and reviewer the chance to review the implications of a fix and whether or not to actually commit it to a particular version. We make a serious consideration on how risky a fix is, can the fix have unintended knockon effects and the like, and how it impacts the overall performance of the game, does the fix contain a lot of computationally heavy code or script that will degrade performance.
提交合并請(qǐng)求時(shí)有必須要填寫(xiě)的模板。這個(gè)流程給修復(fù)擔(dān)當(dāng)和審閱擔(dān)當(dāng)?shù)墓ぷ魅藛T查詢(xún)修復(fù)應(yīng)用方法,以及是否按某一版解決方法執(zhí)行。我們會(huì)針對(duì)修復(fù)的潛在風(fēng)險(xiǎn)進(jìn)行嚴(yán)格把控,包括這樣是否有計(jì)劃之外的效果等問(wèn)題,以及游戲整體運(yùn)行會(huì)受什么影響、是否包括了會(huì)降低運(yùn)行性能的大量硬編碼或編程內(nèi)容。
The golden rules of managing a merge request are:
處理整合請(qǐng)求時(shí)的基本法則如下:
1. Reviewer is right until proven wrong.
1、審核員被證明出錯(cuò)前,他說(shuō)啥都是對(duì)的
2. Discipline leads are always right.
2、管理組長(zhǎng)永遠(yuǎn)是對(duì)的。
Adding a fix to a build generally requires approval from the discipline lead, tech lead and another reviewer, and only the tech lead can actually merge the fix into the build when we’re getting close to release.
要給某版本添加修復(fù)通常需要管理組長(zhǎng)、技術(shù)組長(zhǎng)和另一位審核人員的同意,而且接近發(fā)布前能實(shí)際將修復(fù)內(nèi)容添加進(jìn)版本中的也只有技術(shù)組長(zhǎng)。

[The commit fixing the issue][交付的問(wèn)題修復(fù)]
The reviewer(s) give feedback on the merge request, and these must be addressed in one way or another. In the overview, you can see that the fix ended up being five commits in total, where just one of them was the fix itself. The rest were either addressing comments made in the review process or issues raised by the automated build and testing system, which we call pipelines. Speaking of pipelines.
審核員(們)會(huì)對(duì)合并請(qǐng)求提出反饋,并以某種形式進(jìn)行處理。總體來(lái)說(shuō),你會(huì)發(fā)現(xiàn)最后共提交了5份內(nèi)容,但真正的修復(fù)只有一個(gè)。其他的要么是回復(fù)審核流程中的評(píng)論或者是自動(dòng)編制與測(cè)試系統(tǒng)提出的問(wèn)題,我們稱(chēng)之為流水線。

[Pipeline for merge request][合并請(qǐng)求的流水線]
Pipelines verify the integrity and quality of the code, build the game and test the game while the review process is going. All of these must pass for the merge request to be allowed to merge, unless explicit permission is given from the programmers, and in the case of an upcoming release the pipelines must be green. No exceptions.
流水線會(huì)核實(shí)代碼、游戲版本的完整性與質(zhì)量,并在審核流程進(jìn)行時(shí)測(cè)試游戲。所有流程通過(guò)后才能允許合并請(qǐng)求實(shí)際進(jìn)行合并,除非程序員專(zhuān)門(mén)給了許可。而即將發(fā)布的內(nèi)容則要求流水線全程達(dá)標(biāo),絕無(wú)例外。
Once the fix has been merged, we hand it back over to the sadistic wonderful QA team.
修復(fù)內(nèi)容被合并后,便交付給高效而嚴(yán)酷的QA組。

The (sadistic) QA verification - where QA asks the fixer: “why are you running?!”
QA組(殘酷的)核實(shí)流程——QA問(wèn)修復(fù)員:你為啥要跑?。?/strong>

[Happy tears from QA after a 2 year old issue was resolved][歷經(jīng)兩年的一個(gè)問(wèn)題終于修復(fù)后,QA留下了幸福的淚水]
Once a ticket gets processed, churned through the complicated development machine, the issue is removed from the game, the correct code, script or asset gets merged into the game, the ticket is then marked as resolved.
在某個(gè)ticket獲得處理、歷經(jīng)繁瑣的開(kāi)發(fā)流程后,便會(huì)移除游戲內(nèi)的問(wèn)題,讓正確的代碼、腳本或素材融入游戲,最后將這一單標(biāo)為已解決。
This is when we get our hands on it one more time to verify if the fix has not only resolved the issue listed therein, but also that it has no other knock-on effects. Think of big fixes like a domino - you push one piece and the others will fall. Sometimes a different set of dominos, that we set up a long time ago, gets randomly pushed and some older issues reappear out of nowhere. It happens when you deal with a complex codebase, in which case you sometimes do see returning fan favorites.
在此我們又有一次機(jī)會(huì)來(lái)驗(yàn)證修復(fù)內(nèi)容是否解決了相應(yīng)問(wèn)題,而且沒(méi)有帶來(lái)什么連鎖效果。大型修復(fù)就像是一套多米諾骨牌,推倒一塊必然會(huì)讓后面的也倒下。有時(shí)候可能是很久以前碼好的不同套牌,莫名受什么影響挨碰了,然后某些老問(wèn)題又突然回來(lái)了。這種情況會(huì)在處理繁瑣的代碼庫(kù)時(shí)出現(xiàn),因此有時(shí)某些廣為玩家喜愛(ài)的bug會(huì)唐突返場(chǎng)。
But all we have to do is revisit the older system, fix it (again), and away we go! Unless yet another bug is retriggered, in which case… Well, we have to revisit yet another system. Videogames are hard, m'kay?
但我們要做的也就是重查舊系統(tǒng)、(又雙叒叕)修復(fù),然后實(shí)裝!除非又有其他bug出現(xiàn),好吧……我們就得再重查另一個(gè)系統(tǒng)了。電子游戲開(kāi)發(fā)很難的好吧。
This is why we sometimes need to go through the same ticket again, and again, and again, until we are very sure it fixes more things than it breaks. Sometimes bugs linger in our database for a long time. Trust us - we know that issues you mentioned on release still persist and we want to fix everything, but with every release we get a new batch of tickets we have to go through…
這也是有時(shí)要反復(fù)翻出舊帖的原因,直到能確定修復(fù)的內(nèi)容多過(guò)改崩的部分。有時(shí)候某些bug會(huì)在數(shù)據(jù)庫(kù)里存活很久。請(qǐng)理解,我們知道大家提到的發(fā)布時(shí)就有的問(wèn)題還在,我們也想把所有內(nèi)容都改好,但每一次發(fā)布都會(huì)新加一大堆要看的帖子……
So.
Many.
Times.
However, once the fix is confirmed, and the build is locked in - we are ready to press the large green button and release it for your scrutiny and repeat aforementioned hokey-pokey jig again!
猴
多
次!
不過(guò)在確認(rèn)修復(fù)補(bǔ)訂并保證版本穩(wěn)定后,我們就會(huì)著手按下綠色按鈕發(fā)布,并由各位玩家仔細(xì)審查,然后再照前文那套流程再搞一遍!

The Update - Are we done yet?
更新——做好了嘛?
Not really. On our end we close the bug as resolved, but there is one last thing that comes into play on resolving a bug. This is all of you, the community. The QA team catches most of the problems before a release is made, but sometimes for an issue to reoccur, you need the stars to align on a laptop manufactured on 29th of February 2020 while the player is doing the Macarena.
沒(méi)完全好。我們這邊還沒(méi)確定bug都解決了,不過(guò)修復(fù)bug這套流程里還有一個(gè)要素,就是各位玩家——我們的社群。QA組會(huì)在發(fā)布前盡量查清所有問(wèn)題,但有時(shí)候要查明某個(gè)問(wèn)題,需要“行星與2020年2月29日產(chǎn)筆記本電腦成一線且玩家正玩著二人轉(zhuǎn)”這種級(jí)別的天時(shí)地利人和。
Paraphrasing, of course, but there are cases where an issue can reemerge later. This can happen due to a myriad of factors that are hard to account for. Some issues can be related to hardware and specific circumstances we don't have the capacity to test for. This is when we rely on you all to be vigilant and report issues back to us. The more detailed and specified, the better. Once this is done we go back from the top of this expose and do the dance one more time.
例子舉得有點(diǎn)歪,不過(guò)有時(shí)某些問(wèn)題可能之后才會(huì)復(fù)現(xiàn),可能是由一坨難以考量的因素所致。有些問(wèn)題可以與硬件或其他我們無(wú)法滿足測(cè)試條件的特定情況掛鉤,所以這時(shí)我們才會(huì)依靠諸位玩家打起精神提供問(wèn)題反饋,越詳細(xì)具體越好。之后,我們會(huì)從頭整理發(fā)現(xiàn)的問(wèn)題并再來(lái)一遍整個(gè)流程。
If no one in the community experiences the issue again, then it stays resolved.
如果社群內(nèi)沒(méi)有其他人再遇到這個(gè)問(wèn)題,那么它就歸檔為已解決。
I hope you all have enjoyed this little expose into the life of a game developer! Thank you for your time, and we wish you a very pleasant day.
希望大家中意本次游戲開(kāi)發(fā)者的小揭底!謝謝大家來(lái)看日志,祝日安!
Until next time!
下周再見(jiàn)!
翻譯:一個(gè)幽靈 毛里求斯大酋長(zhǎng) zzztotoso
校對(duì):三等文官猹中堂
歡迎關(guān)注UP主和主播小牧Phenix!
歡迎關(guān)注牧游社微信公眾號(hào)和知乎專(zhuān)欄!微信公眾號(hào)改版為信息流,歡迎【置頂訂閱】不迷路,即時(shí)獲得推送消息!
B站在關(guān)注分組中設(shè)置為【特別關(guān)注】,將會(huì)在私信內(nèi)及時(shí)收到視頻和專(zhuān)欄投稿的推送!
歡迎加入牧有漢化, 致力于為玩家社群提供優(yōu)質(zhì)內(nèi)容!組員急切募集中!測(cè)試群組822400145!??
本作品英文原文著作權(quán)屬Paradox interactive AB所有,中文譯文著作權(quán)屬牧有漢化所有。