{{indexmenu_n>30}} ===== Game API ===== The Game API is an API for writing your own frontend version or interacting with game information from within the game. It can be used for Telegram bots, native applications, or browser extensions. ===== Entry Points ===== All actions are performed via two entry points: **game.php** - Authentication, retrieving tasks, submitting answers, unlocking penalty hints. **game_au.php** - Checking for new actions from other players that need to be displayed (for example, if someone entered a correct answer). **The GET parameter `json` must be added to all requests. In this case, the response will be returned in JSON format.** ===== Authentication ===== Used: **login.php** **POST parameters:** **user** - player login **pass** - player password You must save cookies and pass them all in subsequent requests. If the response contains a field named **login_error**, the authentication failed. ===== Task Data ===== Used: **game.php** **GET parameters:** **gid** - Game ID. **tid** - [Optional] Level ID. The response returns a UTF-8 JSON containing a lot of optional data. If there is a `?` next to a type, it may be absent. **Class names and types are not returned—they are provided for illustrative purposes only.** class PublicContext { int version = 1; // Protocol version ?string error ; // Error. ?string login_error; // Login error string domain_time_zone; // Current domain timezone ?int game_id; // Game ID ?int task_id; // Current level ID ?int user_id; // Authenticated user ID ?string user_name; // Player login ?int team_id; // Player team ID, may match current user ID in single-player games ?int refresh_time_ms; // Last page update time in unix_time milliseconds ?int refresh_check_limit_ms; // Interval in milliseconds during which you should not query the server without cause. PublicGame game; // Game data /*?PublicGame[]*/ available_games; // Data of active/upcoming domain games. Available if called without gid PublicTask task; // Data of the current task PublicLastAnswers last_answers; // Monitoring of recently entered answers ?PublicAnswerResult answer_result; // Result of the last answer submission ?PublicAnswerForm answer_form; // Data of the answer form /* ?[n => PublicCode] */ codes; // Code data /* ?PublicHint[] */ hints; // Hints ?int n_bonuses; // Total number of bonuses, if any exist in the task ?int compact_n_bonuses; // Total number of bonuses if the author chose compact bonus mode ?int compact_bonus; // Cumulative bonus/penalty received if the author chose compact bonus mode /* ?string[] */ compact_bonus_answers; // Known answers to bonuses if the author chose compact bonus mode /* ?string[] */ compact_bonus_hints; // Hints for entered bonuses if the author chose compact bonus mode /* ? PublicBonus[] */ bonuses; // Bonuses /* ? PublicBonus[] */ global_bonuses; // Global bonuses /* ?PublicTaskButton[] */ active_tasks; // Tasks currently available /* ?PublicTaskButton[] */ closed_tasks; // Tasks already closed - in storm mode only } class PublicGame { int id; // Game ID string name; // Game name int start_time; // Game start time in unix_time int end_time; // Game end time in unix_time ?int type; // Game type - 0 or absent: storm sequence, 1: linear sequence ?bool single; // Single-player or team game } class PublicTask { int n; // Task number string name; // Task name ?string task; // Task text ?string answer_format; // Answer format ?int n_codes; // Total number of codes in the task ?int need_n_codes; // Number of codes required to complete the task ?int start_time_ms; // Task start time in unix_time milliseconds ?int time_left_ms; // Time left in milliseconds before automatic transition ?int delay_left_ms; // Delay in milliseconds before the task appears int is_complete; // Task is already complete } class PublicLastAnswers { /* ?PublicLastAnswer[] */ answers; // Array of answer info int last_update_ms; // Last update time in unix_time milliseconds } class PublicLastAnswer { int time_ms; // Time in unix_time milliseconds when the answer was sent ?string user; // Who entered it - absent in single-player games string answers; // Entered answers separated by commas string type; // One of: right, wrong, repeat (correct but already submitted), nonsubmit (not accepted due to lock) ?string bonus; // Received bonus or penalty for answers } class PublicAnswerResult { int task_id; // Level ID for which it is calculated /* ?string[] */ right_answers = []; // correct answers /* ?string[] */ wrong_answers = []; // incorrect answers /* ?string[] */ repeat_answers = []; // correct but repeat answers /* ?string[] */ nonsubmit_answers = []; // not accepted due to lock ?string bonus = ''; // Bonus received for answers ?string penalty = ''; // Penalty received for answers } class PublicAnswerForm { public bool show_finish_task = false; // Whether to show the button that closes the task. If yes, the task can be closed by submitting "!finish!" bool hide_answer_form = false; // Answers will no longer be accepted, input field can be hidden ?int block_time_left_ms; // Time left before input lock is removed, in milliseconds. If penalty is not 0, answers can be submitted but with a penalty for incorrect ones. ?int limit_n_answers; // Limit on the number of incorrect answers. Constant - configured by author. ?int time_limit; // Time in seconds. The interval over which limit_n_answers is enforced. If 0, limit_n_answers is a limit for the entire level. ?int penalty; // Penalty for each incorrect answer exceeding the limit ?int n_answers_left; // Number of answers the team can enter before restriction. Changes after each submission. If 0, restriction is active. } class PublicCode { ?string name; // Code name ?string answer; // Code answer ?string user_name; // Who entered first ?int user_id; // Who entered first ?int answered_ms; // When entered first } class PublicBonus { ?int n; // Bonus number ?int bonus; // Bonus received or penalty (if negative value), in seconds or points ?string answer; // Answer to bonus ?string description; // Bonus description (riddle) ?string hint; // Hint, if bonus is solved ?int time_to_open_ms; // Time in milliseconds before bonus opens ?int time_to_close_ms;// Time in milliseconds before bonus closes ?bool is_closed; // Time to enter bonus expired - no longer available for submissions ?string user_name; // Who entered first ?int user_id; // Who entered first ?int answered_ms; // When entered first } class PublicHint { int n; // Hint number ?int time_to_open_ms; // Time in milliseconds before hint opens ?int id; // Penalty hint ID - required for usage ?string description; // Hint description ?string hint; // Hint text ?int penalty; // Penalty for the hint ?int any_code; // If present, hint can open any code /*int[]*/ codes; // List of codes that the hint can open } ==== Error Variants ==== The **error** field can receive the following errors: * NO_GAME_ID - gid not specified * NO_GAME - incorrect gid * NO_USER - user needs to log in * NO_TEAM - team game, but player is not in a team * TEAM_NO_ANONYMOUS - anonymous player cannot play in games with roster limits * TEAM_TOO_BIG - team has more players than roster limit * TEAM_GAME_NOT_REQUESTED - team has not requested to join * TEAM_GAME_NOT_ACCEPTED - team not accepted into the game * GAME_NOT_STARTED - game has not started yet * GAME_FINISHED - game has finished * SEQUENCE_ERROR - error in the level sequence defined by the author ===== Submitting Answers ===== Used: **game.php** **GET parameters:** **gid** - Game ID. **tid** - Level ID where the answer should be submitted. If omitted, there is a risk of submitting an answer from the previous level into a level with input restrictions. **a** - Answers to submit, separated by commas. ===== Taking Penalty Hints ===== Used: **game.php** GET parameters: **gid** - Game ID. **hint_id** - ID of the hint to unlock. **hint_code** - [Optional] number of the code to be opened by the penalty hint. ===== Page Refresh ===== Used: **game_au.php**, **game.php** If the game is a team game, the response of **game.php** will contain **refresh_check_limit_ms** This is the time in milliseconds after which you can check if there are changes in the engine due to teammate actions. If you query the server more frequently, there is a risk of getting an IP ban for some period. **refresh_check_limit_ms** is not a constant and can change depending on server load. If any timer in the game expires sooner than **refresh_check_limit_ms**, you must refresh the page using **game.php**. In this case, **refresh_check_limit_ms** can be ignored. ==== Optimal ==== Use **game_au.php** to check if page refresh is needed. GET parameters: **gid** - Game ID. **tid** - Task ID. **time** - time received in **refresh_time** from **game.php** response. The response will return JSON: class PublicAutoUpdateResult { ?string error; // Error ?bool refresh; // Need to refresh page, someone entered a correct code or took a penalty hint ?bool reload; // Someone completed the level ?bool refresh_monitoring; // New incorrect answers are in monitoring. Can load them if needed. ?int next_check_ms; // How long to wait (in milliseconds) until next check - calculated by server based on load } If the JSON contains fields refresh, reload, or refresh_monitoring, refresh the page using **game.php**. ==== Non-optimal ==== Regularly load the new version using **game.php**. **In this case, set the interval for querying the server to refresh_check_limit_ms multiplied by 3.**