디시인사이드 갤러리

갤러리 이슈박스, 최근방문 갤러리

갤러리 본문 영역

포켓몬 레드로 보는 과거 FSM과 현대 FSM

ㅆㅇㅆ찡갤로그로 이동합니다. 2025.06.17 07:03:51
조회 404 추천 18 댓글 16
														


viewimage.php?id=3dafdf21f7d335ab67b1d1&no=24b0d769e1d32ca73de883fa11d02831b8cb9d3d20aacaf16d808840f2953b31386213251a0881a75b7ed525083852735bdefe64cfd32c5067494a3fd1111e576eac43beabb4ae


격동의 90년대 수많은 세계의 소년들이 8KB RAM이라는 제약속에서 태초 마을을 떠났다.


그리고 그 소년들은 이제 수십 GB메모리 위에 또다른 세계를 창조한다.


Z80 CPU - 8비트 아키텍쳐의 작업용 RAM(WRAM)


1MB의 카트리지 ROM은 오늘날 고화질 이미지의 한장의 수천분의 일도 되지 않는 것이었다


그리고 그곳에서 시작한 게임은 세계를 놀라게 하였다.


생존 전략- 모든 것은 수작업으로





viewimage.php?id=3dafdf21f7d335ab67b1d1&no=24b0d769e1d32ca73de883fa11d02831b8cb9d3d20aacaf16d808840f2953b31386213251a0881a75b7ed52508383f1e6186ad76beda6c7907f383450f402de9698e9414056c


(디어셈블리 되어서 공유되는 포켓몬 레드)


Game Boy 시절, 개발자는 "코드가 돌아가도록 만드는 것"이 아니라,

64KB 주소 공간에 어떻게든 게임 전체를 욱여넣는 일을 하고 있었다.

자동화도 없고 컴파일러 최적화도 없던 시대, 모든 것은 수작업이었고, 한 줄 한 줄의 어셈블리 코드는 존재 이유와 비용을 계산한 결과였을 것이다.


자, 이제 그 시대의 최적화를 알아야하기 전 우선 우리는 레지스터란 무엇인가에 대해서 알아야한다.






viewimage.php?id=3dafdf21f7d335ab67b1d1&no=24b0d769e1d32ca73de883fa11d02831b8cb9d3d20aacaf16d808840f2953b31386213251a0881a75b7ed525083852735bdefe64cfd32c5067494a6c82164d502c25ed4af5f4b2



(Z80 레지스터 하드웨어 핀 다이어그램)


레지스터란 무엇인가?

레지스터는 CPU 내부에 존재하는 초고속 데이터 저장소로,

연산, 제어 흐름, 메모리 접근 등에 사용되는 작고 빠른 기억장치이다.


그리고 우리는 이 Z80 아키텍쳐로 레지스터에 대해서 서술 할 것이다.


 레지스터는 왜 중요한가?


종류접근 속도사이클 수역할
레지스터매우 빠름(CPU 내부)1~4 cycles즉시 사용 가능,연산 최적화
RAM느림(버스 거침)8~16cycles느린 저장소 보조 역할


이 표만 보아도 레지스터가 훨씬 빠르다.

그런데 왜 레지스터와 RAM을 비교했는가?


우선 그 전에 RAM과 레지스터의 차이에 대해서 알아보자


레지스터는 프로그래머의 눈 앞에 펼쳐진 작업대(WorkBench)이다.

작업대는 매우 비좁고, Z80에서는 7~8개의 도구만 올려둘 수 있었지만, 일단 작업대 위에서 프로그래머는 작업 도구를 빠르게 꺼내 쓸 수 있었다.

즉 그래서 시간(Cycle)이 짧게 걸린다.


하지만 RAM은 프로그래머의 공방을 벗어나야하는 자재창고(WareHouse)이다.

창고는 넓어서 많은 재료(데이터)를 보관 할 수 있지만, 필요한 재료가 생길때마다 프로그래머는 하던 일을 멈추고, 원하는 재료를 가져와야했기에

