Keyboard shortcuts

Press ← or → to navigate between chapters

Press ? to show this help

Press Esc to hide this help

赛季

赛季是一个游戏的一场比赛。平台管理员创建它,你提交的每个版本都属于一个赛季,并且只在这个赛季的参赛者之间对局。赛季可以重叠:一个游戏可以同时进行多个赛季,有公开的也有私有的,每个赛季都有自己的地图、基线、参与者、运行器、排名和领奖台。

赛季有一个管理员起的名称,比如“Summer 2026”,还有一个平台从名称派生出的 slug,即 summer-2026。每个链接、每条路由和每条记录都用 slug 来指代赛季。两者都永不改变,所以指向赛季的链接会一直有效。

请求针对哪个赛季

没有指明赛季的读取请求和提交,针对的都是这个游戏的精选赛季:平台管理员设为精选的公开赛季;没有的话,就是最新的进行中的公开赛季;再没有,就是最新的公开赛季。私有赛季永远不是任何人的默认赛季。

要读取或参加其他赛季,就用 slug 指明它:读取时加 ?season=<slug>,提交时在请求体中写 season。网站的赛季切换器做的是同一件事,它的提交表单提交到页面当前显示的赛季。

谁能看到赛季,谁能参赛

赛季要么公开要么私有,它的参赛资格要么开放要么受限。私有赛季总是受限的。每个赛季对象都以 visibility 和 entry 带着这两项。

谁能看到谁能参赛
公开,开放所有人任何已登录的人
公开,受限所有人它的参与者
私有(受限)它的参与者、它的赛季管理员和平台管理员它的参与者

管理员在创建赛季时就定下这两项,只有一个例外:赛季还未开始时,平台管理员可以把它的参赛资格从开放收窄为受限。它永远不会再放宽,而可见性则完全不可更改:私有赛季一旦转为公开,会把一整个学期的历史一下子公之于众;公开赛季一旦转为私有,会让所有已经分享出去的链接失效。

受限赛季接纳的是它的参与者。赛季管理员添加参与者,赛季进行中也可以添加,所以一个班里晚加入的成员仍然能参赛。每个参与者是一种登录方式加上该方式下的一个登录名。如果已有账户持有这个身份,这条记录会立即绑定到该账户;否则它会等待,直到这个身份第一次登录时再绑定。没有登录名的记录接纳该登录方式下的所有身份。移除参与者会立即阻止其后续提交,在私有赛季中还会收回其查看权限;已经在天梯上的版本则会留下。参与者名单不公开:只有赛季管理员能读取。

赛季还可以限制允许参赛的登录方式。来自其他登录方式的身份无法参赛,即使它的登录名在名单上。被拒的账户会收到 not_a_participant;如果你有多个登录身份,请确认你用的是赛季接纳的那一个登录。

对其他任何人来说,私有赛季并不存在。每条指明它的公开路由都像对待未知赛季一样作答,它的版本和对局都回答 404。它的成员通过 /v1/private/... 下那些需要登录的公开读取副本来读取它,这些路由接受同样的参数、返回同样的结构,并且从不缓存(HTTP API)。它的对局可以在同一群人之间评论,那里的评论永远不会出现在任何人的公开个人主页上。

谁管理赛季

平台管理员创建赛季,定下它的提交窗口、规则、可见性和参赛资格、允许参赛的登录方式,以及由哪些运行器运行它的对局。平台管理员还负责把赛季设为精选、主持它的轮次与决赛,并在创建时或之后指定它的赛季管理员。

赛季管理员管理一个赛季:它的参与者、地图和基线、它自己的运行器密钥和运行器、发给赛季成员的消息,以及它的审计日志。赛季开始前,他们可以编辑它的提交窗口、规则和重量级,也可以请求结束赛季。赛季管理员在其他地方是普通参赛者,但不能参加自己管理的赛季:向它提交会以 season_admin_cannot_enter 被拒绝,因为那样他们的名次就要由自己来评判了。

谁运行赛季的对局

赛季的机群策略规定由哪些运行器运行它的对局(matches)、由哪些审核它的提交(admissions),每一项都是 own、platform 或 both。platform 是平台自己的机群。own 是赛季自己的运行器,用赛季管理员在赛季页面上生成的密钥启动;这样的密钥永远只为这个赛季服务。赛季进行中,平台管理员可以更改这个策略。当赛季允许的运行器全都不在线时,它的对局在队列中等待,它的提交则停在 testing 中等待。

等待不消耗提交的任何尝试次数,所以等一会儿不会有损失。但等得太久,提交会因超时而被拒绝,而这和模型本身毫无关系——所以当提交在排队、而赛季策略允许的机器没有一台报到时,赛季页面会直截了当地说明;GET /v1/status 则为整个平台回答同一个问题(admission_queue 旁边的 admitters)。

提交窗口

GET /v1/games/ants/seasons 列出公开赛季,GET /v1/private/games/ants/seasons 再加上你能看到的私有赛季:每个赛季的名称和 slug、状态、可见性和参赛资格、提交的开放和截止时间、引擎标识、规则,以及它的地图和基线摘要,最新的在前。

状态提交比赛
scheduled尚不接受等待开放时间
open接受,须符合规则版本可以参赛并对局
settling不再接受新提交已有的审核和对局继续进行
closed不接受保留历史排名

开放时间包含在内,截止时间不包含,所以要在截止时间戳之前提交。及时到达的提交在窗口结束时可能仍在审核或试赛中。结算期让这些工作得以完成,除非有人先请求结束赛季。

赛季声明的规则

