Skip to content

Tournaments and Faction War Settings

Lost Saga has two linked events. The regular tournament (LS Cup) is a bracket of teams. Faction War (the code calls it camp or region) is a blue against red season where every player joins one side. The tournament panel shows both. This guide covers the server files, the database row you must create, and the client side.

All file names come from the code that loads them. Anything marked not confirmed yet was not verified in code or config.

Part File Runs on Loaded by
Tournament schedule, size, titles sp2_tournament_regular.ini main server TournamentNode::LoadINI
Faction season and names sp2_camp.ini main server CampManager::LoadINIData
Tournament rewards by date regular_tournament_reward.ini game server TournamentManager::LoadINI
Reward tables (items, pesos) regular_tournament_reward_table.ini game server TournamentManager::LoadINI
Custom tournament item prices sp2_custom_tournament_reward.ini game server TournamentManager::LoadINI
Look, banners, reward text sp2_regular_tournament.ini, sp2_camp.ini and more client config\ client managers
Running state userLeagueListDB and related tables database game_league_* procedures

The main server files are in ls_mainsvr\config\, the game server files in ls_gamesvr\config\. The main server and the game server each have their own sp2_camp.ini. They are different files. The game server copy only holds a LastSeasonDate line. Whether the game server reads it: not confirmed yet (no loader found in the 2021 game server source).

Step 1: Create the first tournament in the database

Section titled “Step 1: Create the first tournament in the database”

The main server only continues a tournament row that exists. Nothing creates the first one (comment in the testbed scripts). Without a row the tournament panel stays empty.

  1. Check userLeagueListDB for a row with leagueType = 1 (regular).
  2. If there is none, insert one. The testbed script for 2019 is 910_first_tournament.sql, and for 2014 11_LS14_first_tournament.sql. They insert accountIDX = 0, leagueType = 1, leagueState = 1 (team sign-up), a start date on the last Monday at 03:00 and an end date 336 hours later.
  3. Dates are stored as YYMMDDHHMM in a DWORD (Help::ConvertCTimeToDate). Since 2022 the number is above the int range of the column, so the scripts store the wrapped value. The server reads the same bits back. Use the script as a template instead of typing a date by hand.
  4. When the period ends, TournamentNode::Process calls SetNextTournament and starts the next one by itself. The next one uses the [default] section of sp2_tournament_regular.ini.

Differences:

  • 2014 and 2019: the testbeds ship the seed script (above).
  • 2021: the testbed scripts have game_league_list_add but no seed row. Whether the 2021 testbed shows the panel without one: not confirmed yet.
  • Ids in ls_query.ini: 2019 game_league_list, 2020 game_league_list_save, 2021 to 2061 team, round and reward procedures, 2084 to 2088 cheer procedures.

Open sp2_tournament_regular.ini on the main server. The keys in [default] are read in TournamentNode::LoadINI.

[default]
next_tournament_hour = 336
start_tournament_team_count = 256
tournament_max_round = 8
adjust_cheer_team_peso = 20000
adjust_cheer_user_peso = 20000
state_team_app_end_minute = 15659
state_team_delay_end_minute = 17820
max_tournament = 8
state_tournament_start_minute_1 = 17930
state_tournament_end_minute_1 = 17940
resource_type = 1
max_player = 3
play_mode = 2
title = <tournament name>
blue_camp_name = <name>
red_camp_name = <name>
Key Meaning
next_tournament_hour Length of one tournament in hours (336 = 14 days)
start_tournament_team_count, tournament_max_round Bracket size and number of rounds. Shipped 256 and 8 (256 is 2 to the power 8, so keep them consistent; inferred)
state_team_app_end_minute Team sign-up ends this many minutes after the start
state_team_delay_end_minute Cheering (betting) period ends at this minute
state_tournament_start_minute_N, _end_minute_N Start and end minute of match day N. max_tournament is how many are read
max_player Players per team (shipped 3)
play_mode Game mode index (BMT). See the sp2_mode_select.ini mentioned in the file
resource_type Picks the [resourceN] block in the client file
disable_tournament 1 shows “the tournament is resting” instead of the event
adjust_cheer_*_peso Base pesos for the winning cheering team and users

To change one tournament only, add a section named with its start date, for example [2101040300], with resource_type, max_player, play_mode, title, blue_camp_name, red_camp_name, disable_tournament and the cheer values. The loader looks for the section whose name is the current start date and overrides the defaults with it.

The file says: edit the [default] section, then restart the main server, and the running tournament takes the new values. Minutes are counted from the start of the tournament. Live reload: not confirmed yet.

sp2_league.ini ([next_league], season times) is also in the main server folder, but no loader for it was found in the 2021 main server code. Treat it as unused. sp2_tournament_backup.ini is a temporary record the server writes itself (its first line says so). Do not edit it.

