Documentation index for AI agents

GS2-Schedule

이벤트 스케줄 기능

게임 내 이벤트 등의 스케줄을 관리하는 기능을 제공합니다.

GS2-Schedule 은 단독으로는 이벤트의 기간 정보만을 관리하는 기능을 가지고 있으며, 보상 지급이나 구매 제한과 같은 처리는 다른 마이크로서비스와 조합하여 실현합니다. GS2-Showcase / GS2-Exchange / GS2-LoginReward / GS2-Mission 등 거의 모든 게임 요소 마이크로서비스가 이벤트 기간과의 연계를 전제로 설계되어 있기 때문에, 기간 한정 운영 시책을 실시할 때 핵심이 되는 마이크로서비스입니다.

이벤트 개최 기간

이벤트 개최 기간에는 두 가지 종류가 있습니다. 첫 번째는 모든 플레이어가 동일한 기간을 공유하는 “절대 기간”, 두 번째는 플레이어마다 기간이 다른 “상대 기간"입니다.

graph TD
  Event["이벤트"]
  Event --> Absolute["절대 기간<br/>(scheduleType = absolute)"]
  Event --> Relative["상대 기간<br/>(scheduleType = relative)"]
  Absolute --> AbsoluteSample["예: 1월 1일~1월 3일의<br/>뉴이어 이벤트"]
  Relative --> RelativeSample["예: 첫 플레이로부터 7일간<br/>첫 보스 격파로부터 24시간"]

절대 기간

“1월 1일~1월 3일에 뉴이어 이벤트를 개최한다"와 같은 경우에 사용하는 기간 유형입니다. 모든 플레이어에게 동일한 개최 기간이 공유되므로, absoluteBegin / absoluteEnd 를 마스터 데이터에서 지정합니다.

상대 기간

“게임 시작으로부터 1주일” 이나 “처음 보스를 쓰러뜨린 후 24시간"처럼, 플레이어에 따라 이벤트 기간이 달라지는 경우에 사용하는 기간 유형입니다.

상대 기간을 실현하기 위한 “트리거"라는 구조가 있습니다. 트리거를 실행한 후, 지정된 기간(ttl)이 이벤트의 개최 기간으로 취급됩니다.

Gs2Schedule:TriggerByUserId 액션

트리거를 당기는 방식의 종류

트리거를 당길 때, 이미 트리거가 당겨져 있는 경우 이벤트 기간을 지정하는 방식에는 여러 가지가 있습니다.

  • 트리거를 재기동한다(renew)
  • 트리거를 연장한다(extend)
  • 아무것도 하지 않는다(drop)
  • 이벤트의 반복 종료 일시에 유효 기간이 만료된다(repeatCycleEnd)
  • 다음 반복 시작 일시에 유효 기간이 만료된다(repeatCycleNextStart)
  • 절대 기간 이벤트의 종료 일시에 유효 기간이 만료된다(absoluteEnd)

repeatCycleEnd / repeatCycleNextStart / absoluteEnd 는 반복 설정이나 절대 기간을 가진 이벤트에 맞춰 유효 기간을 자동으로 조정하는 방식입니다.

2020년 1월 1일 00:00 에 트리거를 당겨 7일간의 상대 기간 이벤트가 시작된 경우, 2020년 1월 3일 00:00 에 트리거를 다시 당겼을 때의 각 동작은 다음과 같습니다.

방식이벤트 종료 일시
renew2020년 1월 10일 00:00트리거를 기동한 시점인 2020년 1월 3일 00:00 에 7일간을 추가
extend2020년 01월 14일 00:00이미 존재하는 트리거의 유효 기간인 2020년 1월 7일 00:00 에 7일간을 추가
drop2020년 01월 7일 00:00이미 존재하는 트리거를 그대로 유지

반복 설정

절대 기간·상대 기간 모두, RepeatSetting 을 조합함으로써 “특정 요일이나 시간대에만 유효”, “며칠 주기로 유효·무효를 전환"과 같은 반복 스케줄을 표현할 수 있습니다.

설정 가능한 반복 유형은 다음과 같습니다.

repeatType설명
always기간 중 항상 유효
daily매일 지정 시각~지정 시각 사이에만 유효(beginHour / endHour)
weekly매주 지정 요일~지정 요일 사이에만 유효(beginDayOfWeek / endDayOfWeek)
monthly매월 지정일~지정일 사이에만 유효(beginDayOfMonth / endDayOfMonth)
custom임의의 주기 일수로 유효·무효를 반복(anchorTimestamp / activeDays / inactiveDays)

custom 유형은 “앵커 일시로부터 3일간 유효·4일간 무효"와 같은 임의의 반복 주기를 표현할 수 있어, 변칙적인 상시 이벤트 설계에 유용합니다.

반복 스케줄 상태 취득

반복 설정을 가진 이벤트에 대해서는 현재 및 직전 반복 주기의 시작 일시·종료 일시를 RepeatSchedule 로 취득할 수 있습니다. 이를 통해 현재 주기 내에서 보상을 몇 번 수령했는지에 대한 집계나, 다음 주기까지의 남은 시간 표시가 가능합니다.

트랜잭션 액션

GS2-Schedule 에서는 다음의 트랜잭션 액션을 제공합니다.

  • 검증 액션: 이벤트 개최 기간 중 검증, 이벤트 기간 외 검증, 트리거가 당겨져 있는지 검증, 트리거가 당겨져 있지 않은지 검증, 트리거를 당긴 후 경과 시간 검증
  • 소비 액션: 트리거 삭제
  • 입수 액션: 트리거 실행, 트리거 기간 연장

