Cloudwiki

Particle Sandbox/구상/디지털 생태계 구상

# 디지털 생태계 구상

Particle Sandbox 안에 "작은 어항/테라리움" 같은 자족적 미니 생태계를 만들어보자는 브레인스토밍 문서다. 제시된 두 주제(식물 리팩토링, 물고기 추가)를 중심으로, 관련해서 떠오르는 추가 아이디어를 함께 정리한다. 개수 제한 없이 던지는 문서이므로 각 항목은 제안과 근거만 짧게 적는다. 채택 여부·우선순위는 별도 논의.

---

## 식물 리팩토링

### 문제의식

현재 `plant.ts`는 씨앗 발아 즉시 매 틱 `GROW_CHANCE=0.09`로 tip이 무작위 방향(좌상/상/우상)으로 뻗으면서 `MAX_GEN=6`까지 계속 두 갈래로 fork한다. 결과적으로 짧은 시간에 "형태를 특정하기 어려운 초록 덤불"이 빠르게 뒤덮이는 느낌이 강하고, 줄기라 부를만한 두꺼운 구조가 없다(전부 1칸 폭 가지).

### 제안 1 — 성장 속도/형태를 "줄기 우선"으로 개편

- **제안**: 발아 직후에는 분기 없이 단일 생장점만 위로 천천히 자라다가(예: 일정 높이·틱 경과 후에야 fork 확률이 열리는 2단계 성장), 전체 `GROW_CHANCE`를 크게 낮춰 "며칠에 걸쳐 자란다"는 체감을 준다.
- **근거**: 지금도 `aux`에 생장점 여부·heading·다음 fork까지 segment 카운트가 이미 패킹되어 있어(`plant.ts`), 이 카운터에 "최소 줄기 길이 도달 전에는 fork 금지" 조건 하나만 추가해도 형태가 크게 달라진다. 로직 골격을 갈아엎지 않고 파라미터·게이트 조정만으로 상당 부분 해결 가능해 보인다.

### 제안 2 — 줄기 두께(1~2칸) 표현

- **제안**: 지금은 모든 가지가 1칸 폭인데, 줄기 코어 셀 옆에 확률적으로 보조 두께 셀 1칸을 붙이는 "코어+사이드" 개념을 aux 비트 하나로 표시한다.
- **근거**: `aux` 16비트 중 여유 비트가 크게 남지 않으므로(수분 7비트+tip+heading 2비트+segment 2비트+generation 3비트+init 1비트로 이미 빡빡함) 새 비트를 넣으려면 다른 필드(예: generation 3비트→2비트)를 줄이는 트레이드오프가 필요할 수 있다. 완전히 새 필드보다는 "짝수 세그먼트에서만 두꺼워진다" 같은 계산 규칙으로 비트 추가 없이 흉내 내는 방법도 검토할 만하다.

### 제안 3 — 씨앗 배치를 브러시 설정과 분리

- **제안**: 씨앗은 브러시 크기와 무관하게 클릭당 1픽셀만 놓이고, 영역(사각) 선택 배치에서는 선택 영역 안에 매우 낮은 밀도로 스캐터되게 한다.
- **근거**: 지금 브러시/영역 배치(`PointerPainter.ts`, `applyRect`)는 모든 물질에 동일한 `paintCells` 경로를 타고, `Material`에는 개별 배치 밀도를 지정하는 훅(`onPlace`/`placementDensity` 류)이 없다. 이건 씨앗만을 위한 특수 분기로 땜질하기보다, "물질이 자기 배치 밀도를 선언할 수 있는" 범용 훅을 엔진에 새로 만들어두면 이후 다른 씨앗류/희소 배치 물질에도 재사용할 수 있어 투자 가치가 있다.

### 제안 4 — 식물 종 다양화를 위한 공통 성장 코어 분리