시간(cycle)이 오래걸린다.


그렇다면 포켓몬 레드에서 '최적화'란 무엇인가? 바로, 이 '창고에 다녀오는 횟수'를 최소화하는 처절한 싸움이다.


굼뜬 Z80 CPU로 프레임이 끊기지 않게 부드러운 화면을 구현하려면, 창고에 가지 않고, 최대한 모든 작업을 작업벤치 위에서


단 8개의 도구를 번갈아가며


흥미를 금세 잃는 어린아이에게 꿈을 주어야만했다


우리는 이제 그 장인의 도구가 어땠는지 볼 것이다.





viewimage.php?id=3dafdf21f7d335ab67b1d1&no=24b0d769e1d32ca73de883fa11d02831b8cb9d3d20aacaf16d808840f2953b31386213251a0881a75b7ed5605d63541935a9783959d08ba0f1e6b3ec5052f6d32858

(장인의 도구 Z80 아키텍쳐의 레지스터)


Z80 레지스터에 대한 설명


레지스터는 단순한 8비트 상자가 아니다


그안은 비트 단위로 의미가 다르게 설계된 고정밀 도구였는데,

특히 Z80은 A,F 레지스터 조합(AF) 안에는 플래그(Flags)라는 연산결과를 추적하는 비트들이 있었다


비트 위치 플래그 이름 의미
7 S (Sign) 결과가 음수인가?
6 Z (Zero) 결과가 0인가?
4 H (Half-Carry) BCD 연산에서 자릿수 올림 여부
2 P/V (Parity/Overflow) 짝수 패리티 or 오버플로
1 N (Add/Sub) 마지막 연산이 뺄셈인가?
0 C (Carry) 자리올림/내림 발생 여부



이들 if문이 없는 Z80에서 조건 분기를 수행하는 핵심이었다.


그리고 여기에 더해서 


레지스터 세트(Re-gister Set) 도구를 가지고 있었는데


A, FA′, F′
B, CB′, C′
D, ED′, E′
H, LH′, L′


그리고 EX AF, AF′ / EXX 명령어로 순간 교체가 가능했다.

즉, 프로그래머는 8개의 레지스터만 가지고 싸운 게 아니라,
‘8개 × 2벌’의 도구를 상황에 맞게 바꿔가며 작업했던 것이다.


그리고 이 도구는 FSM 상태전환으로 사용되며, 전투 루틴, 이벤트 트리거에서 많이 사용되었다.


자, 그럼 이 도구는 어떻게 사용되었을까?




3db28568f5dc3f8650bbd58b3689776a9179f6


(상록시티)


상록시티의 화면과 상록시티에서 쓰인 이벤트 스크립트들이다


그들의 세계는 상태(state)로 구성되어 있었다 


Z80이 가진 한계는 단순히 연산 능력에 그치지 않았다.

"프로그래머는 이벤트를 일일이 기억할 수 없었다."



그 대신 FSM(Finite State Machine, 유한 상태 기계) 이라는 구조가 도입되었다.


FSM이란?


FSM은 현재 상태에 따라 행동이 달라지는 시스템이다.

즉, "지금 뭐 하고 있느냐"에 따라 "다음에 뭘 할 수 있는지"가 정해져 있는 구조이다.


일상적인 가장 간단 FSM 예시: 신호등


현재 상태 조건 다음 상태
빨간불(Red) 30초 경과 초록불(Green)
초록불 30초 경과 노란불(Yellow)
노란불 5초 경과 빨간불(Red)



현재 상태(State): 빨간불, 초록불, 노란불


전이 조건(Condition): 일정 시간 경과


동작(Action): 다음 상태로 전환


신호등은 FSM이다.

현재 색(상태)에 따라 다음 동작(Action)이 정해져있기때문이다.

즉 신호등의 경우 상태(State) 다음 색이 바뀌는 동작(Action)을 가지는 FSM이라고 할 수 있다.


