C#으로 TextRPG를 개발하는 과정에서, 전투 시스템 구현 중 예상치 못한 문제가 발생했다.
몬스터를 관리하는 과정에서 동일한 Monster 객체 인스턴스가 공유되면서 한 몬스터 객체가 계속해서 전투에 쓰이는 문제였다.
문제 상황
초기 전투 시스템은 미리 생성한 Monster 객체들을 리스트에 담아 관리하고 있었다. 각 전투마다 1~4마리의 몬스터를 무작위로 선택해 리스트에 추가하는 방식이었다.
randomMonsterList.Add(normalMonsters[randomIndex]);
이 방식은 처음에는 문제 없이 동작하는 듯했지만, 전투 중 한 몬스터를 처치하면 다른 몬스터도 동시에 사망하는 버그가 발생했다.
원인 분석
C#에서는 참조형(Reference Type) 객체를 리스트에 추가하면 값이 복사되는 것이 아니라 참조(Reference)가 추가된다.따라서 동일한 Monster 인스턴스를 여러 번 리스트에 추가하게 되면, 리스트에 있는 몬스터들이 모두 하나의 인스턴스를 공유하게 된다.
-> 결과적으로 한 몬스터의 Hp를 0으로 만들면, 같은 인스턴스를 참조하는 모든 몬스터가 동시에 Hp = 0이 되어 버렸다.
해결 방법
문제 해결을 위해 전투에 등장하는 몬스터는 모두 독립적인 인스턴스여야 한다는 결론을 내렸다.
따라서, 전투 시작 시 몬스터를 리스트에 추가할 때, 기존 객체를 그대로 추가하는 것이 아니라 새로운 인스턴스를 생성하여 복제(Clone) 하도록 수정했다.
Monster template = isNormalMonster ? normalMonsters[randomIndex] : hardMonsters[randomIndex];
Monster newMonster = new Monster(
template.Name, template.Type, template.Question, template.CorrectAnswer,
template.MaxHp, template.AttackPower, template.DefensePower, template.GoldReward
);
randomMonsterList.Add(newMonster);
이렇게 변경하면서, 전투 중 개별 몬스터의 상태(Hp, IsDefeated 등)가 독립적으로 관리되게 되었고, 하나의 몬스터를 처치해도 다른 몬스터에게 영향을 주지 않게 되었다.
얻은 교훈
- 참조형 객체를 리스트에 추가할 때는 참조가 추가된다는 점을 항상 인지해야 한다.
- 게임과 같이 상태 변화가 중요한 시스템에서는 각 인스턴스가 독립적으로 관리되도록 설계하는 것이 필수적이다.
- 초기 설계 단계에서 객체 복제, 독립성을 고려하지 않으면, 이후 예상치 못한 동시 상태 변화 문제를 겪을 수 있다.
📖 요약
이 트러블슈팅을 통해, 객체 관리의 중요성과 참조/복제에 대한 이해가 프로젝트 안정성에 미치는 영향을 다시 한번 깨달을 수 있었다.
특히, 전투 시스템처럼 상태 변화가 빈번한 게임 로직에서는 객체 생명주기와 관리 방식에 대해 명확한 설계가 필요하다.
항목내용
항목 | 내용 |
문제 | Monster 객체 참조 공유로 인한 동시 상태 변경 |
원인 | 같은 인스턴스를 여러 리스트에 참조로 추가 |
해결 | 전투 시작 시 Monster 객체를 새로 생성하여 복제 |
교훈 | 상태 관리가 필요한 객체는 반드시 독립 인스턴스로 운용할 것 |
'C# > C#프로젝트' 카테고리의 다른 글
[TeamProject2] C# 팀프로젝트 회고 - Dark Zeb(1등!) (0) | 2025.04.29 |
---|---|
[TeamProject2] 기능 나열형 코드를 MVC 패턴으로 구조화 (0) | 2025.04.28 |
[C#Project] C# 개인 과제 개발 회고 – TextRPG (0) | 2025.04.21 |
[C#Project] Player가 Inventory를 참조할 때 발생한 순환 참조 문제 (Circular Dependency) (0) | 2025.04.19 |
[C#Project] TextRPG게임설계 (0) | 2025.04.18 |