- **제안**: 풀(현재 기본형), 수초, 대나무 등을 낱개 물질로 늘리기 전에, `plant.ts`의 성장 로직을 "생장 파라미터 세트(성장확률, 분기확률, 최대 두께, 선호 heading, 물속/공기 중 여부 등)를 받는 공용 함수"로 뽑아두자.
- **근거**: 이미 `crawler.ts`가 termite/nanobot 사이에서 이동 로직을 공유하는 전례가 있다. 같은 패턴을 식물에도 적용하면 "대나무=수직 전용 고속 성장+마디감", "수초=물속에서만 자라고 부력에 흔들림"처럼 종별 차이를 파라미터 차이로 표현할 수 있어 물질 추가 비용이 줄어든다. 수초는 이미 있는 `coral.ts`(수중 정착형 생물)의 침수 판정 로직도 참고할 수 있다.

---

## 물고기 추가

### 구현 방식 — 오브젝트가 아니라 파티클(셀) 기반을 권장

- **제안**: 고무공/드럼통처럼 그리드와 분리된 "오브젝트" 레이어가 아니라, termite/nanobot처럼 `Grid` 셀(파티클) 하나로 물고기를 구현한다.
- **근거**: 오브젝트 레이어는 부력·충돌 물리는 정교하지만 자율 이동 AI 개념이 전무해 헤엄 로직을 통째로 새로 만들어야 한다. 반면 `crawler.ts` 기반 파티클 생물(termite, nanobot)은 이미 "aux에 heading 저장 + 벽/표면 추종 + 군집 분산 + 침수 판정(`isSubmerged`)" 같은 헤엄에 필요한 부품을 대부분 갖추고 있어 재사용 여지가 크다. 요청하신 "엔진 판정은 1픽셀"이라는 조건과도 파티클 방식이 자연스럽게 맞는다.

### 렌더링 — 물리 판정 없는 꼬리 픽셀

- **제안**: 실제 셀 점유는 1픽셀이고, 렌더링 시에만 이동 방향 반대쪽에 회색 꼬리 픽셀 1개를 추가로 그린다(상하 이동은 무시, 좌우 이동 방향 기준).
- **근거**: `CanvasRenderer.ts`의 Fan 바람 글리프가 정확히 같은 패턴(그리드 판정과 무관한 표시 전용 오버레이)이다. 물고기 heading은 `aux`에 이미 저장될 값이므로 렌더러가 "현재 셀 위치 + heading의 반대 방향"만 계산하면 되고, CA 판정 코드는 전혀 건드릴 필요가 없다.

### 생사 2종 물질

- **제안**: `FISH_LIVE`(팔레트 노출) / `FISH_DEAD`(팔레트 비노출, 변환으로만 생성) 두 물질로 분리. 사망 트리거: 충격파 노출 시 50% 확률, 방사능 피폭, 고온, 물 밖 장시간 방치(카운터 누적).
- **근거**: `Material.radiationDeath` 필드(피폭 시 지정된 사체 id로 자동 전환 — Plant/Seed→Ash, Termite→Sawdust)가 이미 있는 패턴이라 방사능 사망은 그대로 재사용 가능. 충격파 50%/고온/방치 조건은 자체 `update` 안에서 카운터나 확률 굴림으로 직접 처리하면 되고, 이 역시 다른 생물 물질에서 쓰는 흔한 방식이라 새로운 엔진 개념이 필요하지 않다.

### 이동 — 수중 헤엄 / 물 밖 펄떡임

- **제안**: 침수 상태에서는 heading 유지 랜덤워크(가끔 방향 전환)로 자유롭게 헤엄치고, 비침수(물 밖) 상태에서는 별도 상태로 전환해 무작위 방향 단발 점프 + 중력 낙하로 "펄떡거림"을 표현한다.
- **근거**: `crawler.ts`의 `isSubmerged(x,y,sim)`이 4방향 이웃 액체/기체 여부로 침수를 판정하는 헬퍼로 이미 존재하고 termite/nanobot의 익사 판정에 쓰이고 있어, 그대로 호출해 물 안/밖 상태 분기에 쓸 수 있다. "펄떡임"은 별도 물리 개념이 아니라 기존 파우더류의 확률적 점프 이동을 흉내 내는 정도로 구현 가능해 보인다.

### 색상

