작업 할당 시스템 분석
목차
시스템 개요
복제체가 작업을 선택하고 수행하는 시스템은 다음과 같은 흐름으로 동작합니다:
- 작업 수집:
ChoreProvider들이 게임 세계에서 사용 가능한 작업들을 제공 - 전제조건 검사: 각 작업에 대해 복제체가 수행 가능한지 전제조건(Precondition) 검사
- 우선순위 비교: 전제조건을 통과한 작업들을 우선순위에 따라 정렬
- 작업 선택: 가장 높은 우선순위의 작업 선택
- 작업 수행:
ChoreDriver가 선택된 작업을 실행
핵심 컴포넌트
Chore (작업)
- 게임 내 모든 작업의 추상 기본 클래스
- 우선순위 설정, 전제조건, 실행 로직을 포함
- 각 작업은 고유한 ID를 가짐
ChoreConsumer (작업 소비자)
- 복제체에 부착된 컴포넌트
- 사용 가능한 작업을 찾고 선택하는 역할
FindNextChore() 메서드로 다음 작업을 찾음
FindNextChore() 메서드로 다음 작업을 찾음ChoreDriver (작업 실행자)
- 복제체에 부착된 컴포넌트
- 선택된 작업을 실제로 실행하는 역할
ChoreProvider (작업 제공자)
- 게임 세계의 객체들에 부착된 컴포넌트
- 사용 가능한 작업들을 제공
- 예: 건물, 저장소, 작업 가능한 객체 등
ChoreType (작업 타입)
- 작업의 타입을 정의
- 각 작업 타입은 고유한 우선순위 값을 가짐
Database/ChoreTypes.cs에서 모든 작업 타입이 정의됨
Database/ChoreTypes.cs에서 모든 작업 타입이 정의됨작업 선택 프로세스
1. 작업 수집 단계
// ChoreConsumer.FindNextChore()
for (int i = 0; i < providers.Count; i++)
{
providers[i].CollectChores(consumerState,
preconditionSnapshot.succeededContexts,
preconditionSnapshot.failedContexts);
}
// 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. 작업 선택
정렬된 목록에서 가장 높은 우선순위의 작업을 선택합니다.
우선순위 시스템
우선순위 비교 순서
작업 선택 시 다음 순서로 우선순위를 비교합니다:
- 전제조건 실패 여부 (
failedPreconditionId)- 전제조건을 통과한 작업이 우선
- 마스터 우선순위 클래스 (
masterPriority.priority_class)idle<basic<high<personalNeeds<topPriority<compulsory
- 개인 우선순위 (
personalPriority)- 복제체별로 설정된 작업 그룹별 우선순위 (0-5)
- 높을수록 우선
- 마스터 우선순위 값 (
masterPriority.priority_value)- 작업에 직접 설정된 우선순위 값 (1-9)
- 작업 타입 우선순위 (
priority)- 작업 타입의 고유 우선순위 값
- "근접 활성화"가 꺼져 있으면:
choreType.priority(암시적 우선순위) - "근접 활성화"가 켜져 있으면:
choreType.explicitPriority(명시적 우선순위, 기본값 5000)
- 우선순위 수정자 (
priorityMod)- 작업별 추가 우선순위 보정값
- 소비자 우선순위 (
consumerPriority)- 복제체별 추가 우선순위 보정값
- 비용 (
cost)- 이동 비용 등 (낮을수록 우선)
- 작업 ID (
chore.id)- 동일한 우선순위일 경우 작업 ID로 결정 (낮을수록 우선)
마스터 우선순위 클래스 (Master Priority Class)
마스터 우선순위 클래스는 작업의 대분류를 나타냅니다:
| 클래스 | 값 | 설명 |
|---|---|---|
idle | -1 | 대기 상태 |
basic | 0 | 기본 작업 |
high | 1 | 높은 우선순위 |
personalNeeds | 2 | 개인 필요 (식사, 수면 등) |
topPriority | 3 | 최우선 작업 |
compulsory | 4 | 강제 작업 |
개인 우선순위 (Personal Priority)
- 각 복제체별로 작업 그룹(Chore Group)에 대해 설정 가능한 우선순위
- 범위: 0-5 (높을수록 우선)
- 우선순위 화면에서 설정 가능
- 작업 타입 우선순위보다 먼저 비교됨
작업 타입 우선순위
암시적 우선순위 (Implicit Priority)
nextImplicitPriority 변수로 관리- 초기값: 10000
- 작업 타입이 추가될 때마다 50씩 감소
skip_implicit_priority_change: true인 작업은 감소하지 않음
nextImplicitPriority 변수로 관리skip_implicit_priority_change: true인 작업은 감소하지 않음명시적 우선순위 (Explicit Priority)
- 대부분의 일반 작업: 5000
- "근접 활성화"가 켜져 있을 때 사용됨
근접 활성화 (Proximity Enable)
위치
- 우선순위 화면 (Jobs Table Screen)에서 "근접 활성화" 토글 버튼
JobsTableScreen.OnAdvancedModeToggleClicked() 메서드로 제어Game.Instance.advancedPersonalPriorities 변수로 저장
JobsTableScreen.OnAdvancedModeToggleClicked() 메서드로 제어Game.Instance.advancedPersonalPriorities 변수로 저장동작 방식
근접 활성화 꺼짐 (기본 모드):
priority = chore.choreType.priority; // 암시적 우선순위 사용근접 활성화 켜짐 (고급 모드):
priority = chore.choreType.explicitPriority; // 명시적 우선순위 사용 (대부분 5000)효과
- 근접 활성화 꺼짐: 작업 타입별로 다른 우선순위 값 사용 (10000부터 50씩 감소)
- 근접 활성화 켜짐: 대부분의 작업이 동일한 우선순위(5000)를 가지므로, 거리(비용)가 더 중요한 요소가 됨
중요 사항
explicitPriority는 개인 우선순위를 무시하지 않습니다- 개인 우선순위는 작업 타입 우선순위보다 먼저 비교되므로 항상 우선 적용됩니다
explicitPriority는 단지 작업 타입 우선순위 비교 단계에서 사용되는 값일 뿐입니다
explicitPriority는 개인 우선순위를 무시하지 않습니다explicitPriority는 단지 작업 타입 우선순위 비교 단계에서 사용되는 값일 뿐입니다작업 타입별 우선순위 목록
최고 우선순위 작업 (10000-6200)
| 작업 타입 | priority | explicitPriority | 설명 |
|---|---|---|---|
| Die | 10000 | 10000 | 사망 |
| Entombed | 9950 | 9950 | 매몰됨 |
| SuitMarker | 9900 | 9900 | 수트 마커 |
| Slip | 9850 | 9850 | 미끄러짐 |
| Checkpoint | 9800 | 9800 | 체크포인트 |
| TravelTubeEntrance | 9750 | 9750 | 이동 튜브 입구 |
| WashHands | 9700 | 9700 | 손 씻기 |
| HealCritical | 9650 | 9650 | 긴급 치료 |
| BeIncapacitated | 9600 | 9600 | 무능력 상태 |
| WaterDamageZap | 9550 | 9550 | 물 피해 감전 |
| BeOffline | 9500 | 9500 | 오프라인 |
| GeneShuffle | 9450 | 9450 | 유전자 셔플 |
| Migrate | 9400 | 9400 | 이주 |
| DebugGoTo | 9350 | 9350 | 디버그 이동 |
| MoveTo | 9300 | 9300 | 이동 |
| RocketEnterExit | 9250 | 9250 | 로켓 출입 |
| DropUnusedInventory | 9200 | 9200 | 미사용 인벤토리 버리기 |
| FindOxygenSourceItem_Critical | 9150 | 9150 | 산소 공급원 찾기 (긴급) |
| BionicAbsorbOxygen_Critical | 9100 | 9100 | 생체공학 산소 흡수 (긴급) |
| ExpellGunk | 9050 | 9050 | 덩어리 배출 |
| Pee | 9000 | 9000 | 소변 |
| RecoverBreath | 8950 | 8950 | 호흡 회복 |
| RecoverWarmth | 8900 | 8900 | 따뜻함 회복 |
| RecoverFromHeat | 8850 | 8850 | 열기에서 회복 |
| Flee | 8800 | 8800 | 도망 |
| MoveToQuarantine | 8750 | 8750 | 격리소로 이동 |
| EmoteIdle | 8700 | 8700 | 감정 표현 (대기) |
| Emote | 8650 | 8650 | 감정 표현 |
| EmoteHighPriority | 8600 | 8600 | 감정 표현 (높은 우선순위) |
| StressEmote | 8550 | 8550 | 스트레스 감정 표현 |
| Hug | 8500 | 8500 | 포옹 |
| StressVomit | 8450 | 8450 | 스트레스 구토 |
| UglyCry | 8400 | 8400 | 우는 소리 |
| BansheeWail | 8350 | 8350 | 비명 |
| StressShock | 8300 | 8300 | 스트레스 쇼크 |
| BingeEat | 8250 | 8250 | 폭식 |
| StressActingOut | 8200 | 8200 | 스트레스 행동 |
| Vomit | 8150 | 8150 | 구토 |
| Cough | 8100 | 8100 | 기침 |
| RadiationPain | 8050 | 8050 | 방사선 통증 |
| SwitchHat | 8000 | 8000 | 모자 교체 |
| StressIdle | 7950 | 7950 | 스트레스 대기 |
| RescueIncapacitated | 7900 | 7900 | 무능력자 구조 |
| BreakPee | 7850 | 7850 | 긴급 소변 |
| Eat | 7800 | 7800 | 식사 |
| ReloadElectrobank | 7750 | 7750 | 전기뱅크 재충전 |
| SeekAndInstallUpgrade | 7700 | 7700 | 업그레이드 찾기 및 설치 |
| OilChange | 7650 | 7650 | 오일 교체 |
| SolidOilChange | 7600 | 7600 | 고체 오일 교체 |
| BionicAbsorbOxygen | 7550 | 7550 | 생체공학 산소 흡수 |
| FindOxygenSourceItem | 7500 | 7500 | 산소 공급원 찾기 |
| Narcolepsy | 7450 | 7450 | 기면증 |
| ReturnSuitUrgent | 7400 | 7400 | 수트 반환 (긴급) |
| SleepDueToDisease | 7350 | 7350 | 질병으로 인한 수면 |
| BionicRestDueToDisease | 7300 | 7300 | 질병으로 인한 생체공학 휴식 |
| Sleep | 7250 | 7250 | 수면 |
| TakeMedicine | 7200 | 7200 | 약 복용 |
| GetDoctored | 7150 | 7150 | 의사 진료 받기 |
| RestDueToDisease | 7100 | 7100 | 질병으로 인한 휴식 |
| BionicBedtimeMode | 7050 | 7050 | 생체공학 취침 모드 |
| ScrubOre | 7000 | 7000 | 광석 세척 |
| DeliverFood | 6950 | 6950 | 음식 배달 |
| Sigh | 6900 | 6900 | 한숨 |
| Heal | 6850 | 6850 | 치료 |
| Shower | 6800 | 6800 | 샤워 |
| LearnSkill | 6750 | 6750 | 기술 학습 |
| UnlearnSkill | 6700 | 6700 | 기술 잊기 |
| Equip | 6650 | 6650 | 장비 착용 |
| JoyReaction | 6600 | 6600 | 기쁨 반응 |
| RocketControl | 6550 | 6550 | 로켓 제어 |
| Fart | 6500 | 6500 | 방귀 |
| StressHeal | 6450 | 6450 | 스트레스 치유 |
| Party | 6400 | 6400 | 파티 |
| Relax | 6350 | 6350 | 휴식 |
| Recharge | 6300 | 6300 | 재충전 |
| Unequip | 6250 | 6250 | 장비 해제 |
| Mourn | 6200 | 6200 | 애도 |
| TopPriority | 6150 | 6150 | 최우선 |
명시적 우선순위 5000 작업들
다음 작업들은 모두 priority 값이 다르지만 explicitPriority = 5000으로 통일되어 있습니다:
| 작업 타입 | priority | explicitPriority | skip | 설명 |
|---|---|---|---|---|
| Attack | 6100 | 5000 | 공격 | |
| Doctor | 6050 | 5000 | 의사 | |
| Toggle | 6000 | 5000 | ✓ | 토글 |
| Capture | 5950 | 5000 | 포획 | |
| CreatureFetch | 5900 | 5000 | 생물 가져오기 | |
| RanchingFetch | 5850 | 5000 | 목축 물품 가져오기 | |
| EggSing | 5800 | 5000 | 알에 노래하기 | |
| Astronaut | 5750 | 5000 | 우주비행사 | |
| FetchCritical | 5700 | 5000 | 긴급 가져오기 | |
| Art | 5650 | 5000 | 예술 | |
| EmptyStorage | 5600 | 5000 | 저장소 비우기 | |
| Mop | 5550 | 5000 | ✓ | 청소 |
| Relocate | 5500 | 5000 | ✓ | 재배치 |
| Disinfect | 5450 | 5000 | ✓ | 소독 |
| Repair | 5400 | 5000 | 수리 | |
| RepairFetch | 5350 | 5000 | 수리 물품 가져오기 | |
| Deconstruct | 5300 | 5000 | 철거 | |
| Demolish | 5250 | 5000 | 파괴 | |
| Research | 5200 | 5000 | 연구 | |
| AnalyzeArtifact | 5150 | 5000 | 유물 분석 | |
| AnalyzeSeed | 5100 | 5000 | 씨앗 분석 | |
| ExcavateFossil | 5050 | 5000 | 화석 발굴 | |
| ResearchFetch | 5000 | 5000 | 연구 물품 가져오기 | |
| GeneratePower | 4950 | 5000 | 전력 생성 | |
| CropTend | 4900 | 5000 | 작물 돌보기 | |
| PowerTinker | 4850 | 5000 | 전력 정비 | |
| RemoteOperate | 4800 | 5000 | 원격 조작 | |
| MachineTinker | 4750 | 5000 | 기계 정비 | |
| MachineFetch | 4700 | 5000 | 기계 물품 가져오기 | |
| Harvest | 4650 | 5000 | 수확 | |
| FarmFetch | 4600 | 5000 | 농업 물품 가져오기 | |
| Uproot | 4550 | 5000 | 뿌리 뽑기 | |
| CleanToilet | 4500 | 5000 | 화장실 청소 | |
| EmptyDesalinator | 4450 | 5000 | 담수화기 비우기 | |
| LiquidCooledFan | 4400 | 5000 | 액체 냉각 팬 | |
| IceCooledFan | 4350 | 5000 | 얼음 냉각 팬 | |
| Train | 4300 | 5000 | 훈련 | |
| ProcessCritter | 4250 | 5000 | 생물 가공 | |
| Cook | 4200 | 5000 | 요리 | |
| CookFetch | 4150 | 5000 | 요리 물품 가져오기 | |
| DoctorFetch | 4100 | 5000 | 의료 물품 가져오기 | |
| Ranch | 4050 | 5000 | 목축 | |
| PowerFetch | 4000 | 5000 | 전력 물품 가져오기 | |
| FlipCompost | 3950 | 5000 | 퇴비 뒤집기 | |
| Depressurize | 3900 | 5000 | 감압 | |
| FarmingFabricate | 3850 | 5000 | 농업 제조 | |
| PowerFabricate | 3800 | 5000 | 전력 제조 | |
| Compound | 3750 | 5000 | 약제 제조 | |
| Fabricate | 3700 | 5000 | 제조 | |
| FabricateFetch | 3650 | 5000 | 제조 물품 가져오기 | |
| FoodFetch | 3600 | 5000 | 음식 가져오기 | |
| Transport | 3550 | 5000 | ✓ | 운반 |
| Build | 3500 | 5000 | ✓ | 건설 |
| BuildDig | 3450 | 5000 | ✓ | 건설용 채굴 |
| BuildUproot | 3400 | 5000 | ✓ | 건설용 뿌리 뽑기 |
| BuildFetch | 3350 | 5000 | ✓ | 건설 물품 가져오기 |
| Dig | 3300 | 5000 | 채굴 | |
| Fetch | 3250 | 5000 | 가져오기 | |
| StorageFetch | 3200 | 5000 | ✓ | 저장소 가져오기 |
| EquipmentFetch | 3150 | 5000 | 장비 가져오기 |
낮은 우선순위 작업 (3000대 이하)
| 작업 타입 | priority | explicitPriority | 설명 |
|---|---|---|---|
| ArmTrap | 3100 | 3100 | 덫 설치 |
| MoveToSafety | 3050 | 3050 | 안전 장소로 이동 |
| ReturnSuitIdle | 3000 | 3000 | 수트 반환 (대기) |
| Idle | 2950 | 2950 | 대기 |
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)
작업이 선택되기 전에 다음 조건들이 검사됩니다:
- 기본 전제조건
- 작업이 유효한지
- 작업이 이미 완료되지 않았는지
- 작업이 다른 복제체에 할당되지 않았는지
- 복제체 관련 전제조건
- 복제체가 해당 작업을 수행할 수 있는지
- 필요한 기술이나 능력이 있는지
- 작업 그룹이 활성화되어 있는지
- 자원 관련 전제조건
- 필요한 자원이 있는지
- 이동 경로가 있는지
- 작업 대상이 접근 가능한지
- 비용 계산
- 이동 비용 계산
- 작업 수행 비용 계산
특수 케이스
작업 중단 (Interrupt)
현재 작업 중인 복제체는 더 높은 우선순위의 작업이 나타나면 현재 작업을 중단할 수 있습니다:
// ChoreConsumer.ChooseChore()
int interruptPriority = currentChore.choreType.interruptPriority;
if (newChore.interruptPriority > interruptPriority)
{
// 현재 작업 중단하고 새 작업 시작
}작업 제외 (Interrupt Exclusion)
특정 작업 타입은 다른 작업을 중단할 수 없도록 설정될 수 있습니다:
- 예:
Vomit,Cough,EmoteHighPriority는HealCritical을 중단할 수 없음
요약
- 작업 선택은 복잡한 우선순위 시스템에 기반합니다
- 개인 우선순위는 작업 타입 우선순위보다 우선 적용됩니다
- 근접 활성화는 작업 타입 우선순위만 변경하며, 개인 우선순위는 그대로 적용됩니다
- 작업 타입별 우선순위는 게임 초기화 시 고정됩니다
- 동일한 우선순위일 경우 비용과 작업 ID로 결정됩니다

댓글 0
댓글을 작성하려면 로그인해주세요.