Repository navigation
fix: re-enable a renderer when visible: true is set - #242
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 visibility guard in UpdateObjectMessage only called ApplyVisible when the inbound value was false, so hiding an object over the wire was one-way: a later visible: true was ignored. data.Visible cannot detect wire presence here. ArenaDataObjectJson.Visible is initialized to true (defVisible), and the message is deserialized with NullValueHandling.Ignore, so the member reads true both for visible: true and for messages that omit visible entirely. The old guard therefore relied on !(bool)data.Visible to mean "the message asked to hide". Test the raw jData for a visible key instead, matching the presence idiom already used for rotation.w, and let ApplyVisible apply either value. A missing or null visible still falls through to the remote-render branch, and visible keeps precedence over remote-render.
visible: true never re-enabling a renderervisible: true is set
claude
Bot
force-pushed
the
fix/visible-true-reenable
branch
from
August 27, 2026 18:10
3ad5334 to
bfeceda
Compare
claude
Bot
force-pushed
the
fix/visible-true-reenable
branch
from
August 27, 2026 18:26
bfeceda to
5dfb5cf
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: Hiding an object over the wire was one-way. Publishing
visible: falsedisabled the renderers, but publishingvisible: truefor the same object afterwards did nothing — the object stayed invisible for the rest of the session. The only way it came back was if the same message also carried aremote-renderfield, which then happened to re-enable it through a different code path.After:
visible: truere-enables the renderers, so visibility can be toggled back and forth over the wire as many times as you like.visible: falsebehaves exactly as it does today, and a message that does not mentionvisibleat all is still handed to theremote-renderbranch untouched.ApplyVisible(Runtime/ArenaUnity.cs:272-284) was always correct — it assignsrenderer.enabled = (bool)data.Visibleand handles both values. Only the guard that decides whether to call it was wrong.How: The guard at
Runtime/ArenaClientScene.Messaging.cs:249readdata.Visible != null && !(bool)data.Visible, soApplyVisiblewas reached only for a false value. The typeddata.Visiblecannot answer "did this message set visible?" in the first place:ArenaDataObjectJson.Visibleis initialized totrue(defVisible,Runtime/Schemas/ArenaDataObjectJson.cs:76,79) and the message is deserialized withNullValueHandling.Ignore(Messaging.cs:116), so the member readstrueboth for an explicitvisible: trueand for the majority of messages that omitvisibleentirely. That is why the old guard leaned on!(bool)data.Visibleas a proxy for "the message asked to hide" — and it is why simply dropping the negation would have made the guard true for nearly every object update and turned theremote-renderbranch into dead code.So the presence test now goes against the raw
jDatainstead, matching the idiom already used a few lines above forrotation.w(Messaging.cs:238), withApplyVisibleleft to apply whichever value arrived. The ordering is unchanged:visibleis still checked first and still takes precedence overremote-render, which is only consulted whenvisibleis absent.Closes #221
Scope — this addresses half of #221. The one-way
visibleguard is fixed. The cross-message priority relationship betweenvisibleandremote-renderis deliberately left exactly as it is, and a second, pre-existing path can still undo the visibility this change restores:Runtime/Components/ArenaMaterial.cs:109setsrenderer.enabled = json.Visiblefrom the material component's ownvisibleproperty, which is a different field from the object-level one this PR fixes. It defaults totrue(defVisible,Runtime/Schemas/Attribute/ArenaMaterialJson.cs:619-622), and it is applied from the baseArenaComponent.Update()tick (Runtime/Components/ArenaComponent.cs:25-32) rather than inline with the message, so it lands a frame after the message is handled. An object that also carries amaterialcomponent can therefore have avisible: falsequietly reverted by that path. Untouched here. Because neither of those two is resolved, the maintainer may preferRefs #221toCloses #221; it is left asClosesfor that call.How to test in the Editor
visible: falsefor an object, confirm its renderer switches off, then publishvisible: truefor the same object and confirm the renderer comes back. Repeat the toggle a couple of times.remote-renderpath still behaves as before: with novisiblefield on the message,remote-rendershould still enable/disable the renderer exactly as it does onmain.visiblefield (position/rotation/scale moves) do not disturb visibility — this is the case the guard change is most exposed to.visible: truein a message of its own, carrying no other key — not alongside a position update and not alongsideremote-render. This is the case that did nothing at all before: the guard now seesvisiblepresent in the rawjData, so a bare{"visible": true}update should bring the renderer back on its own.visible: trueandremote-render. Onmaintheremote-rendervalue wins; with this changevisiblewins, which is what the existing comment on that line ("visible, if set is highest priority") always claimed should happen.Untested
This is untested. There is no Unity Editor and no Unity licence in the environment this was written in, and no CI runs on this PR (the workflow that adds
pull_requesttriggers only exists on the unmerged #183). The diff has been read adversarially against the schema defaults and the deserializer settings, but nothing here has been compiled or run — please treat it as a patch to try in your Editor rather than a verified fix.Note on merge order
Two other open drafts add dispatch arms to this same file,
Runtime/ArenaClientScene.Messaging.cs(one for the physx joint attributes, one forvideo-control). This hunk is deliberately kept to the visibility guard alone and does not touch the attributeswitch, so it should not conflict textually with either — but the merge order between the three still matters, and whichever lands last will want a quick re-read of that region.Generated by Claude Code