FSM이란 ‘상태(state)’라는 개념을 중심으로 동작을 분리하는 설계 방식이며,

하나의 상태는 하나의 동작을 의미하고, 입력이나 조건에 따라 다음 상태로 넘어간다.


그리고 이것이 우리가 포켓몬을 이해하는 열쇠이다.


FSM이 필요한 이유: '게임의 모든 것'은 상태다

포켓몬 레드를 뜯어보면, 모든 것이 FSM이다.


그중에서 가장 상록시티(영문명: VridianCity)를 예로 들어보자


3db28668efc23f8650bbd58b36807c6d8e1f34

(상록시티 어셈블리 화면)


우선 FSM을 보기전에 포켓몬에서는 어떻게 상태를 옮길까?


FSM의 엔진: 스크립트 포인터 테이블과 디스패처


ViridianCity_Script:

call EnableAutoTextBoxDrawing

ld hl, ViridianCity_ScriptPointers    ; 1. 스크립트 주소 목록의 시작점을 HL에 로드

ld a, [wViridianCityCurScript]      ; 2. '현재 스크립트 번호'를 A에 로드

jp CallFunctionInTable              ; 3. 테이블에서 A번째 함수를 찾아 점프


ViridianCity_ScriptPointers:

def_script_pointers

dw_const ViridianCityDefaultScript,               SCRIPT_VIRIDIANCITY_DEFAULT ; 0번

dw_const ViridianCityOldManStartCatchTrainingScript, SCRIPT_VIRIDIANCITY_OLD_MAN_START_CATCH_TRAINING ; 1번

; ... 등등


이것이 상록시티 이벤트 FSM의 심장이자 엔진이다.


상태 저장 변수(The State) wViridianCityCurScript라는 RAM의 특정소에 저장된 1바이트 값이 FSM의 현재 상태를 결정한다


그리고 디스패쳐(The Dispatcher)인 ViridianCity_Script는 매 게임 틱마다 호출되어 wViridianCityCurScript 값을 확인한다


그리고 점프 테이블 CallFunctionInTable은 wViridianCityCurScript값을 인덱스로 사용하여 ViridianCity_ScriptPointers 테이블에서 실행해야할 실제 스크립트(상태)의 주소를 찾아, 그 주소로 JP(점프)한다.


이는 switch 문을 하드웨어 레벨에서 가장 효율적으로 구현한 방식이다. 긴 if-else 비교 없이, 단 몇번의 연산만으로 정확한 로직 블록으로 실행을 옮겨버린다.


상태(State)와 행동(Action)의 구현


테이블이 가리키는 `ViridianCityDefaultScript` 같은 레이블들이 바로 FSM의 각 '상태'에 해당하는 실제 코드이며,


그리고 그 안의 명령어들이 '행동(Action)'이다


실제 게임상의 코드에서는 이렇게 구현되어있다.


ViridianCityCheckGymOpenScript:

CheckEvent EVENT_VIRIDIAN_GYM_OPEN ; 행동 1: 체육관 오픈 이벤트를 체크

ret nz                             ; 조건이 만족되면(nz), 아무것도 안하고 리턴

; ... (중략) ...

ld a, TEXT_VIRIDIANCITY_GYM_LOCKED ; 행동 2: '문 잠김' 텍스트 ID를 로드

ldh [hTextID], a

call DisplayTextID                 ; 행동 3: 텍스트 출력



여기서 `CheckEvent`나 `DisplayTextID` 같은 `call` 명령어들이 바로 해당 상태에서 수행되는 행동(Action) 이다..


그렇다면 call은 무엇인가?



기본 설명: call의 동작 단계


call SomeLabel


Z80에서 call이 실행되면 다음이 일어난다:


1.현재 PC (Program Counter + 3) 값을 스택에 push

->즉, 다음 명령어 주소를 기억


2.PC를 SomeLabel 주소로 설정

->곧바로 점프한다


