산소미포함(Oxygen not included) 작업 할당 시스템

작업 할당 시스템 분석

목차


시스템 개요

복제체가 작업을 선택하고 수행하는 시스템은 다음과 같은 흐름으로 동작합니다:

  1. 작업 수집ChoreProvider들이 게임 세계에서 사용 가능한 작업들을 제공
  2. 전제조건 검사: 각 작업에 대해 복제체가 수행 가능한지 전제조건(Precondition) 검사
  3. 우선순위 비교: 전제조건을 통과한 작업들을 우선순위에 따라 정렬
  4. 작업 선택: 가장 높은 우선순위의 작업 선택
  5. 작업 수행ChoreDriver가 선택된 작업을 실행

핵심 컴포넌트

Chore (작업)

  • 게임 내 모든 작업의 추상 기본 클래스
  • 우선순위 설정, 전제조건, 실행 로직을 포함
  • 각 작업은 고유한 ID를 가짐

ChoreConsumer (작업 소비자)

  • 복제체에 부착된 컴포넌트
  • 사용 가능한 작업을 찾고 선택하는 역할
  • FindNextChore() 메서드로 다음 작업을 찾음

ChoreDriver (작업 실행자)

  • 복제체에 부착된 컴포넌트
  • 선택된 작업을 실제로 실행하는 역할

ChoreProvider (작업 제공자)

  • 게임 세계의 객체들에 부착된 컴포넌트
  • 사용 가능한 작업들을 제공
  • 예: 건물, 저장소, 작업 가능한 객체 등

ChoreType (작업 타입)

  • 작업의 타입을 정의
  • 각 작업 타입은 고유한 우선순위 값을 가짐
  • Database/ChoreTypes.cs에서 모든 작업 타입이 정의됨

작업 선택 프로세스

1. 작업 수집 단계

// ChoreConsumer.FindNextChore()
for (int i = 0; i < providers.Count; i++)
{
    providers[i].CollectChores(consumerState, 
        preconditionSnapshot.succeededContexts, 
        preconditionSnapshot.failedContexts);
}

모든 ChoreProvider로부터 사용 가능한 작업들을 수집합니다.

2. 전제조건 검사

각 작업에 대해 전제조건(Precondition)을 검사합니다:

  • 작업 수행 가능 여부
  • 복제체가 해당 작업을 수행할 수 있는지
  • 필요한 자원이나 조건이 충족되는지
  • 이동 비용 계산

3. 우선순위 정렬

전제조건을 통과한 작업들은 Chore.Precondition.Context.CompareTo() 메서드를 사용하여 정렬됩니다.

4. 작업 선택

정렬된 목록에서 가장 높은 우선순위의 작업을 선택합니다.


우선순위 시스템

우선순위 비교 순서

작업 선택 시 다음 순서로 우선순위를 비교합니다:

  1. 전제조건 실패 여부 (failedPreconditionId)
    • 전제조건을 통과한 작업이 우선
  2. 마스터 우선순위 클래스 (masterPriority.priority_class)
    • idle < basic < high < personalNeeds < topPriority < compulsory
  3. 개인 우선순위 (personalPriority)
    • 복제체별로 설정된 작업 그룹별 우선순위 (0-5)
    • 높을수록 우선
  4. 마스터 우선순위 값 (masterPriority.priority_value)
    • 작업에 직접 설정된 우선순위 값 (1-9)
  5. 작업 타입 우선순위 (priority)
    • 작업 타입의 고유 우선순위 값
    • "근접 활성화"가 꺼져 있으면: choreType.priority (암시적 우선순위)
    • "근접 활성화"가 켜져 있으면: choreType.explicitPriority (명시적 우선순위, 기본값 5000)
  6. 우선순위 수정자 (priorityMod)
    • 작업별 추가 우선순위 보정값
  7. 소비자 우선순위 (consumerPriority)
    • 복제체별 추가 우선순위 보정값
  8. 비용 (cost)
    • 이동 비용 등 (낮을수록 우선)
  9. 작업 ID (chore.id)
    • 동일한 우선순위일 경우 작업 ID로 결정 (낮을수록 우선)

