사전 틱
개념

틱

gabury1고친 사람 github-actions[bot]

틱은 프로그램 속 시간을 같은 간격으로 끊은 한 칸입니다. 프로그램은 그 한 칸마다 정해 둔 일을 한 번 합니다. 게임 서버는 틱마다 게임 속 세계를 한 걸음 앞으로 넘깁니다. 운영체제가 타이머로 시간을 셀 때도 그 한 칸을 틱이라 부릅니다.

쉽고 빠른 이해

무슨 일을 하나 — 시간을 같은 간격으로 끊습니다. 그 박자마다 할 일을 한 번 하게 합니다. 1초에 20번 박자가 오는 게임 서버는 0.05초마다 플레이어들의 입력을 모아 게임 속 세계를 한 번 고칩니다.

왜 이렇게 하나 — 게임 속 세계는 아무도 조작하지 않아도 움직입니다. 던진 공은 누군가 계속 옮겨 줘야 합니다. 입력이 올 때마다 제각각 계산하면 입력이 도착한 순서에 따라 결과가 달라집니다. 박자를 하나로 정해 두면 모든 계산이 같은 박자에 맞춰 돕니다. 같은 박자에 들어온 입력은 같은 시각에 반영됩니다.

어떻게 도나

  1. 박자의 간격을 정합니다. 1초에 20번이면 간격은 0.05초입니다
  2. 박자가 오면 그동안 들어온 입력을 모아 세계를 한 번 고칩니다
  3. 고친 결과를 플레이어들에게 보냅니다. 박자 번호를 하나 올립니다

대가 — 입력은 다음 박자까지 기다렸다가 반영됩니다. 박자를 촘촘히 하면 기다림이 줄어듭니다. 대신 서버가 1초에 할 계산과 보낼 데이터가 늘어납니다. 한 박자의 계산이 간격보다 오래 걸리면 게임 전체가 느려집니다. 상태가 입력으로만 바뀌는 웹 서버나 바둑 게임에는 이 대가를 치를 까닭이 없습니다.

상세

먼저 틱이 무엇인지 장면 하나로 잡습니다. 그다음 게임 서버가 틱으로 도는 까닭, 한 틱 안에서 하는 일, 화면을 그리는 박자와의 차이, 1초에 돌 틱 수를 고르는 기준을 차례로 봅니다. 끝에서는 운영체제와 시계를 다루는 코드가 같은 이름을 어떤 뜻으로 쓰는지 짚습니다.

행진하는 악대를 떠올려 봅니다. 북이 한 번 울릴 때마다 모두가 한 걸음씩 내딛습니다. 먼저 걷고 싶은 사람도 다음 북소리를 기다립니다. 줄이 흐트러지지 않는 까닭입니다.

틱(tick)은 원래 시계가 똑딱이는 소리를 흉내 낸 말입니다. 프로그램에서는 같은 간격으로 돌아오는 박자 하나를 틱이라 부릅니다. 그 박자에 맞춰 하는 일 한 번도 같은 이름으로 부릅니다. 앞의 악대로 치면 북소리 한 번이 틱입니다. 걸음 하나는 그 틱에 하는 일입니다.

예를 들어 1초에 20번 박자가 오는 게임 서버는 0.05초마다 틱 하나를 돕니다. 틱마다 날아가는 공을 한 걸음 옮깁니다. 플레이어가 그사이 누른 키도 이때 반영합니다.

같은 이름의 세 쓰임

틱이라는 말은 세 분야에서 쓰입니다. 셋 다 시간을 같은 칸으로 끊어 센다는 점에서 만납니다. 칸 하나가 무엇이고 그 칸에 무슨 일을 하는지가 다릅니다.

분야 틱 하나가 뜻하는 것 틱마다 하는 일
게임과 시뮬레이션 세계를 한 번 고치는 박자 입력을 모으고 세계를 한 걸음 넘긴다
운영체제 하드웨어 타이머가 한 번 울리는 박자 지난 시간을 세고 실행할 프로그램을 다시 고른다
시계를 다루는 코드 시계가 셀 수 있는 가장 짧은 시간 시각을 그 칸의 개수로 적는다

게임 서버가 틱으로 도는 까닭

웹 서버는 대개 요청이 올 때만 일합니다. 요청 하나를 받아 응답을 돌려주면 그 일은 끝납니다. 요청이 없으면 서버가 쥔 상태도 바뀌지 않습니다.

게임 서버는 사정이 다릅니다. 아무도 키를 누르지 않아도 던진 공은 계속 날아갑니다. 시간이 흐르는 것만으로 세계가 바뀝니다. 그래서 누군가 시간을 정기적으로 흘려보내야 합니다.