3.이후 ret 명령어를 만나면:

->스택에서 PC를 pop

->원래 위치로 되돌아감


이 call이 중요한 것은

이 저수준에서 

행동을 독립적으로 모듈화하는데


call display

call Delay3

등등 각각의 행동이 모듈화된 서브 루틴으로 구현된다.


즉 call은 전화와 같아서, 

call로 함수에게 전화를 걸면, Z80은 전화를 끊은 뒤 다시 돌아갈 장소(주소)를 ㅅ스택에 메모해두고, ret은 전화를 끊고, 다시 돌아가는 것이다.


그리고 이렇게 상태와 행동이 구현된다면 FSM의 가장 중요한 부분인 '상태 변경'은 어떻게 일어날까?


바로 바로 wViridianCityCurScript 변수에 새로운 값을 쓰는 것으로 이루어진다.


스크립트 예시를 보자


플레이어 행동에 의한 전이 (ViridianCityOldManText) 예시:



ViridianCityOldManText:

; ... (대화 출력) ...

call YesNoChoice             ; "예/아니오" 선택지를 띄운다.

ld a, [wCurrentMenuItem]     ; 플레이어의 선택(0=예, 1=아니오)을 A에 로드

and a                        ; A가 0인지(예) 확인

jr z, .refused               ; 0이 아니면(아니오) .refused로 점프


ld hl, .KnowHowToCatchPokemonText ; "예"를 선택했을 경우

call PrintText

    ; === 상태 전이 발생! ===

ld a, SCRIPT_VIRIDIANCITY_OLD_MAN_START_CATCH_TRAINING ; 새 상태(1번) 번호를 A에 로드

ld [wViridianCityCurScript], a                         ; 현재 상태 변수에 덮어쓴다.

jr .done

; ...



플레이어가 "예"를 선택하는 순간, wViridianCityCurScript의 값이 스크립터 포인터내의 SCRIPT_VIRIDIANCITY_DEFAULT(0)에서 SCRIPT_VIRIDIANCITY_OLD_MAN_START_CATCH_TRAINING(1)으로 변경된다.

이로써 상태 전이가 완료되고.

다음 게임 틱에서 디스패처는 이제 ViridianCityOldManStartCatchTrainingScript를 실행하게 되는 것이다.


포켓몬 레드의 루트 기반 상태 머신을 간단하게 요약하면 다음과 같다


MainGameLoop:

    LD A, (wGameMode)

    CP $00

    JP Z, InitBattle


    CP $01

    JP Z, HandleOverworld


    CP $02

    JP Z, HandleMenu


    JP MainGameLoop


포켓몬 레드의 FSM은 다음의 특징을 가진다.


모든 상태는 1바이트 값 (enum 같은 개념)

분기는 CP + JP Z, label 조합
스택 기반 함수 호출이 아닌, 직접 점프 구조
서브 루틴도 가능하면 CALL 대신 JP로 처리하여 스택 사용 최소화

왜 이렇게 짰을까?
Z80의 스택은 RAM 공간을 소모하고, 크기도 작음 (약 128~256 bytes 내외)
CALL → RET 구조는 느리고 오류 위험 존재
그래서 대부분의 FSM은 CP + JP로 플랫 분기 처리 되어있는 것이다.

FSM vs 현대 FSM — 그 구조는 어떻게 바뀌었는가?


3db28768f5dc3f8650bbd58b36837c6973dd

(현대 게임 엔진 대표자중 하나인 Unity의 애니메이션 FSM)



Z80에서의 FSM은 말 그대로 기계 그 자체였다.
상태는 레지스터에 저장된 값
전이는 조건 플래그를 기반으로 점프
행동은 call과 jp로 직접 연결
스택, 함수, 추상화는 최소화

하지만 오늘날의 FSM은 구조적으로 완전히 다르다.

1. 상태는 더 이상 레지스터 값이 아니다

포켓몬의 예시

ld a, [wViridianCityCurScript]
jp CallFunctionInTable