마스터 우선순위 클래스 (Master Priority Class)

마스터 우선순위 클래스는 작업의 대분류를 나타냅니다:

클래스설명
idle-1대기 상태
basic0기본 작업
high1높은 우선순위
personalNeeds2개인 필요 (식사, 수면 등)
topPriority3최우선 작업
compulsory4강제 작업

개인 우선순위 (Personal Priority)

  • 각 복제체별로 작업 그룹(Chore Group)에 대해 설정 가능한 우선순위
  • 범위: 0-5 (높을수록 우선)
  • 우선순위 화면에서 설정 가능
  • 작업 타입 우선순위보다 먼저 비교됨

작업 타입 우선순위

암시적 우선순위 (Implicit Priority)

  • nextImplicitPriority 변수로 관리
  • 초기값: 10000
  • 작업 타입이 추가될 때마다 50씩 감소
  • skip_implicit_priority_change: true인 작업은 감소하지 않음

명시적 우선순위 (Explicit Priority)

  • 대부분의 일반 작업: 5000
  • "근접 활성화"가 켜져 있을 때 사용됨

근접 활성화 (Proximity Enable)

위치

  • 우선순위 화면 (Jobs Table Screen)에서 "근접 활성화" 토글 버튼
  • JobsTableScreen.OnAdvancedModeToggleClicked() 메서드로 제어
  • Game.Instance.advancedPersonalPriorities 변수로 저장

동작 방식

근접 활성화 꺼짐 (기본 모드):

priority = chore.choreType.priority;  // 암시적 우선순위 사용

근접 활성화 켜짐 (고급 모드):

priority = chore.choreType.explicitPriority;  // 명시적 우선순위 사용 (대부분 5000)

효과

  • 근접 활성화 꺼짐: 작업 타입별로 다른 우선순위 값 사용 (10000부터 50씩 감소)
  • 근접 활성화 켜짐: 대부분의 작업이 동일한 우선순위(5000)를 가지므로, 거리(비용)가 더 중요한 요소가 됨

중요 사항

  • explicitPriority는 개인 우선순위를 무시하지 않습니다
  • 개인 우선순위는 작업 타입 우선순위보다 먼저 비교되므로 항상 우선 적용됩니다
  • explicitPriority는 단지 작업 타입 우선순위 비교 단계에서 사용되는 값일 뿐입니다

작업 타입별 우선순위 목록

최고 우선순위 작업 (10000-6200)

