다시 좌충우돌하면서 제미나이를 써보려고합니다

이번에 로그라이크 만들면서 도구가 3가지가 늘었습니다
웹/gemini cli / antigravity
작업은 주로 안티 그래비티에서 작업하며 여기에 웹과 대화하고 아이디어를 안티그래비티로 옮겼습니다
토큰소모 끝나면 다른 모드로 옮겨가면서 작업했죠
제미나이 cli는 빈도가 점점 줄었습니다

## :counterclockwise_arrows_button: 안티그래비티 개발 워크플로우 (운영 전략)
단계 환경 주요 역할 API/토큰 활용 전략
**Plan** 웹 (Web) 무제한 대화로 설계 및 로직 확정 웹 세션의 넉넉한 토큰 활용
**Commit** CLI `GEMINI.md` 업데이트 및 파일 쓰기 짧은 메시지로 API 사용 최소화
**Verify** 로컬/CLI 코드 실행 및 에러 로그 수집 샌드박스 환경에서 자동 검증 수행

:light_bulb: 운영 가이드

  1. 관심사의 분리:
    • 웹(Web)은 프로젝트의 **‘뇌’**입니다. 복잡한 로직 설계와 맥락 유지는 여기서 수행합니다.
    • CLI는 프로젝트의 **‘손’**입니다. 웹에서 확정된 최종안을 로컬 파일에 물리적으로 반영할 때만 호출합니다.
  2. 토큰 절약:
    • 웹에서 길게 나눈 대화 과정을 CLI에 반복하지 않습니다. 오직 '결론’과 '수정할 코드’만 CLI에 던져 API 소모를 방지합니다.
  3. 지식 축적:
    • 작업 중 발생한 에러나 AI가 고쳐야 할 행동 양식은 즉시 CLI를 통해 GEMINI.md에 기록하여 다음 세션의 ‘재시작(Reload)’ 효율을 높입니다.
  4. 검증 루프:
    • 로컬 터미널에서 main.py 실행 시 발생하는 모든 이슈는 캡처하여 다시 Plan(웹) 단계로 가져가 해결책을 도출합니다.
      대충 워크플로를 이렇게 돌리려고합니다
      제미나이 cli는2.5 플랜모드로
      웹은 사고 모드로 작업합니다
      이걸 기반으로 해서 오리지널 둠을터미널에서 아스키모드로 옮겨보려고합니다
      wad파일 컨버팅하고 사운드 그대로 쓰면 어떻게든 될거 같아요
      마우스없이 그냥 키보드만으로 플레이 가능하게 구현해보려고요
      취미로 하는거라 시간은 좀 걸리겠지만 재미있을거 가타요
3개의 좋아요

:rocket: DooM for AntigravitY: Final Blueprint

:milky_way: 1. Project Identity

  • Title: DooM for AntigravitY

  • Concept: Classic Doom Resources + Quake Physics + Zero-G Mechanics.

  • Platform: Linux / WSL (Windows Subsystem for Linux).

  • Environment: GNOME Terminal / Windows Terminal (Recommended).

  • Constraint:

    • Zero-Dependency: Python 3.8+ Standard Library Only (No pygame, numpy, etc).

    • Keyboard Only: No Mouse Support.

    • ASCII Rendering: 100x40 Text Grid Resolution.

:open_file_folder: 2. Project File Structure

​디펜던시 제로 원칙을 지키며 모듈화를 극대화한 구조입니다.

DooM-AntigravitY/
├── assets/ # 외부 리소스
│ ├── DOOM.WAD # 오리지널 둠 WAD 파일 (Shareware or Full)
│ └── config.json # 사용자 설정 (키매핑, 감도, 사운드볼륨)
├── saves/ # 세이브 데이터
│ └── save_slot_1.json # 직렬화된 ECS 상태 덤프
├── src/ # 소스 코드
│ ├── init.py
│ ├── engine.py # 메인 루프 및 터미널 제어 (Entry Point)
│ ├── ecs/ # Entity Component System 코어
│ │ ├── world.py # 엔티티 매니저
│ │ └── components.py # 데이터 클래스 모음 (Pos, Vel, Stats…)
│ ├── systems/ # 게임 로직
│ │ ├── input_sys.py # termios 비차단 입력
│ │ ├── physics_sys.py # 중력, 관성, 충돌 처리
│ │ ├── render_sys.py # 레이캐스팅 및 아스키 버퍼링
│ │ ├── combat_sys.py # 투사체, 대미지, 파괴
│ │ └── sound_sys.py # aplay 프로세스 호출
│ └── utils/ # 유틸리티
│ ├── wad_loader.py # WAD 바이너리 파서 & Scaler
│ └── math_core.py # 삼각함수 및 벡터 연산
├── docs/ # 문서
│ └── GEMINI.md # 본 설계 문서
└── main.py # 실행 스크립트 (src.engine 호출)