OOP로 구현한 FSM

3db28868efc23f8650bbd58b36807d659e86

상태는 명시적인 Enum

전이는 의미 기반 조건문

리턴 주소를 걱정할 필요도 없다


2. 전이는 조건 플래그가 아닌, 의미적 조건으로 제어된다



포켓몬의 예시

cp 1
jp z, SomeState

OOP로 구현한 FSM



3db28968efc23f8650bbd58b36807569b848


인간 친화적으로 변했고, 유지 보수 용이하게 변했으며




3db28176abd828a14e81d2b628f176658fb17c

동작(Action)또한 모듈화하고, 캡슐화된 함수로

클래스 혹은 스크립트 단위로 행동을 나누게 된것이다.


(일반적으로 FSM 코드는 switch 문으로 구현되지만, C#에서는 Dictionary<State, Action>과 같은 매핑 구조를 사용하여 행동을 등록할 수도 있다.

switch 문은 case 값이 조밀(dense) 하고, enum처럼 연속된 상수 값일 경우 컴파일러가 jump table로 최적화하므로 매우 빠른 분기 성능을 보인다.

반면 Dictionary 방식은 상태 값이 희소(sparse) 하거나, 런타임에 동적으로 상태를 주입/확장해야 하는 경우에 유리하다.

특히 상태 수가 많고, 값들이 일정하지 않을 때는 Dictionary가 더 간결하고 유지보수가 쉬우며, 실행 성능에서도 경쟁력을 가진다.)



 가장 중요한 차이점: 제어권의 흐름


구분Z80 FSM현대 OOP FSM
상태 전이직접 상태 값 변경 (ld [state], a)상태 객체 간 전환 (stateMachine.ChangeState())
흐름 제어jp, call, ret (PC 직접 조작)프레임 기반 Update(), Coroutine, async/await
상태 유지RAM 변수 (wCurScript)클래스 인스턴스, 컨텍스트 객체
디스패치 방식포인터 테이블 + JP가상 함수 호출 / 인터페이스 기반



물론 저마다의 장점이 있었지만 OOP의 방식이 일반적으로 더 확장성이 뛰어났고, 저수준에서의 조작은 갈수록 방대해지는 게임의 크기에서 힘들어졌기때문에

점차 OOP적 FSM을 사용했다


분명히 OOP FSM은 다음과 같은 장점이 있었다


명시적인 상태 클래스


모듈화된 Enter, Update, Exit 함수


가독성이 좋고 유지보수 용이하다는 장점 등등


하지만 그럼에도 불구하고 성능적 병목이 존재하였다.


상태를 전이한다는 것은 무엇인가? 오브젝트가 재생성이 된다는 것이다. 물론 오브젝트 풀링등의 패턴을 사용하지만 이 역시도 어느정도 한계가 있었고 


다음과 같은 성능적 병목들이 존재했다.


한계설명
상태 전이 시 오브젝트 재생성 비용GC/GPU 캐시 무효 발생 가능
Update 함수의 분산 호출CPU Branch Prediction 불리
상태 정보가 여러 객체에 퍼짐데이터 정렬성 손실, 캐시 미스 증가
모바일/대규모 엔티티 대응 어려움병렬화 비효율


즉 OOP FSM은 구조는 아름답지만, 대규모 환경에서 성능적 한계가 명확했다.


그리고 이때 DOP가 등장한다.


DOP란? : Data-Oriented Programming을 말한다.






3db28177abc236a14e81d2b628f1706f8b3ba8a1


DOP FSM의 핵심


상태는 더 이상 "객체"가 아니다.

상태는 "컴포넌트 데이터"이고,

동작은 "시스템(System)"이 책임지게 변한 것이다.


DoP는 OOP가 가진 시스템이 커질수록 생기는 성능상의 병목을 극복하기 위해, 다시 데이터 중심으로 회귀한 프로그래밍 지향으로써 

