<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[[Defold] room.state.on_change does not get triggered on state change]]></title><description><![CDATA[<p>Hi all,</p>
<p>I am seeing what seems to me to be inconsistent results when registering callbacks for room state changes.</p>
<p>Here I register a callback for base state changes, like in <a class="plugin-mentions-user plugin-mentions-a" href="http://discuss.colyseus.io/uid/1">@endel</a>'s example here: <a href="https://github.com/endel/colyseus-tic-tac-toe/blob/master/defold/scripts/game_controller.script" rel="nofollow">https://github.com/endel/colyseus-tic-tac-toe/blob/master/defold/scripts/game_controller.script</a>.</p>
<pre><code>room.state['on_change'] = function (changes)
	for i, change in ipairs(changes) do
		print(&quot;base state change&quot;)
		print(change.field)
		print(change.value)
		print(change.previousValue)
	end
end
</code></pre>
<p>Here I register a callback for something more specific in the state:</p>
<pre><code>room.state.players.on_add = function(player, sessionId)
	player.character.position.on_change = function(changes)
                local position = {}
		for i, change in ipairs(changes) do
			if change.field == &quot;x&quot; then
				position[&quot;x&quot;] = change.value
			end
			if change.field == &quot;y&quot; then
				position[&quot;y&quot;] = change.value
			end
		end
                print(&quot;new position&quot;, inspect(changes))
	end
end
</code></pre>
<p>I know that the state changes are successfully making it from one client, to the server, and back to the other client, because I see the player on one client move on the other (and also from the logs).</p>
<p>When one client moves, therefore updating the state, I see only messages from the more specific callbacks:</p>
<pre><code>DEBUG:SCRIPT: new position	{
  x = 869.49731445313,
  y = 370.85791015625
}
</code></pre>
<p>However I expect to see not only that, but also a message like:</p>
<pre><code>DEBUG:SCRIPT: base state change
</code></pre>
<p>Do I misunderstand how these callbacks work? I would assume that if I assign a callback to the root state, it would fire any time anything changes within that state (recursively).</p>
<p>Also, in the docs here (<a href="https://docs.colyseus.io/state/overview/" rel="nofollow">https://docs.colyseus.io/state/overview/</a>) it says that binary patches of the state are sent to the client every 50ms. Is it the case that if there are no changes, it sends nothing, and therefore the callback doesn't fire?</p>
<p>One specific reason I want a generic callback is I want to estimate how often I receive updates from the client so I can lerp the other players' movements accurately, though I think having a base callback might be useful in other ways.</p>
<p>In short, I'm not quite sure how <code>on_change</code> works, and I can't really figure it out from the docs (&quot;this event is triggered when the server updates its state&quot;, it doesn't really elaborate on which callbacks get called for which state).</p>
<p>Thanks everyone!</p>
]]></description><link>http://discuss.colyseus.io/topic/459/defold-room-state-on_change-does-not-get-triggered-on-state-change</link><generator>RSS for Node</generator><lastBuildDate>Tue, 19 May 2026 13:21:18 GMT</lastBuildDate><atom:link href="http://discuss.colyseus.io/topic/459.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 22 Apr 2021 00:32:11 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to [Defold] room.state.on_change does not get triggered on state change on Invalid Date]]></title><description><![CDATA[<p>Hi all,</p>
<p>I am seeing what seems to me to be inconsistent results when registering callbacks for room state changes.</p>
<p>Here I register a callback for base state changes, like in <a class="plugin-mentions-user plugin-mentions-a" href="http://discuss.colyseus.io/uid/1">@endel</a>'s example here: <a href="https://github.com/endel/colyseus-tic-tac-toe/blob/master/defold/scripts/game_controller.script" rel="nofollow">https://github.com/endel/colyseus-tic-tac-toe/blob/master/defold/scripts/game_controller.script</a>.</p>
<pre><code>room.state['on_change'] = function (changes)
	for i, change in ipairs(changes) do
		print(&quot;base state change&quot;)
		print(change.field)
		print(change.value)
		print(change.previousValue)
	end
end
</code></pre>
<p>Here I register a callback for something more specific in the state:</p>
<pre><code>room.state.players.on_add = function(player, sessionId)
	player.character.position.on_change = function(changes)
                local position = {}
		for i, change in ipairs(changes) do
			if change.field == &quot;x&quot; then
				position[&quot;x&quot;] = change.value
			end
			if change.field == &quot;y&quot; then
				position[&quot;y&quot;] = change.value
			end
		end
                print(&quot;new position&quot;, inspect(changes))
	end
end
</code></pre>
<p>I know that the state changes are successfully making it from one client, to the server, and back to the other client, because I see the player on one client move on the other (and also from the logs).</p>
<p>When one client moves, therefore updating the state, I see only messages from the more specific callbacks:</p>
<pre><code>DEBUG:SCRIPT: new position	{
  x = 869.49731445313,
  y = 370.85791015625
}
</code></pre>
<p>However I expect to see not only that, but also a message like:</p>
<pre><code>DEBUG:SCRIPT: base state change
</code></pre>
<p>Do I misunderstand how these callbacks work? I would assume that if I assign a callback to the root state, it would fire any time anything changes within that state (recursively).</p>
<p>Also, in the docs here (<a href="https://docs.colyseus.io/state/overview/" rel="nofollow">https://docs.colyseus.io/state/overview/</a>) it says that binary patches of the state are sent to the client every 50ms. Is it the case that if there are no changes, it sends nothing, and therefore the callback doesn't fire?</p>
<p>One specific reason I want a generic callback is I want to estimate how often I receive updates from the client so I can lerp the other players' movements accurately, though I think having a base callback might be useful in other ways.</p>
<p>In short, I'm not quite sure how <code>on_change</code> works, and I can't really figure it out from the docs (&quot;this event is triggered when the server updates its state&quot;, it doesn't really elaborate on which callbacks get called for which state).</p>
<p>Thanks everyone!</p>
]]></description><link>http://discuss.colyseus.io/post/1483</link><guid isPermaLink="true">http://discuss.colyseus.io/post/1483</guid><dc:creator><![CDATA[banool]]></dc:creator><pubDate>Invalid Date</pubDate></item><item><title><![CDATA[Reply to [Defold] room.state.on_change does not get triggered on state change on Invalid Date]]></title><description><![CDATA[<p>Hi <a class="plugin-mentions-user plugin-mentions-a" href="http://discuss.colyseus.io/uid/792">@banool</a>!</p>
<p>I think you're looking for <code>room:on(&quot;statechange&quot;, ...)</code>: <a href="https://docs.colyseus.io/client/room/#onstatechange" rel="nofollow">https://docs.colyseus.io/client/room/#onstatechange</a></p>
<p>Thanks for the observation about the documentation, it is not clear indeed. The &quot;on change&quot; callbacks are not recursive since <code>colyseus@0.14</code> - the new schema implementation introduced a concept of <code>refId</code> and instance references. Changes are triggered directly and only on the instance in which a change has happened by their <code>refId</code>.</p>
<p>I hope this helps! Feel free to post any issues and/or suggestions here or on Discord! Cheers!</p>
]]></description><link>http://discuss.colyseus.io/post/1484</link><guid isPermaLink="true">http://discuss.colyseus.io/post/1484</guid><dc:creator><![CDATA[endel]]></dc:creator><pubDate>Invalid Date</pubDate></item><item><title><![CDATA[Reply to [Defold] room.state.on_change does not get triggered on state change on Invalid Date]]></title><description><![CDATA[<p>Hi!</p>
<p>Thanks for the super quick response. I see different options in different places:</p>
<ul>
<li><code>room.state.on_change</code></li>
<li><code>room.state[&quot;on_change&quot;]</code></li>
<li><code>room:on(&quot;statechange&quot;)</code></li>
</ul>
<p>I'll go with the latter from now on.</p>
<p>Good to know that the on change callbacks are not recursive. I can put up a PR to make this a bit clearer on the docs.</p>
<p>Thanks!</p>
]]></description><link>http://discuss.colyseus.io/post/1485</link><guid isPermaLink="true">http://discuss.colyseus.io/post/1485</guid><dc:creator><![CDATA[banool]]></dc:creator><pubDate>Invalid Date</pubDate></item><item><title><![CDATA[Reply to [Defold] room.state.on_change does not get triggered on state change on Invalid Date]]></title><description><![CDATA[<p>No worries! In fact <code>room.state.on_change</code> and <code>room.state[&quot;on_change&quot;]</code> are just different in syntax, they are actually equal!</p>
<blockquote>
<p>I can put up a PR to make this a bit clearer on the docs.</p>
</blockquote>
<p>That'd be much appreciated! 🙏</p>
<p>Cheers!</p>
]]></description><link>http://discuss.colyseus.io/post/1486</link><guid isPermaLink="true">http://discuss.colyseus.io/post/1486</guid><dc:creator><![CDATA[endel]]></dc:creator><pubDate>Invalid Date</pubDate></item></channel></rss>