“이벤트 개최 기간 검증"을 검증 액션으로 이용함으로써, 특정 이벤트 기간 중에만 구매 가능한 상품이나 기간 한정 교환소와 같은 제한을 트랜잭션 내에서 안전하게 마련할 수 있습니다. 또한 “트리거 실행"을 입수 액션으로 이용함으로써, 퀘스트 클리어 시나 아이템 입수 시에 해당 플레이어만의 기간 한정 이벤트(상대 기간)를 시작시키는 등, 동적인 게임 경험 제어가 쉬워집니다.

마스터 데이터 관리

마스터 데이터를 등록함으로써 마이크로서비스에서 사용 가능한 데이터나 동작을 설정할 수 있습니다.

마스터 데이터의 종류에는 다음이 있습니다.

  • EventMaster: 이벤트 기간과 반복 설정

다음은 마스터 데이터의 JSON 예시입니다.

{
  "version": "2019-03-31",
  "events": [
    {
      "name": "newyear-2026",
      "metadata": "신년 이벤트",
      "scheduleType": "absolute",
      "absoluteBegin": 1735660800000,
      "absoluteEnd": 1735920000000,
      "repeatType": "always"
    },
    {
      "name": "tutorial-bonus",
      "metadata": "최초 플레이로부터 7일간 한정",
      "scheduleType": "relative",
      "relativeTriggerName": "tutorial-clear",
      "repeatType": "always"
    }
  ]
}

마스터 데이터의 등록은 관리 콘솔에서 등록하는 것 외에도, GitHub에서 데이터를 반영하거나, GS2-Deploy를 사용하여 CI에서 등록하는 워크플로우를 구성할 수도 있습니다.

구현 예제

트리거 당기기

트리거를 당기는 처리는 게임 엔진용 SDK 에서는 처리할 수 없습니다.

GS2-Account 의 계정 생성 시 스크립트 내에서, 또는 GS2-Quest 의 클리어 보상으로 트리거를 당기는 방법 등으로 구현하십시오.

개최 중인 이벤트 목록 취득

현재 플레이어 기준으로 개최 중인 이벤트만 반환됩니다. 절대 기간으로 개최 중이거나, 상대 기간으로 트리거가 당겨져 유효 기간 내에 있는 이벤트가 해당합니다.

    var items = await gs2.Schedule.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).EventsAsync(
    ).ToListAsync();
    const auto Domain = Gs2->Schedule->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        AccessToken
    );
    const auto It = Domain->Events(
    );
    TArray<Gs2::UE5::Schedule::Model::FEzEventPtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }
var iterator = ez.schedule.namespace_(
        "namespace-0001"
    ).me(
        game_session
    ).events(
    )

var async_result = await iterator.load()
if async_result.error != null:
    # 에러를 처리
    push_error(str(async_result.error))
    return

var items = async_result.result

특정 이벤트의 정보 취득

특정 이벤트 이름을 지정하여, 해당 이벤트의 개최 기간이나 반복 설정을 취득합니다. isInScheduletrue 로 하면 현재 개최 중인 이벤트만, false 로 하면 마스터 데이터에 등록된 모든 이벤트를 참조할 수 있습니다.

    var item = await gs2.Schedule.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Event(
        eventName: "event-0001"
    ).ModelAsync();
    const auto Domain = Gs2->Schedule->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        AccessToken
    )->Event(
        "event-0001" // eventName
    );
    const auto Item = Domain->Model();
var domain = ez.schedule.namespace_(
        "namespace-0001"
    ).me(game_session).event(
        "event-0001"
    )

var async_result = await domain.model()
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

트리거 목록 취득

플레이어에게 당겨져 있는 상대 기간 트리거의 목록과 유효 기간을 취득할 수 있습니다.

    var items = await gs2.Schedule.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).TriggersAsync(
    ).ToListAsync();
    const auto Domain = Gs2->Schedule->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        AccessToken
    );
    const auto It = Domain->Triggers(
    );
    TArray<Gs2::UE5::Schedule::Model::FEzTriggerPtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }
var iterator = ez.schedule.namespace_(
        "namespace-0001"
    ).me(
        game_session
    ).triggers(
    )

var async_result = await iterator.load()
if async_result.error != null:
    # 에러를 처리
    push_error(str(async_result.error))
    return

var items = async_result.result

반복 스케줄 상태 취득

반복 설정을 가진 이벤트의 현재 반복 주기 정보를 취득합니다. 반복 횟수나, 현재 주기의 시작 일시·종료 일시, 직전 주기의 종료 일시를 확인할 수 있습니다.

    var item = await gs2.Schedule.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Event(
        eventName: "event-0001"
    ).RepeatSchedule(
    ).ModelAsync();
    const auto Domain = Gs2->Schedule->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        AccessToken
    )->Event(
        "event-0001" // eventName
    )->RepeatSchedule(
    );
    const auto Item = Domain->Model();
var domain = ez.schedule.namespace_(
    "namespace-0001"
).me(game_session).event(
    "event-0001"
).repeat_schedule()
var async_result = await domain.model()
if async_result.error != null:
    push_error(str(async_result.error))
    return
var item = async_result.result

상세 레퍼런스