작업 타입priorityexplicitPriority설명
Die1000010000사망
Entombed99509950매몰됨
SuitMarker99009900수트 마커
Slip98509850미끄러짐
Checkpoint98009800체크포인트
TravelTubeEntrance97509750이동 튜브 입구
WashHands97009700손 씻기
HealCritical96509650긴급 치료
BeIncapacitated96009600무능력 상태
WaterDamageZap95509550물 피해 감전
BeOffline95009500오프라인
GeneShuffle94509450유전자 셔플
Migrate94009400이주
DebugGoTo93509350디버그 이동
MoveTo93009300이동
RocketEnterExit92509250로켓 출입
DropUnusedInventory92009200미사용 인벤토리 버리기
FindOxygenSourceItem_Critical91509150산소 공급원 찾기 (긴급)
BionicAbsorbOxygen_Critical91009100생체공학 산소 흡수 (긴급)
ExpellGunk90509050덩어리 배출
Pee90009000소변
RecoverBreath89508950호흡 회복
RecoverWarmth89008900따뜻함 회복
RecoverFromHeat88508850열기에서 회복
Flee88008800도망
MoveToQuarantine87508750격리소로 이동
EmoteIdle87008700감정 표현 (대기)
Emote86508650감정 표현
EmoteHighPriority86008600감정 표현 (높은 우선순위)
StressEmote85508550스트레스 감정 표현
Hug85008500포옹
StressVomit84508450스트레스 구토
UglyCry84008400우는 소리
BansheeWail83508350비명
StressShock83008300스트레스 쇼크
BingeEat82508250폭식
StressActingOut82008200스트레스 행동
Vomit81508150구토
Cough81008100기침
RadiationPain80508050방사선 통증
SwitchHat80008000모자 교체
StressIdle79507950스트레스 대기
RescueIncapacitated79007900무능력자 구조
BreakPee78507850긴급 소변
Eat78007800식사
ReloadElectrobank77507750전기뱅크 재충전
SeekAndInstallUpgrade77007700업그레이드 찾기 및 설치
OilChange76507650오일 교체
SolidOilChange76007600고체 오일 교체
BionicAbsorbOxygen75507550생체공학 산소 흡수
FindOxygenSourceItem75007500산소 공급원 찾기
Narcolepsy74507450기면증
ReturnSuitUrgent74007400수트 반환 (긴급)
SleepDueToDisease73507350질병으로 인한 수면
BionicRestDueToDisease73007300질병으로 인한 생체공학 휴식
Sleep72507250수면
TakeMedicine72007200약 복용
GetDoctored71507150의사 진료 받기
RestDueToDisease71007100질병으로 인한 휴식
BionicBedtimeMode70507050생체공학 취침 모드
ScrubOre70007000광석 세척
DeliverFood69506950음식 배달
Sigh69006900한숨
Heal68506850치료
Shower68006800샤워
LearnSkill67506750기술 학습
UnlearnSkill67006700기술 잊기
Equip66506650장비 착용
JoyReaction66006600기쁨 반응
RocketControl65506550로켓 제어
Fart65006500방귀
StressHeal64506450스트레스 치유
Party64006400파티
Relax63506350휴식
Recharge63006300재충전
Unequip62506250장비 해제
Mourn62006200애도
TopPriority61506150최우선

명시적 우선순위 5000 작업들

다음 작업들은 모두 priority 값이 다르지만 explicitPriority = 5000으로 통일되어 있습니다:

작업 타입priorityexplicitPriorityskip설명
Attack61005000공격
Doctor60505000의사
Toggle60005000토글
Capture59505000포획
CreatureFetch59005000생물 가져오기
RanchingFetch58505000목축 물품 가져오기
EggSing58005000알에 노래하기
Astronaut57505000우주비행사
FetchCritical57005000긴급 가져오기
Art56505000예술
EmptyStorage56005000저장소 비우기
Mop55505000청소
Relocate55005000재배치
Disinfect54505000소독
Repair54005000수리
RepairFetch53505000수리 물품 가져오기
Deconstruct53005000철거
Demolish52505000파괴
Research52005000연구
AnalyzeArtifact51505000유물 분석
AnalyzeSeed51005000씨앗 분석
ExcavateFossil50505000화석 발굴
ResearchFetch50005000연구 물품 가져오기
GeneratePower49505000전력 생성
CropTend49005000작물 돌보기
PowerTinker48505000전력 정비
RemoteOperate48005000원격 조작
MachineTinker47505000기계 정비
MachineFetch47005000기계 물품 가져오기
Harvest46505000수확
FarmFetch46005000농업 물품 가져오기
Uproot45505000뿌리 뽑기
CleanToilet45005000화장실 청소
EmptyDesalinator44505000담수화기 비우기
LiquidCooledFan44005000액체 냉각 팬
IceCooledFan43505000얼음 냉각 팬
Train43005000훈련
ProcessCritter42505000생물 가공
Cook42005000요리
CookFetch41505000요리 물품 가져오기
DoctorFetch41005000의료 물품 가져오기
Ranch40505000목축
PowerFetch40005000전력 물품 가져오기
FlipCompost39505000퇴비 뒤집기
Depressurize39005000감압
FarmingFabricate38505000농업 제조
PowerFabricate38005000전력 제조
Compound37505000약제 제조
Fabricate37005000제조
FabricateFetch36505000제조 물품 가져오기
FoodFetch36005000음식 가져오기
Transport35505000운반
Build35005000건설
BuildDig34505000건설용 채굴
BuildUproot34005000건설용 뿌리 뽑기
BuildFetch33505000건설 물품 가져오기
Dig33005000채굴
Fetch32505000가져오기
StorageFetch32005000저장소 가져오기
EquipmentFetch31505000장비 가져오기