입력이 올 때마다 바로 계산할 수도 있습니다. 그러면 두 플레이어의 입력이 몇 밀리초 차이로 도착했는지에 따라 결과가 갈립니다. 같은 장면도 도착 순서가 바뀌면 다른 결과가 나옵니다.

틱은 두 문제를 함께 풉니다. 서버는 정한 간격마다 세계를 한 번 넘깁니다. 그 사이에 도착한 입력은 모아 두었다가 다음 틱에 한꺼번에 반영합니다.

한 틱에 모인 입력은 모두 같은 게임 시각에 반영됩니다. 몇 밀리초 먼저 왔는지는 그 틱 안에서 지워집니다. 세계가 틱 단위로만 바뀌니 결과도 틱 단위로 정해집니다.

한 틱 안에서 하는 일

틱 한 번은 대개 세 단계를 차례로 밟습니다. 먼저 입력을 모읍니다. 그다음 세계를 계산합니다. 마지막으로 결과를 보냅니다. 아래 그림은 플레이어 둘과 서버 하나가 101번째 틱을 지나가는 순서입니다.

sequenceDiagram
    participant A as 플레이어 A
    participant 서버
    participant B as 플레이어 B
    A->>서버: 입력 · 오른쪽으로 이동
    B->>서버: 입력 · 공 던지기
    Note over 서버: 틱 101 · 모인 입력을 반영하고 세계를 한 칸 넘긴다
    서버->>A: 틱 101의 세계 상태
    서버->>B: 틱 101의 세계 상태

서버는 틱과 틱 사이에 들어온 입력을 쌓아 둡니다. 틱이 오면 쌓인 입력을 반영합니다. 그다음 시간이 한 칸 흐른 만큼 세계를 계산합니다. 날아가던 공은 한 칸만큼 더 갑니다.

마지막으로 바뀐 세계 상태를 플레이어들에게 보냅니다. 세계 상태는 그 틱의 모든 물체의 위치와 속도 같은 값의 모음입니다. 플레이어의 화면은 이 값을 받아 그립니다.

세계를 한 칸 넘기는 계산 가운데 물체의 움직임과 충돌을 맡는 부분이 물리 스텝입니다. 서버는 틱 하나에 물리 스텝 하나를 맞추는 일이 흔합니다. 둘을 같은 말로 부르기도 합니다.

틱과 프레임

게임은 게임 루프라는 반복문 안에서 돕니다. 한 바퀴에 입력 읽기 · 세계 고치기 · 화면 그리기를 차례로 합니다.

화면에 그린 한 장이 프레임입니다. 1초에 그리는 장 수는 프레임률입니다. 프레임률은 컴퓨터 성능과 장면의 복잡도에 따라 오르내립니다.

한 바퀴에 둘이 다 들어 있어도 틱은 프레임과 따로 셀 수 있습니다. 세계를 고치는 간격을 고정해 두는 방식이 고정 타임스텝입니다. 루프는 한 바퀴 돌 때마다 지난 시간을 잽니다. 틱 간격만큼 시간이 쌓였을 때만 세계를 고칩니다.

화면을 자주 그리는 컴퓨터에서는 루프가 여러 바퀴 도는 동안 틱이 한 번도 안 돌기도 합니다. 한 바퀴가 틱 간격보다 오래 걸리는 컴퓨터에서는 한 바퀴에 밀린 틱을 여러 번 돌립니다. 1초당 틱 수는 늘 같습니다. 프레임 수만 컴퓨터마다 달라집니다. 두 박자를 견주면 이렇습니다.

틱 프레임
하는 일 세계 상태를 한 칸 넘긴다 화면을 한 장 그린다
1초에 몇 번 정해 둔 수로 고정 컴퓨터 성능을 따라 바뀐다
어디서 도나 세계를 계산하는 컴퓨터(온라인 게임이면 서버) 화면이 있는 플레이어의 컴퓨터

1초에 틱이 30번이고 프레임이 120장이면 틱 하나 사이에 화면이 네 장 그려집니다. 네 장이 모두 같은 그림이면 움직임이 뚝뚝 끊겨 보입니다.

보간은 두 값 사이의 값을 계산해 채우는 일입니다. 플레이어의 컴퓨터는 직전 두 틱의 결과 사이를 보간해서 네 장을 서로 다른 그림으로 그립니다.

틱레이트

1초에 도는 틱 수가 틱레이트(tick rate)입니다. 틱레이트가 높을수록 세계를 더 자주 고칩니다.

틱레이트는 헤르츠(hertz, Hz)로 적습니다. 헤르츠는 1초에 몇 번인지를 뜻하는 단위입니다. 틱레이트 20 Hz 는 1초에 틱 20번이라는 뜻입니다.

틱 간격은 1초를 틱레이트로 나눈 값입니다. 아래는 20 Hz 와 60 Hz 의 간격을 밀리초로 구한 계산입니다.

