{"record":{"id":"4ec32361d9612c82","repo":"ppy/osu","slug":"only-scores-in-the-osu-taiko-catch-or-mania-rul","errorCode":null,"errorMessage":"Only scores in the osu, taiko, catch, or mania rulesets can be encoded to the legacy score format.","messagePattern":"Only scores in the osu, taiko, catch, or mania rulesets can be encoded to the legacy score format\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"osu.Game/Scoring/Legacy/LegacyScoreEncoder.cs","lineNumber":94,"sourceCode":"        private readonly Score score;\r\n        private readonly IBeatmap? beatmap;\r\n\r\n        /// <summary>\r\n        /// Create a new score encoder for a specific score.\r\n        /// </summary>\r\n        /// <param name=\"score\">The score to be encoded.</param>\r\n        /// <param name=\"beatmap\">The beatmap used to convert frames for the score. May be null if the frames are already <see cref=\"LegacyReplayFrame\"/>s.</param>\r\n        /// <exception cref=\"ArgumentException\"></exception>\r\n        public LegacyScoreEncoder(Score score, IBeatmap? beatmap)\r\n        {\r\n            this.score = score;\r\n            this.beatmap = beatmap;\r\n\r\n            if (beatmap == null && !score.Replay.Frames.All(f => f is LegacyReplayFrame))\r\n                throw new ArgumentException(@\"Beatmap must be provided if frames are not already legacy frames.\", nameof(beatmap));\r\n\r\n            if (!score.ScoreInfo.Ruleset.IsLegacyRuleset())\r\n                throw new ArgumentException(@\"Only scores in the osu, taiko, catch, or mania rulesets can be encoded to the legacy score format.\", nameof(score));\r\n        }\r\n\r\n        public void Encode(Stream stream, bool leaveOpen = false)\r\n        {\r\n            using (SerializationWriter sw = new SerializationWriter(stream, leaveOpen))\r\n            {\r\n                sw.Write((byte)(score.ScoreInfo.Ruleset.OnlineID));\r\n                sw.Write(score.ScoreInfo.TotalScoreVersion);\r\n                sw.Write(score.ScoreInfo.BeatmapInfo!.MD5Hash);\r\n                sw.Write(score.ScoreInfo.User.Username);\r\n                sw.Write(FormattableString.Invariant($\"lazer-{score.ScoreInfo.User.Username}-{score.ScoreInfo.Date}\").ComputeMD5Hash());\r\n                sw.Write((ushort)(score.ScoreInfo.GetCount300() ?? 0));\r\n                sw.Write((ushort)(score.ScoreInfo.GetCount100() ?? 0));\r\n                sw.Write((ushort)(score.ScoreInfo.GetCount50() ?? 0));\r\n                sw.Write((ushort)(score.ScoreInfo.GetCountGeki() ?? 0));\r\n                sw.Write((ushort)(score.ScoreInfo.GetCountKatu() ?? 0));\r\n                sw.Write((ushort)(score.ScoreInfo.GetCountMiss() ?? 0));\r\n                sw.Write((int)(score.ScoreInfo.TotalScore));\r","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/ppy/osu/blob/d9c73e12adff2feaae4a3e158d36fe5883faf6ca/osu.Game/Scoring/Legacy/LegacyScoreEncoder.cs#L76-L112","documentation":"Thrown by the LegacyScoreEncoder constructor when score.ScoreInfo.Ruleset.IsLegacyRuleset() is false. The legacy score format only supports the four original osu! rulesets; encoding for any other (e.g. lazer-only or custom) ruleset is rejected at construction time.","triggerScenarios":"Constructing new LegacyScoreEncoder(score, beatmap) where score.ScoreInfo.Ruleset is not osu/taiko/catch/mania. The encoder cannot represent non-legacy rulesets in the stable binary format.","commonSituations":"Exporting a score from a custom ruleset; exporting a lazer-only gamemode; forgetting to filter scores by IsLegacyRuleset() before export.","solutions":["Filter to score.ScoreInfo.Ruleset.IsLegacyRuleset() before instantiating LegacyScoreEncoder.","Use the lazer JSON score format (.osr-lazer) for non-legacy rulesets instead of the legacy encoder.","Check OnlineID of the ruleset (0,1,2,3) as a quick pre-guard before constructing the encoder.","Wrap construction in try/catch ArgumentException and skip non-encodable scores in batch exports."],"exampleFix":"// before\nvar encoder = new LegacyScoreEncoder(score, beatmap);\n\n// after\nif (!score.ScoreInfo.Ruleset.IsLegacyRuleset())\n    throw new NotSupportedException($\"Ruleset {score.ScoreInfo.Ruleset.ShortName} cannot be legacy-encoded.\");\nvar encoder = new LegacyScoreEncoder(score, beatmap);","handlingStrategy":"validation","validationCode":"if (!score.ScoreInfo.Ruleset.IsLegacyRuleset())\n    throw new NotSupportedException(\"Use lazer score format for non-legacy rulesets.\");","typeGuard":"static bool IsLegacyEncodable(Score s) => s.ScoreInfo.Ruleset.IsLegacyRuleset();","tryCatchPattern":"try { new LegacyScoreEncoder(score, beatmap); }\ncatch (ArgumentException) { /* fall back to JSON encoder */ }","preventionTips":["Filter scores by IsLegacyRuleset() before legacy export.","Reserve LegacyScoreEncoder for osu/taiko/catch/mania.","Use the lazer JSON format for custom/lazer-only rulesets."],"tags":["score","legacy-encoder","ruleset","serialization"],"backgroundTag":null,"analyzedSha":"d9c73e12adff2feaae4a3e158d36fe5883faf6ca","analyzedAt":"2026-08-13T14:12:54.015Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}