낮은 우선순위 작업 (3000대 이하)

작업 타입priorityexplicitPriority설명
ArmTrap31003100덫 설치
MoveToSafety30503050안전 장소로 이동
ReturnSuitIdle30003000수트 반환 (대기)
Idle29502950대기

skip_implicit_priority_change 참고사항

skip 열의  표시는 skip_implicit_priority_change: true인 작업을 의미합니다. 이 작업들은 nextImplicitPriority를 감소시키지 않으므로, 그 이후 작업들의 우선순위가 예상과 다를 수 있습니다.

skip 작업 목록:

  • Toggle (6000)
  • Mop (5550)
  • Relocate (5500)
  • Disinfect (5450)
  • Transport (3550)
  • Build (3500)
  • BuildDig (3450)
  • BuildUproot (3400)
  • BuildFetch (3350)
  • StorageFetch (3200)

작업 ID 할당

각 작업은 생성 시 고유한 ID를 받습니다:

// Chore.cs
private static int nextId = 0;

public static int GetNextChoreID()
{
    return ++nextId;
}
  • 작업 ID는 순차적으로 할당됩니다 (1, 2, 3, ...)
  • 동일한 우선순위를 가진 작업들 간의 최종 비교에 사용됩니다
  • 낮은 ID를 가진 작업이 우선 선택됩니다

전제조건 (Preconditions)

작업이 선택되기 전에 다음 조건들이 검사됩니다:

  1. 기본 전제조건
    • 작업이 유효한지
    • 작업이 이미 완료되지 않았는지
    • 작업이 다른 복제체에 할당되지 않았는지
  2. 복제체 관련 전제조건
    • 복제체가 해당 작업을 수행할 수 있는지
    • 필요한 기술이나 능력이 있는지
    • 작업 그룹이 활성화되어 있는지
  3. 자원 관련 전제조건
    • 필요한 자원이 있는지
    • 이동 경로가 있는지
    • 작업 대상이 접근 가능한지
  4. 비용 계산
    • 이동 비용 계산
    • 작업 수행 비용 계산

특수 케이스

작업 중단 (Interrupt)

현재 작업 중인 복제체는 더 높은 우선순위의 작업이 나타나면 현재 작업을 중단할 수 있습니다:

// ChoreConsumer.ChooseChore()
int interruptPriority = currentChore.choreType.interruptPriority;
if (newChore.interruptPriority > interruptPriority)
{
    // 현재 작업 중단하고 새 작업 시작
}

작업 제외 (Interrupt Exclusion)

특정 작업 타입은 다른 작업을 중단할 수 없도록 설정될 수 있습니다:

  • 예: VomitCoughEmoteHighPriority는 HealCritical을 중단할 수 없음

요약

  1. 작업 선택은 복잡한 우선순위 시스템에 기반합니다
  2. 개인 우선순위는 작업 타입 우선순위보다 우선 적용됩니다
  3. 근접 활성화는 작업 타입 우선순위만 변경하며, 개인 우선순위는 그대로 적용됩니다
  4. 작업 타입별 우선순위는 게임 초기화 시 고정됩니다
  5. 동일한 우선순위일 경우 비용과 작업 ID로 결정됩니다


🏠 홈으로

댓글 0

댓글을 불러오는 중...