유니티에서는 ECS라는 이름으로구현된다.


유니티 ECS FSM을 바탕으로 DOP FSM을 구조화하면 다음과 같다.



1. 상태는 구조체로 배열된다

3db28174abd828a14e81d2b628f1766fca1232

이제 상태는 유닛의 필드가 아니라, 전체 유닛 배열의 하나의 열(Column)이 되고


2. 상태 별로 데이터를 선형 필터링하면서 분기하고

3db28175abd828a14e81d2b628f1776e2b8d9d




3. 상태 전이를 '쓰기 연산'으로 구현한다.

3db28172abd828a14e81d2b628f17565da1630


즉 OOP에서 변했던, 객체간의 철학보다는

이제 오히려 과거의 직접적인 기계에 매핑하던 FSM과 유사해지기 시작한 것이다.



특성 (Feature)Z80 FSM (과거)OOP FSM (아름다운 외도)DOP FSM (과거로의 회귀)
상태 표현RAM의 원시 데이터 (byte)객체 (포인터/참조)메모리의 원시 데이터 (struct)
로직 실행순차적 루프 + 점프 (JP)분산된 개별 호출 (virtual Update)순차적 루프 + 조건 (System)
메모리 접근순차적 접근 ([hli])무작위 접근 (포인터 추적)순차적 접근 (배열 순회)
핵심 가치하드웨어 효율성인간의 가독성하드웨어 효율성



 FSM의 진화 3단계

시대구현 방식상태 표현제어 흐름병렬화/성능
Z80 시대레지스터 + 점프RAM 변수JP/RET하드웨어 최적
OOP 시대상태 클래스객체 필드ChangeState()유지보수 최적
현대 실시간 시스템DOP 기반구조체 열(Column)데이터 조건성능 최적





3db28173abd828a14e81d2b628f1716fa267ab


가장 저렴하고, 빠르며, 믿을 수 있는 부품은 존재하지 않는 부품이다. -Golden Bell PDP 컴퓨터 설계자


8KB의 RAM, 부동소수점 연산 불가


포켓몬 개발자들에게 '존재하지 않는 부품'은 부동소수점 연산 유닛이었고, 넉넉한 RAM이었으며, 똑똑한 컴파일러였다..

그들은 '없는 것'을 당연하게 여기고, 오직 있는 것(레지스터와 약간의 메모리)만으로 세계를 빚었다.


유명한 컴퓨터 공학자는 이렇게 말했다


가장 저렴하고, 빠르며, 믿을 수 있는 부품은 존재하지 않는 부품이다.


Bell은 없는 부품이야말로 최선의 부품이라하였지만, 포켓몬의 개발자는 '없는 부품을 코드로 만든다'라고 답했다.


오늘날 우리에게 '존재하지 않는 부품'은 어쩌면 무한한 CPU 캐시와 완벽한 분기 예측일지 모른다.

우리는 풍요로움 속에서 '하드웨어가 당연히 빠를 것'이라 가정하지만,

최고의 성능은 여전히 기계의 동작 원리를 이해하고 그들의 방식으로 데이터를 구성해 줄 때 나타난다.


FSM의 진화는 '인간을 위한 추상화'와 '기계를 위한 최적화' 사이를 오가는 거대한 진자 운동과 같다.

그리고 오늘날 DOP의 모습에서, 우리는 그 둘을 모두 쟁취하려는 현대 개발자들의 새로운 도전을 목격하고 있다.

도구는 변했지만, 주어진 제약 속에서 최고의 경험을 만들어내려는 '장인의 혼'은 그때나 지금이나 변하지 않았던 것이다.


그리고 그때나 지금이나 가장 저렴하고, 빠르며, 믿을 수 있는 부품


프로그래머는 여전히 살아 숨쉬고 있다.



추천 비추천

18

고정닉 3

0

댓글 영역

전체 댓글 0
본문 보기

하단 갤러리 리스트 영역

왼쪽 컨텐츠 영역

갤러리 리스트 영역