:building_construction: 3. ECS Architecture

​데이터(Component)와 로직(System)의 완전한 분리.

:puzzle_piece: Components (Data)

  • Transform: x, y, z, angle (위치)

  • Motion: vx, vy, vz (속도), ax, ay, az (가속도), friction (마찰계수)

  • Body: radius, height (충돌 박스)

  • Stats: hp, armor, ammo, fuel (생존 수치)

  • PhysicsMode: NORMAL | ZERO_G | INVERTED (현재 적용된 물리 법칙)

  • Render: sprite_char (스프라이트), texture_id (벽 텍스처)

:gear: Systems (Logic)

  1. InputSystem: 키보드 입력을 가속도 벡터로 변환.

  2. GravitySystem: PhysicsMode에 따라 중력 가속도(g) 방향 결정.

  3. PhysicsSystem:

    • ​위치 업데이트 (P = P + V).

    • ​벽/천장/바닥 충돌 처리 (반사 벡터 계산).

  4. CombatSystem: 투사체 이동, 피격 판정, 벽 파괴.

  5. RenderSystem: 3D 뷰포트 생성 및 HUD 합성.

:video_game: 4. Gameplay Mechanics

:joystick: Physics Modes (The Core)

  1. Normal Mode:

    • ​g = -9.8. 바닥 마찰력 높음.

    • ​Space 누를 시 부스트 상승.

  2. Zero-G Mode:

    • ​g = 0. 마찰력 거의 없음(0.99).

    • ​벽 충돌 시 튕겨 나감(Bounce). 360도 전방향 이동.

  3. Inverted Mode:

    • ​g = +9.8. 천장이 바닥이 됨.

    • ​렌더링 화면 상하 반전 (Upside Down).

:person_running: Movement Tech

  • Inertia: 즉시 멈추지 않고 미끄러짐. Shift로 달리기 시 관성 증가.

  • Hovering: 부스트(Space)를 짧게 끊어 눌러 고도 유지.

  • Wall Kick: 무중력 상태에서 벽을 차고 반대 방향으로 급가속.

:crossed_swords: Combat & Destruction

  • Ballistics: 투사체 궤적이 중력 모드에 따라 휘어짐 (직선/포물선/역포물선).

  • Targeting: 우하단 발사 → 중앙 조준점 수렴 (Parallax).

  • Strategic Destruction: ‘약한 벽’ 파괴 시 통로 개척 및 파편(Debris) 생성.

:desktop_computer: 5. Engine Specs