- **제안**: 살아있는 물고기 = 짙은 네이비 몸통 + 회색 꼬리 픽셀(요청사항 그대로). 죽은 물고기는 창백한 회백색~탁한 베이지 계열로, 배가 하얗게 뜬 느낌을 주고 밀도를 낮춰 수면 위로 둥둥 뜨게 하면 "죽어서 뜬 물고기"라는 정보가 색과 거동 둘 다로 전달된다.
- **근거**: 파티클 밀도 기반 부력은 CA의 기본 동작(`bubble.ts` 등에서 이미 활용 중)이라, 사망 시 물질을 바꾸면서 밀도 값만 낮게 잡아주면 별도 로직 없이 자연스럽게 떠오른다.

---

## 추가 아이디어 (디지털 어항/테라리움 컨셉 전반)

- **미세 먹이사슬**: 물고기가 작은 벌레·조류를 먹고, 배설물/사체가 식물 비료가 되는 순환 고리. termite류의 `eatAndReproduce` 패턴을 재활용하면 "먹이 탐색 → 섭취 → 번식/성장"까지 구현 부담이 낮다.
- **조류(Algae) 오염 이벤트**: 방치하면 수초 주변에 초록 조류가 과증식해 물이 뿌옇게 변하고 심하면 물고기가 스트레스/질식. 어항을 "그냥 두면 안 되고 관리해야 하는" 대상으로 만들어 편의성보다 재미(1순위)를 살리는 장치.
- **청소부 생물(달팽이/새우)**: 조류를 먹어치우는 저속 이동 생물을 별도로 두면 유저가 "생태 균형"을 손수 맞추는 플레이가 생긴다.
- **산소 순환**: 수초가 광원 근처에서 기포(기존 `bubble.ts` 재사용)를 방출하고, 물고기는 밀폐된 어항에 산소 공급원이 없으면 서서히 사망 카운터가 오르는 식으로 "닫힌 계"라는 테라리움 본연의 긴장감을 준다.
- **산호 연동**: 이미 있는 `coral.ts`의 백화(bleaching) 스트레스 누적 로직이 정확히 테라리움 컨셉과 맞닿아 있어, 신규 구현 없이 "디지털 어항" 프리셋 안에 그대로 끼워 넣을 수 있는 기존 자산.
- **먹이 주기 인터랙션**: 유저가 사료(가루 물질)를 뿌리면 물고기가 그쪽으로 이동. termite의 먹이 탐색 로직을 헤딩 갱신에 활용하면 별도 pathfinding 없이도 그럴듯하게 동작할 것으로 보인다.
- **무리짓기(school of fish)**: crawler류의 "혼잡하면 흩어진다" 로직을 반대로 뒤집어 "동종이 적당히 가까우면 약하게 끌린다"로 만들면 물고기 떼가 뭉쳐 다니는 비주얼을 적은 코드로 얻을 수 있다.
- **번식(알)**: 조건 충족 시 물고기가 알 물질을 낳고, 일정 시간 후 치어(작은 물고기, 별도 색/크기)로 부화하는 생애주기. 씨앗→식물 발아 로직과 구조적으로 거의 동일해 seed.ts 패턴을 그대로 참고 가능.
- **미니 어항 프리셋/튜토리얼**: "디지털 어항" 완성형 씬(유리벽 오브젝트 + 모래 바닥 + 수초 + 물고기 몇 마리)을 저장 슬롯이나 시작 프리셋으로 제공하면, 재미·편의성 둘 다에 기여하고 Cloudwiki에도 소개하기 좋은 결과물이 된다.
- **온도/조명에 따른 생태 반응**: 히터·조명 오브젝트를 어항 위에 놓으면 식물 성장 속도가 빨라지거나 물고기가 활발해지는 등, 기존 열전도 시스템을 그대로 재사용해 "환경을 꾸미는 재미"를 추가할 수 있다.

---

## 메모

- 위 항목들은 모두 브레인스토밍 단계이며, 실제 채택 시에는 `docs/` 하위 문서(예: `MATERIALS.md`, `MATERIAL-SYSTEMS.md`)에 상세 설계를 별도로 정리해야 한다.
- 물질 배치 밀도 훅(식물 제안 3)은 씨앗 하나만을 위한 게 아니라 엔진 차원의 신규 개념이라, 착수 전에 범위를 먼저 정하는 편이 좋아 보인다.