Rewards live on the game server.

  1. In regular_tournament_reward.ini, [common] has max_load and load_date_N lines. Each load_date_N is a tournament start date (same YYMMDDHHMM number as in the database). A section with that name holds:

    ; example, table numbers point to [tableN] in the reward table file
    [2101040300]
    max_round_reward = 9
    reward_table1 = 1
    camp_blue_win_table = 1
    camp_blue_lose_table = 2
    camp_red_win_table = 3
    camp_red_lose_table = 4
    camp_draw_table = 5

    reward_tableN is the table for round N (the first is the winner, so max_round_reward is the round count plus 1). battle_reward_peso is read too. The comment in the shipped file says the date must equal the start date set in the database. In the 2021 testbed file only load_date_1 is active (the rest are commented out), so a tournament that starts on another date has no reward entry until you add its line and raise max_load.

  2. In regular_tournament_reward_table.ini, each [tableN] is a reward set: max_present and present<n>_type, _ment, _period, _value1, _value2. Types (from the file header): 1 hero (code, seconds), 2 look, 3 etc item (code, amount), 4 pesos, 5 gear (code, strength x 10000 + hours), 6 gear box, 7 look with hero choice, 8 EXP, 9 medal. _ment is a message id in the client text and _period the period of the present.

  3. [common] there also sets camp_peso_reward_* and cheer_peso_reward_* (message id and period for the peso rewards).

  4. sp2_custom_tournament_reward.ini (max, [rewarditem<n>], etc_item_type, reward_item_pirce) prices the items players can offer as prizes in custom tournaments.

Open sp2_camp.ini on the main server.

[CampData]
MaxCamp = 2
Camp1_Type = 1
Camp1_Name = <blue name>
Camp2_Type = 2
Camp2_Name = <red name>
[SeasonDate]
LastSeasonDate = 2020101202
PeriodTime = 335
RecessTime = 1
PlayStartHour = 10
PlayPreceedTime = 15
TodayPointBonus = 0.03f
Key Meaning
LastSeasonDate When the last season ended. The server writes this line itself at each season end (SaveSeasonDateINI). 0 means “start now”
PeriodTime Season length in hours (335 is about 14 days)
RecessTime Rest period after a season in hours (at least 1)
PlayStartHour, PlayPreceedTime Daily battle window: starts at this hour and lasts this many hours (it may run past midnight)
TodayPointBonus Bonus rate for the daily result
[Alarm] MaxCheck, Check_N Server-wide notices at influence limits. Shipped MaxCheck = 0, so none

The next season end is LastSeasonDate + PeriodTime + RecessTime (CampManager::ProcessSeason). With an old date the server may run several season ends in a row until it catches up (not tested), so set a recent date or 0 when you first start. The date looks like YYYYMMDDHH; that format is inferred from the shipped values, not confirmed in code.

Client side, sp2_camp.ini [Info] holds SyncTime, SeasonBonus, LimitCampPoint, InfluenceCloseEntry (shipped very high, so joining never closes) and the bonus formula keys CampBonusCorrectionA/B, CampBonusDefaultA/B, CampBonusMinEntry, CampBonusMaxEntry. The help text blocks in the same file are Korean. If you translate text that contains placeholders, remember that non-Korean clients print %1 %2 where Korea uses %s %d. Whether these texts contain placeholders: not confirmed yet.

Names and pictures of the two sides on the tournament panel come from the client sp2_regular_tournament.ini: block [resourceN] (N is resource_type) with blue_camp_title, red_camp_title, blue_camp_icon, red_camp_icon, main_banner, reward lines reward_<place>_<n> and max_reward. Add one block for each resource_type you use.

Faction data is stored in userRegionDB through game_region_get_point (2008), game_region_save (2009), game_region_player_count (2010), game_region_season_end_data_init (2011) and game_region_season_end (2012).

Differences:

  • The loaders (CampManager.cpp, TournamentNode.cpp) read the same keys in all three sources.
  • Shipped values: only the side names and LastSeasonDate differ between the three. PeriodTime, RecessTime, PlayStartHour and PlayPreceedTime are the same as above, and the tournament schedule keys match too.
  • The game_region_* procedures exist in all three testbeds. In 2014 they come from the base scripts.
  1. Start the main server and read its log: it prints Camp SetNextSeasonTime, Reqular Tournament ... and the state minutes.
  2. Open the tournament panel in the client with a test account, sign up a team and check the rows in userLeagueTeamDB.
  • Whether the game server reads its own sp2_camp.ini.
  • A full run of a tournament and a Faction season end in the client.
  • Seed row needs of the 2021 testbed, and live reload of these files.
  • Pack contents of the 2014 and 2019 clients.