赛季带有一份规则文档,描述整场比赛。每条规则都是可选的。没有声明任何规则的赛季按平台自己的默认值进行,所以在同一个未改动的平台上,两个赛季可以是两场不同的比赛。赛季一旦开始,规则就固定下来。谁能参赛不是规则:那是上文所说的赛季参赛资格和参与者。

你能提交多少

  • 你能向赛季提交多少个模型。
  • 你的所有模型合计,可以同时有多少个版本处于审核中。
  • 你能提交多少个版本,按每个模型计或按总数计。
  • 同一个模型两次提交之间的冷却时间。
  • 你有多少个模型可以处于同一个重量级:赛季可以声明这一条,但平台目前还不会强制执行。

什么可以提交

  • 赛季设有哪些重量级。审核会取赛季设有的、能容纳你的大小的最小重量级,所以如果测得的大小低于某个赛季跳过的重量级,模型会落到再上一级。只能放进赛季未设重量级的模型会以 CLASS_NOT_OFFERED 被拒绝。
  • ONNX 范围:opset 区间、算子允许列表、参数上限和适配器指令预算。算子列表只能比平台的更窄,因为更宽的列表会放行运行时无法执行的算子,到对局时就会失败;opset 区间和预算则是赛季自己定的数字。
  • 是否拒绝重复权重,以及在什么范围内拒绝:其他参赛者在这个游戏任何地方提交过的权重、其他参赛者在本赛季提交过的权重,或任何其他模型(包括你自己的)持有的权重。

天梯如何对局、如何解读

  • 赛季使用哪些地图、有多少跨级对局把无差别级天梯连起来,以及每个版本能打多少场对局。地图是赛季自己的:由它的管理员上传,GET /v1/games/ants/seasons/{slug}/maps 从每张地图到达的那一刻起就把它列出来。与规则不同,地图在赛季进行中可以变化。管理员可以启用或停用一张地图;平台会取消在已停用地图上排队的对局,已经在进行的对局则打完并计入成绩。请按游戏的限制来设计,因为赛季今天有的地图以后可能会变(地图)。
  • 你自己的两个模型能否相遇。除非赛季另有规定,否则不能,因为你的两个模型之间的对局会白白地在它们之间转移评分。
  • 你最多能有多少个模型出现在天梯上。
  • 评分常数、什么算已稳定,以及赛季是在稳定后自行结束,还是只在管理员要求时才结束。

在假定上述任何一条之前,先读返回的 rules。GET /v1/games/{game}/submission(带 ?season=<slug>,或针对精选赛季)会在你发出请求之前报告提交窗口、你是否可以参赛,以及模型数、版本数和冷却时间的限制,措辞与拒绝时相同。重复权重规则由提交本身回答,重量级和 ONNX 规则则由审核在测量你的计算图之后判定。

赛季如何结束

提交窗口结束后,一旦每个候选版本都有了裁定、未完成的对局和计分都已完成、参赛中参赛者的评分在无差别级上满足稳定策略,平台就会自行结束赛季。提交截止时间并不固定最后一场对局的时间。打到决赛的赛季则不同:每个参赛模型都打完决赛的对局、没有任何对局在进行中后,赛季才结束。

赛季管理员或平台管理员也可以请求结束赛季。随后 Soma 的撤回时钟把赛季标记为已结束,以 SEASON_CLOSED 拒绝等待中的候选版本,并取消排队中的对局。已被认领或正在进行的对局仍可以打完并计入该赛季,所以排名在结束之后还可能接收这些最后的更新。SEASON_CLOSED 拒绝记录的是一个管理决定,与你的模型是否满足要求无关。

进入新赛季

你的模型跨赛季保留,它们的参赛记录则留在原赛季。你上赛季创建的模型仍然是你的,名称和全部历史都在,但它的参赛记录一条也不会延续:新赛季开始时没有地图、没有基线、没有参与者,也没有版本。晋级和前代版本的评分继承都只在一个赛季内有效,平台也不会替你把任何参赛者账户报名到赛季里。

新赛季的管理员负责把它的地图和基线带进来,可以上传,也可以从另一个赛季导入。导入的地图到达时处于停用状态,启用它时会在新赛季的引擎下重新检查一遍。导入的基线会按新赛季的规则重新审核,并以停用状态落地。另一个赛季里同名的基线是同一个对手,从先验重新开始。

你的参赛模型由你自己带进来。像平常一样向赛季提交新文件,或者让一个参赛模型以它在早先赛季中的状态重新参赛:

await fetch('/v1/submissions/reenter', {
  method: 'POST',
  credentials: 'same-origin',
  headers: {'Content-Type': 'application/json'},
  body: JSON.stringify({
    game: 'ants',
    model: '<你的 model_id>',
    season: '<它要进入的赛季的 slug>',
    from: '<它原来所在赛季的 slug>'
  })
});

重新参赛会取该参赛模型在 from 中的状态(它在那里参赛中的版本,或它最新的一个在赛的版本),把同样的字节提交到 season,无需上传任何东西。从这里开始它就是一次普通的提交:新赛季的参赛资格、上限、冷却时间、重复权重规则和提交窗口全都适用,新的 testing 版本会在新赛季的重量级、记忆和引擎下再次经过审核和试赛。响应是 201 并附上新版本,若该版本已在处理中则为 200。拒绝原因与普通提交相同,另加一条:当该参赛模型在 from 中没有任何在赛的版本时,返回 404 nothing_to_reenter。

历史排名

平台保留已结束赛季的排名。用 GET /v1/games/ants/leaderboard?season=summer-2026&ladder=open 读取,或按重量级筛选。对局和版本记录也写明各自的赛季,所以你在训练笔记中可以把不同赛季的结果分开。