갤러리 리스트
번호 제목 글쓴이 작성일 조회 추천
설문 운이 좋아서 따라다니면 콩고물이라도 떨어질 것 같은 스타는? 운영자 25/06/16 - -
2864965 3년 넘게 나님 악질스토킹하는 멍퀴벌레 때문에 [1] ♥냥덩이♥갤로그로 이동합니다. 06.17 59 0
2864964 윤수괴 발끈하는거 재밋지않냐? [4] 헬마스터갤로그로 이동합니다. 06.17 67 0
2864963 c#과 파이썬 openCV 메모리 질문 [2] 프갤러(14.52) 06.17 94 0
2864960 ❤✨☀⭐나님 시작합니당⭐☀✨❤ [3] ♥냥덩이♥갤로그로 이동합니다. 06.17 54 0
2864959 멍유야 리마1급 쉽다 [6] 프갤러(61.43) 06.17 59 0
2864958 돈주면 해외여행 가니깐 지역화폐로 주는거다 [9] 헬마스터갤로그로 이동합니다. 06.17 80 0
2864957 이력서 열람했다 [1] 프갤러(61.43) 06.17 57 0
2864956 나님 주무시러감 ㅇㅅㅇ ㅇㅅㅇ(121.157) 06.17 21 0
2864955 한국이라는 나라 역사가 100년도 안 되는데 ㅇㅇ(106.241) 06.17 34 0
2864954 여러분 제가 뗴인돈 23만원 받을 수 있게 기도해주세요 [7] ㅆㅇㅆ(124.216) 06.17 79 0
2864952 습관적으로 지각하는 개발자 어떡함? [28] 개멍청한유라갤로그로 이동합니다. 06.17 148 0
2864951 24시간째 깨어있고 14시에는 외부 일정까지 있다 [1] ㅇㅇ(106.241) 06.17 30 0
2864950 이재명 씨발새끼야 빨리 25만원 내놔 [5] 아스카영원히사랑해갤로그로 이동합니다. 06.17 84 0
2864949 사람들 앞에서 바지 내리면서 성기 보여주는 자폐아가 투표를 한다는게 [1] ㅇㅇ(106.241) 06.17 43 1
2864948 국민들이 대통령을 투표한다는게 우스운 일이지 [2] ㅇㅇ(106.241) 06.17 37 0
2864947 민주주의가 역겨운 이유중 제일 큰건 ㅇㅇ(106.241) 06.17 30 0
2864946 그건됐고 시발 오늘 아두이노 설계 납품한거 돈 안들어오는줏 ㅆㅇㅆ(124.216) 06.17 33 0
2864945 멍유 어디갔음? [13] 프갤러(61.43) 06.17 78 0
2864944 이재명 결국엔 G7 나가리됐네 ㅉㅉ ㅇㅇ(106.241) 06.17 73 0
2864943 교권 붕괴 운운하는 사람들이 구시대적인 이유 ㅇㅇ(106.241) 06.17 26 1
2864942 포프나 메가유치 같은 사람들 보면 ㅇㅇ(106.241) 06.17 34 0
2864941 21세기 생존기: 기계로부터 흡혈 욕구를 충족시키는 법 루비갤로그로 이동합니다. 06.17 38 0
2864940 여성이 여성성을 버리겠다는게 말이 안 됨 [2] ㅇㅇ(106.241) 06.17 36 0
2864939 특수성 운운하면서 엣지케이스 들고 오는 미친놈들은 [1] ㅇㅇ(106.241) 06.17 39 0
2864938 나는 가시나들이 테스토스테론 분비가 적고 신체적으로 약하다는덴 동의함 [1] ㅆㅇㅆ(124.216) 06.17 50 0
2864937 일반화를 하려하지 않고 특수성을 강조하며 민주주의를 거론 하는 것이 ㅇㅇ(106.241) 06.17 34 0
2864936 흑인이 운동을 잘하고, 여성이 XX를 잘하고는 그냥 기회의 경로 문제임 [2] ㅆㅇㅆ(124.216) 06.17 58 0
2864935 나는 포프햄처럼 웹하는데 어셈블리 하라고 안팔건데 뭔 포프여 ㅆㅇㅆ(124.216) 06.17 42 0
2864934 ㅆㅇㅆ 나중에 김포프같이 되지 않을까? [3] ㅇㅇ(118.235) 06.17 72 0
2864933 아니 애초에 나는 여자가 프로그래밍 못한다는 말에 신뢰를 못하는게 [18] ㅆㅇㅆ(124.216) 06.17 145 1
2864932 여자들 코딩 잘 못한다 = 여자가 무당 잘 믿는다랑 동급임 [1] ㅇㅇ(118.235) 06.17 52 0
2864931 ❤✨☀⭐나님 시작합니당⭐☀✨❤ [1] ♥냥덩이♥갤로그로 이동합니다. 06.17 41 0
2864930 어느 전시회의 그림..ㅇㅅㅇ 헤르 미온느갤로그로 이동합니다. 06.17 24 0
2864929 태연 ㅇㅅㅇ 헤르 미온느갤로그로 이동합니다. 06.17 31 0
2864928 하루 한 번 헤르미온느 찬양 헤르 미온느갤로그로 이동합니다. 06.17 29 0
2864927 노인은 불쌍하고 자라나는새싹들은 불쌍하지않아??? [1] 뒷통수한방(1.213) 06.17 39 0
포켓몬 레드로 보는 과거 FSM과 현대 FSM [16] ㅆㅇㅆ찡갤로그로 이동합니다. 06.17 404 18
2864924 vscode 용 웹스퀘어 확장 만들었다 프갤러(125.191) 06.17 46 0
2864923 얘네 6명 와꾸 순위 어케뎀 ????? [1] ㅇㅇ(210.94) 06.17 79 0
2864922 김문수가 당선된 멀티버스 세계 [1] 야옹아저씨갤로그로 이동합니다. 06.17 63 1
2864921 맥주 500캔 3개면 ㅅㅂ 소주 1병넘네 ㅋㅋㅋㅋㅋㅋㅋ ㅇㅇ(223.38) 06.17 51 0
2864920 뿌랜차이즈 매물 나온거 좀 둘러봣는데아직 사태파악 못하고 여전히 호구 야옹아저씨갤로그로 이동합니다. 06.17 47 0
2864919 야야야야야야야 육개장 컵소면 vs 봉지라명 빨리 ㄱㄱㄱㄱㄱㄱ ㅇㅇ(223.38) 06.17 39 0
2864918 냉정하게 배가 존나게 부른데 라면이 존내게 마렵다 어쩌냐;;; [2] ㅇㅇ(223.38) 06.17 57 0
2864917 시끄럽다. 넥도리아(222.233) 06.17 32 0
2864915 제미나이 코딩 성능 존나 좋은데 뭐임? 프갤러(180.231) 06.17 66 0
2864914 나 어제 걸었다고요. 이재명 대통령 언급할 수 있는 자격 없어요 넥도리아(106.101) 06.17 39 0
2864913 누구도 나를 업신여기지 못함 vs 모두가 나를 좋아함 발명도둑잡기갤로그로 이동합니다. 06.17 31 0
2864912 실수하면 발명도둑잡기갤로그로 이동합니다. 06.17 31 0
2864911 극장판 프로젝트 세카이 부서진 세카이와 전해지지 않는 미쿠의 노래 ㅇㅅㅇ 익명의따당이갤로그로 이동합니다. 06.17 51 0
뉴스 이효리 2세 고민에…“내 주변에 58세에 첫아이 낳은 분 있어” 디시트렌드 06.18
갤러리 내부 검색
제목+내용게시물 정렬 옵션

오른쪽 컨텐츠 영역

실시간 베스트

1/8

뉴스

디시미디어

디시이슈

1/2