JavaScript
const rate = 20;         // 1초에 20틱
1000 / rate;             // 50 ms
const rate2 = 60;        // 1초에 60틱
1000 / rate2;            // 약 16.7 ms

틱레이트를 세 배로 올리면 간격은 3분의 1로 줄어듭니다. 입력이 다음 틱까지 기다리는 시간도 그만큼 줄어듭니다.

틱레이트를 공짜로 올릴 수는 없습니다. 세 가지가 함께 움직입니다.

틱레이트를 높이면 틱레이트를 낮추면
입력이 반영되기까지 기다림 짧아진다 길어진다
서버가 1초에 하는 계산 늘어난다 줄어든다
플레이어에게 보내는 데이터 늘어난다 줄어든다

그래서 반응 속도가 승패를 가르는 대전 게임일수록 틱레이트를 높게 잡습니다. 한 세계에 사람이 아주 많이 모이는 게임은 서버 부담 탓에 낮게 잡기도 합니다.

틱 번호

서버는 틱을 돌 때마다 번호를 하나씩 올립니다. 게임이 시작하고 몇 번째 틱인지가 곧 게임 속 시각입니다. 틱 번호에 틱 간격을 곱하면 시각이 나옵니다. 아래는 0.05초 간격으로 1200틱을 돈 서버의 시각입니다.

JavaScript
const dt = 50;       // 틱 간격 50 ms
const tick = 1200;   // 지금까지 돈 틱
tick * dt;           // 60000 ms, 1분

게임 속 시각은 소수를 더해 가지 않고 정수인 틱 번호로 셉니다. 컴퓨터가 소수를 나타내는 방식인 부동소수점은 0.05 같은 수를 딱 떨어지게 담지 못합니다. 0.05를 수만 번 더하면 작은 오차가 쌓입니다. 정수는 몇 번을 더해도 오차가 생기지 않습니다.

틱 번호는 사건에 붙이는 이름표도 됩니다. 「틱 1201에 플레이어 A가 점프했다」처럼 적을 수 있습니다.

결정성은 같은 처음 상태에 같은 입력을 넣으면 같은 결과가 나오는 성질입니다. 계산이 이 성질을 지키면 틱 번호와 입력만 적어 두어도 장면을 되살릴 수 있습니다.

게임의 리플레이를 이렇게 만들 수 있습니다. 화면을 영상으로 담지 않아도 틱마다 들어온 입력 기록만으로 경기를 다시 계산해 보여 줍니다.

틱이 간격 안에 못 끝날 때

틱 하나의 계산은 틱 간격 안에 끝나야 합니다. 20 Hz 서버라면 0.05초 안입니다. 플레이어가 몰려 한 틱에 0.08초가 걸리면 다음 틱이 제때 시작하지 못합니다.

그러면 서버는 1초에 20틱을 다 돌지 못합니다. 게임 속 시간이 바깥 시간보다 느리게 흐릅니다. 플레이어 눈에는 세계가 굼뜨게 움직입니다.

서버는 게임 속 시간을 바깥 시간에 다시 맞추려 합니다. 그러려면 밀린 틱을 한꺼번에 돌려 따라잡아야 합니다. 그 계산이 다시 간격을 넘기면 서버는 점점 더 뒤처집니다. 이 되먹임이 죽음의 나선입니다.

그래서 서버는 틱 하나에 걸린 시간을 재서 지켜봅니다. 간격을 넘기는 틱이 잦으면 틱레이트를 낮추거나 한 서버가 받는 인원을 줄입니다.

운영체제의 틱

운영체제도 틱이라는 말을 씁니다. 같은 간격으로 오는 박자 하나라는 뜻은 같습니다. 다른 점은 그 박자를 하드웨어가 만든다는 것입니다.

컴퓨터에는 정해 둔 간격마다 신호를 보내는 하드웨어 타이머가 있습니다. 운영체제는 이 신호를 박자로 삼습니다.

인터럽트는 하던 일을 끊고 급한 일을 먼저 처리하게 하는 신호입니다. 인터럽트가 오면 CPU(Central Processing Unit, 중앙 처리 장치)는 하던 일을 잠깐 멈춥니다. 그 신호를 맡은 운영체제의 코드를 먼저 부릅니다.

하드웨어 타이머가 보내는 인터럽트가 타이머 인터럽트입니다. 운영체제의 틱은 타이머 인터럽트 한 번입니다.

운영체제의 핵심부인 커널은 틱마다 두 가지 일을 합니다. 첫째는 시간 세기입니다. 부팅한 뒤 지난 틱 수를 세어 두면 틱 간격을 곱해 지난 시간을 압니다. 잠든 프로그램을 깨울 시각이 됐는지도 이때 봅니다.