:brick: WAD Integration (No Editor Needed)

  • Binary Parsing: struct 모듈로 오리지널 WAD 직접 해석.

  • Auto-Scaling: 맵 로딩 시 모든 섹터의 Ceiling Height에 x2.5 배율 적용.

    • 이유: 오리지널 둠 맵은 낮아서 부스트팩 사용 시 머리를 박기 때문.
  • Texture Mapping: WAD의 텍스처 이름을 아스키 패턴(@%#…)으로 변환.

:artist_palette: Rendering Pipeline

  1. Raycasting: DDA 알고리즘. 수직 시야각(Pitch) 대신 Z-Shearing(Y축 밀기) 기법 사용.

  2. Post-Processing:

    • Shading: 거리별 10단계 명암 (ASCII_RAMP).

    • View Flip: Inverted 모드 시 버퍼 배열 역순 출력.

  3. Double Buffering: 화면 깜빡임 제거를 위한 프레임 버퍼 스와핑.

:speaker_high_volume: Sound

  • Tech: Linux aplay (ALSA) 활용.

  • Implementation: subprocess.Popen을 이용한 Non-blocking(비차단) 사운드 재생.

:white_check_mark: 6. Development Roadmap (Sprint 1)

​1단계: 인프라 구축

  • ​[ ] 100x40 터미널 강제 설정 및 더블 버퍼링 출력.

  • ​[ ] ECS 기본 클래스(World, Entity) 구현.

​2단계: 렌더링 (The Eye)

  • ​[ ] 더미 맵(Python List)을 이용한 레이캐스팅 구현.

  • ​[ ] 2.5배 수직 스케일링 수식 적용 테스트.

​3단계: 물리 (The Body)

  • ​[ ] termios 키보드 입력 처리.

  • ​[ ] 관성 이동 및 부스트 물리 구현.

  • ​[ ] 중력 반전 시 화면 뒤집기 테스트.

몇시간동안 제미나이와 이야기하면서 GEMINI.md를 만들었습니다

바닐라둠에서 제공하는 wad를 컨버팅해서 사용할 생각입니다

이건 이거대로 문제가 될 수 있겠네요

2개의 좋아요

일단 wad파일 불러와 컨버트하고 이걸 터미널에서 렌더링해서 맵을 만드는 단계에 와있습니다.

실 작업 시간은 1시간좀 안됩니다

간단한 이동과 높이개념을 넣어 상하를 볼수 있습니다

아직 맵이 조악해보이는건 wad에서 쓸 타일들을 아스키코드로 대체할때 폰트 지정이 간결하게 처리되어있기때문입니다

여기 명암 좀 더 자세히 구현하면 실제 둠의 wad 파일을 불러와 맵을 돌아다니게 하려고 합니다.

역시나 취미 수준의 작업이니 완성도는 그리 높지는 안을겁니다만 마우스없이 키보드만으로 90년대 초반의 그 충격을 터미널에서 추억에 잠겨 재현하듯 놀 정도는 될겁니다.

목표는 터미널에서 네트웍으로도 둠을 즐겨보자입니다.

무중력모드와 반중력 모드는 작성하는 주된 툴이 안티그래비티라서 넣은 겁니다

일단 주말에 작업할 내용을정리해보았습니다

:rocket: DooM for AntigravitY: Visual & Immersion Blueprint

:artist_palette: 1. Advanced Wall Shading (벽면 쉐이딩 고도화)

​기존의 단순 아스키 그라데이션을 넘어, 유니코드 블록 문자와 노이즈 기법을 도입하여 벽의 **질감(Texture)**과 **깊이감(Depth)**을 극대화합니다.

:brick: Block Element Ramp (블록 문자 램프)

​일반 문자 대신 밀도가 꽉 찬 블록 문자를 사용하여 벽의 견고함을 표현합니다.

  • Ramp Table: 가까움 [“█”, “▓”, “▒”, “░”, " "] 멂.

  • Implementation: 거리(d)에 따라 인덱스를 매핑하되, 정수형 변환 시 내림(floor) 처리.

:fog: Noise Dithering (노이즈 디더링)

​거리에 따른 문자 변화 구간(Band)이 칼처럼 잘리는 '계단 현상’을 제거합니다.

  • Logic: 쉐이딩 단계가 변하는 경계 거리(Threshold) 부근에서, 난수(random())를 발생시켜 인접한 두 단계의 문자를 섞어서 출력합니다.

  • Effect: 벽이 훨씬 더럽고(Gritty) 자연스럽게 그라데이션되는 효과.

:triangular_ruler: Edge & Detail Detection (윤곽선 및 디테일)

​레이캐스팅의 hit_offset(광선이 벽의 1.0 너비 중 어디에 맞았는지) 값을 활용합니다.

  • Vertical Strips: hit_offset이 0.0~0.05 또는 0.95~1.0 (벽의 모서리)일 경우, 거리와 무관하게 진한 문자(| 또는 █)를 출력하여 벽돌/타일의 경계선을 강조합니다.

  • Result: 플레이어 이동 시 벽의 무늬가 스쳐 지나가는 속도감(Motion Perception) 강화.

:astonished_face: 2. Interactive Status Face (반응형 얼굴 HUD)

​화면 하단 중앙에 위치하여, 플레이어의 상태를 직관적이고 감성적으로 전달하는 아스키 아바타 시스템입니다.

:performing_arts: Health States (체력 상태)

​체력(hp) 구간에 따라 얼굴 표정이 영구적으로 변화합니다.

  • 100% ~ 80% (Healthy): ( o _ o ) - 눈동자가 가끔 좌우로 움직이는 Idle 애니메이션 포함.

  • 79% ~ 50% (Hurt): ( - _ - ) - 약간 지침, 입꼬리가 내려감.

  • 49% ~ 20% (Injured): ( > _ < ) - 고통스러움, 이마에 주름(~) 표현.

  • 19% ~ 1% (Critical): ( @ _ @ ) - 정신 혼미, 피 흘림 효과.

  • 0% (Dead): [ x _ x ] - 사망, 고개 꺾임.

:high_voltage: Event Reactions (이벤트 반응)

​특정 게임플레이 이벤트 발생 시 0.5초~1초간 일시적으로 표정을 오버라이드합니다.

  • Evil Grin (무기 획득/학살): ( ^ 皿 ^ ) - 강력한 무기를 들거나 연속 처치 시.

  • Shock (큰 피해): ( 0 ㅁ 0 ) - 한 번에 20 이상의 대미지를 입었을 때.

  • God Mode: ( * _ * ) - 무적 치트 사용 시 눈이 빛남.

:water_pistol: 3. Weapon Realism & Animation (무기 리얼리즘)

​"멈춰있는 텍스트는 가짜다." 아스키 아트에 애니메이션물리적 움직임을 더해 타격감을 구현합니다.

:hammer_and_wrench: Rendering Principle (렌더링 원칙)

  • Overlay Layer: 3D 뷰포트 렌더링이 끝난 후, 우측 하단 버퍼에 투명도(공백 제거)를 적용하여 덮어쓰기.

  • Perspective Art: 총구가 사용자 시선과 일치하도록 원근감이 적용된 사선(\, /) 활용.

:clapper_board: Animation States (상태 머신)

​각 무기는 ECS의 WeaponSystem에 의해 다음 상태를 순환합니다.

A. Shotgun (Example)

  1. IDLE: Bobbing (호흡에 맞춰 1초 주기로 Y좌표 ±1 이동).

  2. FIRE (Frame 1):

    • Muzzle Flash: 총구 앞에 거대한 섬광 텍스트(*, ###) 출력.

    • Recoil: 무기 아스키 전체가 위/뒤(X, Y 오프셋)로 튕겨 올라감.

  3. RELOAD_DOWN (Frame 2~4):

    • ​펌프 액션을 위해 무기가 화면 하단으로 빠르게 내려감.
  4. RELOAD_UP (Frame 5~7):

    • ​"철컥" 소리와 함께 무기가 다시 올라옴.

B. Chainsaw (Special)

  • Idle Vibration: 공격하지 않을 때도 톱날 부분의 문자가 매 프레임 교체됨.

    • ​Frame A: =====+=====

    • ​Frame B: =====#=====

    • Effect: 시각적으로 톱날이 “우웅~” 하고 돌아가는 진동 효과 구현.

C. Chaingun (Special)

  • Spinning Barrel: 발사 중 총신 부분 문자 ( )의 위치를 프레임마다 변경하여 회전하는 착시 유도.

:package: Ammo Display Integration

  • Direct HUD: 별도의 UI 창이 아닌, 무기 아스키 아트 바로 왼쪽 옆에 탄약 수([ 42 ])를 띄워 전투 중 시선 분산을 막음.

:memo: Implementation Priority (구현 우선순위)

  1. Shading Table: 유니코드 블록 문자 SHADE_RAMP 상수 정의.

  2. Face Renderer: hp 변수에 따른 문자열 반환 함수 구현.

  3. Weapon Class: 상태(Idle/Fire/Reload)를 관리하는 Weapon 클래스와 아스키 데이터(ASSETS) 작성.

  4. Shotgun Logic: 발사 → 반동 → 펌프액션으로 이어지는 타이밍 로직 구현.

1개의 좋아요


WAD를 컨버팅한다음 점자로 채웠습니다. 지금 보이는 화면은 코딩은 가짜 벽돌입니다. 이제 여기에 텍스쳐매핑을 해야 합니다. 이제 이 자리에 진짜 둠의 텍스쳐를 집어 넣어야 합니다.

원하는 화면이 나올때까지 계속 왜 그런지 제미나이와 묻고 갈구느라 주말이 다 가버렸네요

2개의 좋아요

점자 타일링을 구현했더니 너무 촘촘합니다. 90년대의 저 해상도에서 저런 고해상도 타일이 나올리 없죠. ㅎ

2개의 좋아요