Repository navigation
fix: add missing Moon member to ArenaEnvPresetsJson.PresetType - #241
Draft
claude[bot] wants to merge 1 commit into
Draft
claude[bot] wants to merge 1 commit into
claude[bot] wants to merge 1 commit into
Conversation
The "moon" key in ArenaSceneEnvPresetsDefaults.Presets has no matching PresetType member, so an inbound "preset":"moon" fails the StringEnumConverter conversion. The [OnError] handler marks it handled, so the moon values still populate (the defaults lookup keys on the raw JSON string under StringComparer.OrdinalIgnoreCase) but json.Preset is left at Default. The preset-change detector in ArenaUnity.ApplyEnvironmentPresets then compares "moon" against "default" on every later env-presets message and wipes accumulated state each time, and the outbound echo reports the wrong preset. Closes #226
claude
Bot
force-pushed
the
fix/moon-env-preset
branch
from
August 27, 2026 18:10
5a9b976 to
ad21d5f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested by mwfarb · Slack thread
Before:
ArenaSceneEnvPresetsDefaults.Presetshas a"moon"key, butArenaEnvPresetsJson.PresetTypehas noMoonmember. An inbound"preset":"moon"therefore fails theStringEnumConverterconversion. It is not silent and it does not lose the look of the scene: the defaults lookup inApplyEnvironmentPresetskeys on the raw JSON string underStringComparer.OrdinalIgnoreCase, so the 25 moon values are populated anyway, and the DTO's[OnError]handler logs a Newtonsoft warning before settingHandled = true. What is left behind is a torn state — the component holds moon values while its enum-typedPresetfield still readsDefault. Because the preset-change detector compares the incoming string againstc.json.Preset.ToString().ToLower(), every laterenv-presetsmessage sees"moon" != "default", takes the "preset changed" branch, and wipes the accumulated state, discarding any incremental override the scene layered on top. The outbound echo reportspresetasdefaultrather thanmoon.After:
"moon"binds toPresetType.Moon, so the enum field agrees with the values that were loaded. The change detector reads"moon"on the second and every subsequent message, matches the incoming value, and keeps the previous state instead of wiping it. The outbound echo reports the preset the scene actually is.Adds one enum member,
Moon, with[EnumMember(Value = "moon")], in the enum's alphabetical position betweenJapanandNone.How: the only change is two lines in
Runtime/Schemas/Attribute/ArenaEnvPresetsJson.cs(+2 at:371-372), declared exactly like its 18 siblings — attribute line carrying the lowercase wire name, then the PascalCase member.Presetis already annotated[JsonConverter(typeof(StringEnumConverter))], which honoursEnumMemberAttribute, so no converter or dictionary change is needed.PresetType.Moon.ToString().ToLower()is"moon", which is what the detector atRuntime/ArenaUnity.cs:749compares against, so that call site needs no change either. Nothing else in the tree referencesPresetType(grep -rn "PresetType" --include=*.csreturns only the three lines in this one file).Refs #226
Refsrather thanCloses, because the fix is not durable on its own. A reviewer checkedarenaxr/arena-schemasand reports that itsschemas/scene-options.jsondeclarespreset.enumas exactly the 18 pre-PR values, with nomoon— so the next regeneration of this file deletes the member added here and the defect returns. That repo is not reachable from this session, so the enum contents are the reviewer's finding and not something verified here.The local
PresetType.Moonaddition is therefore a stopgap. The two durable options are to declaremoonin the upstream schema'spreset.enum, or to drop the local"moon"key fromArenaSceneEnvPresetsDefaults.Presetsso the DTO and the defaults table agree the other way. Note that upstreamaframe-environment-componenthas the same split — it defines amoonpreset but omits it from the property's allowed values — so which side is "correct" is a maintainer call, not something either repo's source settles.Runtime/Schemas/Attribute/ArenaEnvPresetsJson.cscarries the header// CAUTION: This file is autogenerated from https://github.com/arenaxr/arena-schemas. Changes made here may be overwritten.The samemoonaddition has to be made to thearena-schemassource, or this fix is lost on the next regeneration. That repo was not reachable from the session that produced this PR, so nothing was changed there. Worth deciding at the same time whethermoonis a genuineaframe-environment-componentpreset (belongs in the schema) or an addition local to this repo (in which case the dictionary key may be what should change) — that is a maintainer call, not something the source settles.Relayed second-hand from another session and not verified in this pass: that report states
Runtime/Components/ArenaSceneEnvPresetsDefaults.csis hand-maintained rather than generated — the generator is said to write onlyRuntime/Schemas/— so a schema regeneration would delete thePresetType.Moonmember this PR adds while leaving the local"moon"defaults entry in place, restoring exactly the torn state described above. That claim was not checked here; treat it as hearsay to confirm, not as a finding of this PR.What was traced in source vs. inferred
Traced, by reading this tree at
a5d27bd:Presetis[JsonConverter(typeof(StringEnumConverter))]with[JsonProperty(PropertyName = "preset")](ArenaEnvPresetsJson.cs:390-393), and every sibling member uses[EnumMember(Value = "<lowercase>")]. AddingMoonwithValue = "moon"is the serialised form the wire already sends, per the dictionary key atArenaSceneEnvPresetsDefaults.cs:33.ArenaUnity.cs:748-753compares(string)incoming["preset"]withc.json.Preset.ToString().ToLower(). With the member present that comparison is"moon" == "moon", so the wipe branch is not taken andbaseJson = JObject.FromObject(c.json)keeps state. Stable across repeated messages.moonenv preset has no PresetType enum member, so an inboundpreset: mooncannot round-trip #226 sayspresetdrops out of the outbound echo becauseShouldSerializePresetreturnsPreset != defPreset. That is not what this tree contains —ShouldSerializePreset()at:394-397isreturn true; // required in json schema, unconditional. Sopresetis never omitted; the defect on the outbound side is that it carried the wrong value ("default"), and theInjectNulls/"preset":nullconcern raised in the issue does not arise. After this change the echo carries"moon".Inferred, not executed (no Editor available — see below):
How to test in the Editor
env-presetsscene message withpreset: moon. Confirm the scene renders the moon environment and that the Newtonsoft conversionLogWarningno longer appears in the Console.ArenaSceneEnvPresetscomponent in the Inspector:Presetshould now readMoon, notDefault.env-presetsmessage withpreset: moona second time in a row, ideally with an incremental override layered on (e.g.groundColor). Confirm the second message does not wipe scene state — the override survives. Before this change the "preset changed" branch fired on every message.presetwith the valuemoon(previouslydefault).japan,none) and back.Untested
This PR is untested. No Unity Editor and no Unity licence were available, so it was never compiled or run, and no CI runs on this PR — the workflow that adds
pull_requesttriggers exists only in the unmerged draft #183. The diff was read adversarially instead; please compile and exercise it in your Editor before this leaves draft.No tests were added: the
Tests~/DotNet/project only exists on #183's branch. #186 tracks golden-value assertions for these presets and is where a round-trip assertion — every key ofArenaSceneEnvPresetsDefaults.Presetsparses to aPresetTypemember and back — would belong.Most likely risk in the Editor: the new member shifts the underlying integer values of
Noneand every member after it by one. AnyArenaSceneEnvPresetscomponent already serialized in a scene or prefab asset stores the enum as an int, so a savedNone(was 10) would deserialize asMoon(now 10), and so on down the list. Please check any committed scenes/prefabs that pin a preset at or afternonealphabetically. Inserting alphabetically matches the file's idiom and how a regeneration from the schema would order it; appendingMoonat the end would avoid the renumbering but diverge from that ordering — say the word if you would rather have it appended.Generated by Claude Code