둘째는 실행할 프로그램 다시 고르기입니다. 여러 프로그램이 CPU 하나를 나눠 쓸 때 한 프로그램이 CPU를 오래 붙잡으면 나머지가 멈춥니다. 그래서 프로그램마다 한 번에 쓸 시간을 정해 줍니다. 이 시간이 타임 슬라이스입니다.

커널은 틱마다 지금 프로그램이 타임 슬라이스를 다 썼는지 봅니다. 다 썼으면 다른 프로그램으로 바꿉니다. 다음에 실행할 프로그램을 고르는 이 일이 스케줄링입니다.

틱은 할 일이 없을 때도 옵니다. CPU는 쉬는 중에도 박자마다 깨어나야 해서 전기를 씁니다.

그래서 할 일이 없는 동안에는 틱을 멈추는 방식이 있습니다. 타이머는 다음 일이 있는 시각에만 겁니다. 이 방식을 틱리스 커널(tickless kernel)이라 부릅니다.

시계를 다루는 코드의 틱

시계를 다루는 코드에서 틱은 그 시계가 셀 수 있는 가장 짧은 시간을 뜻하기도 합니다. 백엔드 개발자가 흔히 만나는 예는 로그나 데이터베이스에 큰 정수로 적힌 타임스탬프입니다.

이 정수는 정해 둔 기준 시각에서 틱이 몇 개 지났는지를 셉니다. 출발점으로 삼는 이 기준 시각이 에포크입니다. 1틱이 1000분의 1초인 시계에서 에포크로부터 5000틱이 지났다면 5초가 지난 것입니다.

1틱의 길이는 시계와 라이브러리마다 다릅니다. 1000분의 1초로 세는 시계가 있습니다. 100만분의 1초로 세는 시계도 있습니다. 틱 수를 주고받을 때는 1틱이 얼마인지를 함께 알아야 합니다.

보내는 쪽이 100만분의 1초 단위로 5초를 적으면 5000000틱입니다. 받는 쪽이 이 값을 1000분의 1초 단위로 읽으면 5000초, 약 1시간 23분이 됩니다. 시각이 천 배 멀리 어긋납니다.

틱을 쓰는 곳과 안 쓰는 곳

틱은 시간이 흐르는 것만으로 상태가 바뀌는 프로그램에 맞습니다. 물체가 움직이는 게임 서버와 시뮬레이션이 그렇습니다. 정해 둔 간격으로 센서를 읽는 제어 프로그램도 그렇습니다.

상태가 입력으로만 바뀌는 프로그램에는 틱이 필요 없습니다. 한 수씩 두는 바둑이나 카드 게임은 수가 들어올 때만 계산하면 됩니다. 요청을 받아 응답하는 웹 서버도 같습니다. 이런 프로그램에 틱을 두면 아무 일 없는 박자마다 서버가 헛돕니다.

한 프로그램 안에서 둘을 섞기도 합니다. 채팅이나 아이템 구매처럼 입력에만 반응하는 기능은 요청이 올 때 처리합니다. 세계의 움직임만 틱으로 돌립니다.

관련 항목

틱을 돌리는 반복 구조와 시간 관리 방식

게임 루프 · 고정 타임스텝 · 가변 타임스텝 · 타임스텝 · 델타 타임 · 물리 스텝 · 틱 그룹

틱의 빠르기를 재는 지표

틱레이트 · 헤르츠 · 프레임률 · 프레임 시간 · 프레임 예산 · 지연

틱의 결과를 화면에 옮기는 기법

프레임 · 보간 · 외삽 · 렌더링 · 주사율

틱 번호에 기대는 네트워크 게임 기법

결정성 · 리플레이 · 락스텝 · 클라이언트 측 예측 · 롤백 넷코드 · 지연 보상

틱 시각을 담는 수 표현

부동소수점 · 고정소수점 · 정수 오버플로 · 반올림 오차

틱이 밀릴 때 나는 장애

죽음의 나선 · 스터터링 · 프레임 드롭 · 러버밴딩

운영체제가 틱으로 굴리는 장치와 기능

하드웨어 타이머 · 인터럽트 · 타이머 인터럽트 · 커널 · 스케줄링 · 타임 슬라이스 · 문맥 교환 · 틱리스 커널 · jiffies

틱을 시간 단위로 세는 시계 개념

시간과 시계 · 에포크 · 타임스탬프 · 유닉스 시간 · 단조 시계 · 시계 해상도

틱이 속하는 상위 분류

게임 개발 · 게임 서버 · 운영체제 · 시뮬레이션 · 실시간 시스템

다른 이름: tick · 게임 틱 · game tick · 서버 틱 · server tick · 시뮬레이션 틱 · 클럭 틱 · clock tick · 타이머 틱