みんなのランキング ── ゲームの中でスコアを競う

ハイスコアを他の冒険者と競いたい。そんなときは shared/ フォルダを使います。 覚えることは 2 つだけです。

  • 自分のは書く ── shared/score.json に自分のスコアを書く
  • 集団のは読む ── shared/ranking.json を読む(Code & Magic が書き戻します)

セーブデータ(セーブデータ ── 冒険の記録をアカウントに残す)と同じで、 特別な API はありません。普通の Python の open()json だけです。

使い方

import json

def submit_score(score):
    """1 回の勝負が終わったときだけ呼ぶ"""
    try:
        with open("shared/score.json", "w") as f:
            json.dump({"score": int(score)}, f)
    except OSError:
        pass  # 共有できない環境(デスクトップの Pyxel など)では、そのまま遊べる


def read_board():
    """ランキングを読む。無ければ None(ひとりで遊んでいる状態)"""
    try:
        with open("shared/ranking.json") as f:
            return json.load(f)
    except (OSError, ValueError):
        return None

shared/ranking.json の中身はこうなっています。

{
  "order": "desc",
  "top": [
    { "rank": 1, "name": "エイダ", "label": "ada-lovelace", "score": 5200, "isMe": false },
    { "rank": 2, "name": "ADV-1a2b", "label": "ADV-1a2b", "score": 3100, "isMe": true }
  ],
  "me": { "rank": 2, "score": 3100 },
  "players": 42
}
  • top ── 上位の記録。isMe が自分の行です
  • me ── 自分の順位とスコア(まだ出していなければ null
  • players ── その作品で記録を出した人の数

覚えておくこと

提出は「勝負が終わったとき」だけ

毎フレーム書く必要はありません。ゲームオーバーや時間切れの瞬間に 1 回書けば十分です。 短い間に何度も書くと、提出が間引かれます。

集計はすこし待つ

書いた瞬間に順位が出るわけではありません。Code & Magic が集計して shared/ranking.json を 書き戻すまで、少し時間がかかります。数フレームおきに読み直すのがコツです。

# 提出したあと、自分の記録が載るまで読み直す
board = read_board()
if board and board.get("me", {}).get("score", -1) >= my_score:
    ...  # 届いた

記録はプレイヤーごとにベストが残る

低いスコアを出しても、それまでのベストは消えません。順序は スコアが高いほうが上です。

名前は自分で名乗りません

「誰の記録か」は Code & Magic が決めます(score.json に名前を書いても無視されます)。 表示されるのは、

  • クリエイターページ(/c/<名前>)を作っている人 ── 冒険者名
  • 作っていない人 ── ADV-1a2b のような記号

です。ほかの冒険者の名前を勝手に出さないための決まりです。

名前を描くときは label を使う

Pyxel が最初から持っているフォントは英数字だけなので、日本語の冒険者名は画面に出ません。 label は必ず英数字なので、こちらを描けばどの名前でも表示できます。

name = entry.get("label") or entry.get("name", "?")
pyxel.text(10, 20, f"{entry['rank']:>2} {name[:12]}", 7)

日本語で出したいときは、日本語フォント(BDF)を魔導書に入れて pyxel.Font で描いてください。

ひとりでも遊べるように書く

shared/ranking.json が無いことは、ふつうに起こります。

  • サインインしていない人が遊んでいるとき
  • デスクトップの Pyxel で動かしているとき
  • まだ誰も記録を出していないとき

読めなかったときは「ひとり用」に切り替えるのが作法です。ランキングが無いとゲームが 止まってしまう作りにはしないでください。

サンプル

この作法どおりに作った小さなゲームがあります(20 秒のスコアアタック → 提出 → 順位表示)。 コードは短いので、丸ごと読んでから自分の作品に移すのが早道です。