<?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[Stencyl (HaXe) Extension]]></title><description><![CDATA[<p>This week I've started using Colyseus. I'm going to try to create a HaXe Extension for Stencyl so that I can publish multiplayer games with Colyseus.<br />
Previously I've created a couple of multiplayer extensions for Stencyl but failed to get anything near realtime. Maybe Colyseus can help?!?<br />
From first glance the Colyseus stuff looks great. I love the fact that I can run the server on my own infrastructure.</p>
<p>It will be a long road ahead and I've decided to start this Showcase thread to let you all follow my progress. Maybe you can help me along the way?!?</p>
<p>First I started by porting the example nyancat to a Stencyl game (Using a bitmap for the cat)</p>
<p>Flash publication failed! I've tried to put the flash (swf) on the same server and experimented with crossdomain.xml. But apparently websockets do not care about that.</p>
<p>Working clients:</p>
<ul>
<li>HTML5 (Tested only Chrome)</li>
<li>Windows native</li>
<li>Mac OSX native</li>
<li>iOS (iPad mini)</li>
<li>iOS Simulator (iPhone 5s)</li>
<li>Android (Samsung S3 Note)</li>
<li>Linux</li>
</ul>
]]></description><link>http://discuss.colyseus.io/topic/197/stencyl-haxe-extension</link><generator>RSS for Node</generator><lastBuildDate>Sun, 14 Jun 2026 00:34:35 GMT</lastBuildDate><atom:link href="http://discuss.colyseus.io/topic/197.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 06 Jan 2019 22:46:14 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Stencyl (HaXe) Extension on Invalid Date]]></title><description><![CDATA[<p>This week I've started using Colyseus. I'm going to try to create a HaXe Extension for Stencyl so that I can publish multiplayer games with Colyseus.<br />
Previously I've created a couple of multiplayer extensions for Stencyl but failed to get anything near realtime. Maybe Colyseus can help?!?<br />
From first glance the Colyseus stuff looks great. I love the fact that I can run the server on my own infrastructure.</p>
<p>It will be a long road ahead and I've decided to start this Showcase thread to let you all follow my progress. Maybe you can help me along the way?!?</p>
<p>First I started by porting the example nyancat to a Stencyl game (Using a bitmap for the cat)</p>
<p>Flash publication failed! I've tried to put the flash (swf) on the same server and experimented with crossdomain.xml. But apparently websockets do not care about that.</p>
<p>Working clients:</p>
<ul>
<li>HTML5 (Tested only Chrome)</li>
<li>Windows native</li>
<li>Mac OSX native</li>
<li>iOS (iPad mini)</li>
<li>iOS Simulator (iPhone 5s)</li>
<li>Android (Samsung S3 Note)</li>
<li>Linux</li>
</ul>
]]></description><link>http://discuss.colyseus.io/post/636</link><guid isPermaLink="true">http://discuss.colyseus.io/post/636</guid><dc:creator><![CDATA[mdotedot]]></dc:creator><pubDate>Invalid Date</pubDate></item><item><title><![CDATA[Reply to Stencyl (HaXe) Extension on Invalid Date]]></title><description><![CDATA[<p>Since I like developers journals myself, I'm writing one for the Stencyl Colyseus Extension journey.</p>
<p>The main idea of the Stencyl Extension is a general purpose Server with accommodating Stencyl blocks.<br />
Not sure if that is the right approach, but that is the path I take now.</p>
<p>Goals:</p>
<ul>
<li>Application ID system</li>
<li>Lobby system</li>
<li>Turn Based system</li>
<li>System that one client acts as a server for the other clients and itself</li>
<li>Chat system</li>
</ul>
<p>First, I want something persistent. Currently the thought process is that there is a LobbyRoom.<br />
That can be used for MatchMaking but I hope to use it for public storage of the application IDs.</p>
<p><strong>Persistence</strong></p>
<p>The journey leads to investigations on how to store application ids.<br />
This can be using a simple text file since I'm aiming for a single server (at this time) and I<br />
hopefully don't need a (shared) database server.</p>
<p>Test LocalPresence : adjusted rooms/01-chat-room.ts</p>
<pre><code>import { LocalPresence } from &quot;colyseus&quot;;
</code></pre>
<p>after   maxClients = 4;</p>
<pre><code>private presence:LocalPresence=new LocalPresence();
</code></pre>
<p>Added to onMessage:</p>
<pre><code>var msg = this.presence.hget(&quot;MdotTest&quot;,&quot;Field&quot;);
console.log(&quot;Last Message: &quot;, msg);
this.presence.hset(&quot;MdotTest&quot;, &quot;Field&quot;, data.message);
</code></pre>
<p>This works really well. When leaving room and joining again it still knew the last message.<br />
However, when I kill the server and start it up the data is lost.</p>
<p>I couldn't find any writing to files in <a href="https://github.com/colyseus/colyseus/tree/master/src/presence" rel="nofollow">https://github.com/colyseus/colyseus/tree/master/src/presence</a></p>
<p>In RedisPresence there is use of promisfy but no where is something with files (at least so far I can see)</p>
<p>How do we do server reboot persistence?!</p>
<p>This is what I hacked together and I'm sure there is something else that I should be doing so please point m.e. to the better thing!!!</p>
<pre><code>import { readFileSync,writeFileSync } from &quot;fs&quot;;
</code></pre>
<p>Added to onJoin:</p>
<pre><code>var jsonfile=JSON.parse(readFileSync('temp.txt','utf8'));
var item=jsonfile.hash;
//console.log('item', item.MdotTest.Field);
this.presence.hset(&quot;MdotTest&quot;, &quot;Field&quot;, item);
</code></pre>
<p>Added to onDispose:</p>
<pre><code>writeFileSync(&quot;temp.txt&quot;, JSON.stringify(this.presence));
</code></pre>
<p>Now at least the data is persistent even when there is a server boot/crash/shutdown (not when it crashes when writing ...)</p>
]]></description><link>http://discuss.colyseus.io/post/648</link><guid isPermaLink="true">http://discuss.colyseus.io/post/648</guid><dc:creator><![CDATA[mdotedot]]></dc:creator><pubDate>Invalid Date</pubDate></item><item><title><![CDATA[Reply to Stencyl (HaXe) Extension on Invalid Date]]></title><description><![CDATA[<p>hey <a class="plugin-mentions-user plugin-mentions-a" href="http://discuss.colyseus.io/uid/282">@mdotedot</a>, not exactly sure what you're planning to build, but to persist the data across server reboots you can use the <code>RedisPresence</code> alternative. The <code>LocalPresence</code> really doesn't persist any data. Cheers!</p>
]]></description><link>http://discuss.colyseus.io/post/649</link><guid isPermaLink="true">http://discuss.colyseus.io/post/649</guid><dc:creator><![CDATA[endel]]></dc:creator><pubDate>Invalid Date</pubDate></item><item><title><![CDATA[Reply to Stencyl (HaXe) Extension on Invalid Date]]></title><description><![CDATA[<p>Thanks Endel! It appears that RedisPresence needs a Redis Server!<br />
When using RedisPresence and you don't have a running Redis Server you get this:</p>
<pre><code>Could not connect to Redis at 127.0.0.1:6379: Connection refused
</code></pre>
<p>For running a server this quick start is available : <a href="https://redis.io/topics/quickstart" rel="nofollow">https://redis.io/topics/quickstart</a></p>
<p>I hate to run different things on the server since I want to have deployment by the Extension users as easy as it can be.</p>
<p>Maybe I will revisit this approach when I need persistence.<br />
I've changed the approach to ApplicationIDs and 'just' generate some IDs for the Extension Users.</p>
<p>In the chat I've been told that one of my room-mechanism approach will fail. We will see where this thing is going to crash ...<br />
I'm not promising that I can create a general purpose server for all kinds of clients.<br />
If an approach don't work, extension users still have the ability to change the server themselves.<br />
Although they probably lack the skills, they can hire you guys to make the server for them :D<br />
There will be overhead on the proxy mechanism, but we will see what can be done.<br />
Rather than saying that running logic on client is impossible I still want to try it.<br />
Using the Colyseus server as a proxy to the active client.</p>
<p>For now I've created a turn based mechanism on the server that I need to write some clients for.</p>
<p>The example : 02-state-handler.ts appears to be working correctly with below additions, but I guess that I need to investigate<br />
different types of turn based games and their server-side logic.</p>
<p>These are the steps taken to rotate player activity: (Modify 02-state-handler.ts)</p>
<p>After : something = &quot;This ...</p>
<pre><code>
        nextPlayer(){
                var doNext=false;
                for(var m in this.players){
                        if(doNext){
                                this.players[m].ActivePlayer=m;
                                doNext=false;
                        }else{
                                if(this.players[m].ActivePlayer != &quot;&quot;){
                                        this.players[m].ActivePlayer=&quot;&quot;;
                                        doNext=true;
                                }
                        }
                } // check Next available player
                if(doNext){ // if we need to shift but there are no players after : first player
                        for(var m in this.players){
                                if(doNext){
                                        this.players[m].ActivePlayer=m;
                                        doNext=false;
                                }
                        }// go through all players
                } // check first available player
        }// ActivePlayer shift
// Changed createPlayer
    createPlayer (id: string, room:Room) {
        this.players[ id ] = new Player();
        if(room.clients.length == 1){ // first player in room
                this.players[id].ActivePlayer=id;
        }
    } // createPlayer

</code></pre>
<p>In removePlayer we need to check if the leaving player is the active player and rotate when necessary:</p>
<pre><code>    if(this.players[id].ActivePlayer!=&quot;&quot;)this.nextPlayer(); 
</code></pre>
<p>movePlayer includes a check on activity: After movePlayer(id: string, movement: any){</p>
<pre><code>   
        if(this.players[id].ActivePlayer != id)	return; // ignore move when not active
		
</code></pre>
<p>And before the end of the function:</p>
<pre><code>	this.nextPlayer(); // after move 
</code></pre>
<p>Adjusted class Player with the ActivePlayer :</p>
<pre><code>
export class Player {
    x = Math.floor(Math.random() * 400);
    y = Math.floor(Math.random() * 400);
        ActivePlayer = &quot;&quot;;
}

</code></pre>
<p>Adjusted onJoin :</p>
<pre><code>   this.state.createPlayer(client.sessionId, this);
</code></pre>
<p>When running this example the players can only move when it is their turn.<br />
It is a basic example with no validation on move or if time expired etc..</p>
]]></description><link>http://discuss.colyseus.io/post/650</link><guid isPermaLink="true">http://discuss.colyseus.io/post/650</guid><dc:creator><![CDATA[mdotedot]]></dc:creator><pubDate>Invalid Date</pubDate></item><item><title><![CDATA[Reply to Stencyl (HaXe) Extension on Sat, 19 Jan 2019 18:43:47 GMT]]></title><description><![CDATA[<p>This week I've tried to make a few Stencyl Extension blocks:</p>
<ul>
<li>get Player (ID / Name)</li>
<li>get Room (ID / Name)</li>
<li>assign Name [..] to [room/player] with id []</li>
<li>List of Rooms</li>
<li>List of Players</li>
</ul>
<p>It took me a while to find out that <a href="http://client.id" rel="nofollow">client.id</a> != <a href="http://player.id" rel="nofollow">player.id</a>. It appears that player is instantiated with room.SessionId.</p>
<p>Then it took me a lot longer to get a list of rooms (of the same type).<br />
getAvailableRooms seems to show a list of rooms where you can join to, not the ones that are full or something like that.<br />
I (also) want rooms with large number of possible clients, so the client is now always joining the same room where I want the client to be able to create a new room.</p>
<p>Apparently we need to use the MatchMaker to get a list of rooms. But I fail to get it to use.<br />
It is a Server component, but how do I access this from the client when the client isn't in a room?</p>
<p>I've also looked at the example on MatchMaker but it registered the rooms differently then I was seeing in the 02-state-change example<br />
Source: <a href="https://github.com/colyseus/colyseus/blob/master/src/MatchMaker.ts" rel="nofollow">https://github.com/colyseus/colyseus/blob/master/src/MatchMaker.ts</a></p>
<p>At last I've hacked something together that appears to be working for now.</p>
<p>globals.ts:</p>
<pre><code>//
// Global data for the server
//
export abstract class Globals{
        private static theRooms =  [];

        public static set(index:string,value:string){
                this.theRooms[index]=value;
        }
// get, remove as well when room gets disposed
}
</code></pre>
<p>This static class can hold 'server-wide' globals as long as you import them in your room-code, like:</p>
<pre><code>import { Globals } from &quot;../globals&quot;; // global data from the server

//  onInit :
  Globals.set(&quot;&quot;+this.roomId, &quot;state_handler&quot;);

</code></pre>
<p>This method allows me to get the list of rooms from other client sessions and even for other rooms when I want...</p>
<p>I'm sure that there is another way to get this done using the MatchMaker but I couldn't find example of this.</p>
]]></description><link>http://discuss.colyseus.io/post/659</link><guid isPermaLink="true">http://discuss.colyseus.io/post/659</guid><dc:creator><![CDATA[mdotedot]]></dc:creator><pubDate>Sat, 19 Jan 2019 18:43:47 GMT</pubDate></item><item><title><![CDATA[Reply to Stencyl (HaXe) Extension on Invalid Date]]></title><description><![CDATA[<p>Since a couple of days I'm making a mess of things :(</p>
<p>I have a feeling that I'm doing this the wrong way.</p>
<p>It all started with the 02-state-handler.ts</p>
<p>What I conclude is that you have a client that has an ID and that is constant no matter what room is created or joined.<br />
However each joining or creation of a room is done with a session ID. SessionID != <a href="http://Client.ID" rel="nofollow">Client.ID</a></p>
<p>I want the game(s) to be able to get a list of players in the room.</p>
<pre><code>export class RoomData{
    playernames = &quot;&quot;;
    roomnames = &quot;&quot;;
    roomids = &quot;&quot;;
    sessionids = &quot;&quot;;
}

export class Player {
	ID = &quot;&quot;;
	Name = &quot;&quot;;
    x = Math.floor(Math.random() * 400);
    y = Math.floor(Math.random() * 400);
    width = 132;
    height = 132;

}
</code></pre>
<p>Currently I use the RoomData class to alter the state of the server. These RoomData members are being broadcasted to the clients.<br />
It feels kind of hacky to set these variables to have the roomstate being synchronized.</p>
<p>The way that I'm currently setting these values is in client (room.send) and server onMessage communications.</p>
<p>This is the current client perspective:</p>
<p>New Room:</p>
<p><img src="http://photoquesting.com/Colyseus/NewRoom.PNG" alt="http://photoquesting.com/Colyseus/NewRoom.PNG" class="img-responsive img-markdown" /></p>
<p>Second Room:</p>
<p><img src="http://photoquesting.com/Colyseus/SecondRoom.PNG" alt="http://photoquesting.com/Colyseus/SecondRoom.PNG" class="img-responsive img-markdown" /></p>
<p>Joining From the other Room (looks like it works)</p>
<p><img src="http://photoquesting.com/Colyseus/JoinedRoom.PNG" alt="http://photoquesting.com/Colyseus/JoinedRoom.PNG" class="img-responsive img-markdown" /></p>
<p>And second player joining the third  (this fails : player seems to be in two rooms ??!? )</p>
<p><img src="http://photoquesting.com/Colyseus/ThirdRoom.PNG" alt="http://photoquesting.com/Colyseus/ThirdRoom.PNG" class="img-responsive img-markdown" /></p>
<p>Server Side Data :</p>
<pre><code>
roomName with id:  RoomName:3tAeV4aU7 the changeID is pQZlJiSNb  the ID without Name:  3tAeV4aU7  the name is  Room424
roomName with id:  RoomName:MZOaBj7hu the changeID is pQZlJiSNb  the ID without Name:  MZOaBj7hu  the name is  Room6959
roomName with id:  RoomName:pQZlJiSNb the changeID is pQZlJiSNb  the ID without Name:  pQZlJiSNb  the name is  Room7704
roomnames:  3tAeV4aU7=Room424:MZOaBj7hu=Room6959:pQZlJiSNb=Room7704:
playername with id:  PlayerName:iwIpOcjZs  the changeID is pQZlJiSNb  the id without name:  iwIpOcjZs  the name is  Player8707
playername with id:  PlayerName:j6a-rk8dc  the changeID is pQZlJiSNb  the id without name:  j6a-rk8dc  the name is  Player4301
playername with id:  PlayerName:EsP17dY-m  the changeID is pQZlJiSNb  the id without name:  EsP17dY-m  the name is  Player1374
playernames:  iwIpOcjZs=Player8707:j6a-rk8dc=Player4301:EsP17dY-m=Player1374

</code></pre>
<p>As it is fairly hacky stuff I'm hoping that someone has dealt with this before and can shed some light ....</p>
<p>When I don't use <a href="http://Client.ID" rel="nofollow">Client.ID</a> and only show SessionIDs it worked much better, but how can I get a client (name) from a session?<br />
The Player Class data does not appear to be part of a state. What should I do to get Player List with Names?!</p>
]]></description><link>http://discuss.colyseus.io/post/663</link><guid isPermaLink="true">http://discuss.colyseus.io/post/663</guid><dc:creator><![CDATA[mdotedot]]></dc:creator><pubDate>Invalid Date</pubDate></item><item><title><![CDATA[Reply to Stencyl (HaXe) Extension on Invalid Date]]></title><description><![CDATA[<p>Since I couldn't get HaXe Json to work (it doesn't know the format) I used Reflection to get the information I need:</p>
<pre><code>// Get The Player ID/Name
			var thePlayers:Dynamic = Reflect.field(state, &quot;players&quot; );
			var sessionIDs:Array&lt;Dynamic&gt; = Std.string(thePlayers).split(&quot;: {&quot;);
			for(sessionID in sessionIDs){
				var sessionid:String=&quot;&quot;;
				if(sessionID.indexOf(&quot;{&quot;) == 0) sessionid=sessionID.split(&quot;{&quot;)[1]; // for the first player
				if(sessionID.indexOf(&quot;},&quot;) &gt; 0) sessionid=sessionID.split(&quot;},&quot;)[1]; // for all the rest
				if(sessionid == null) sessionid=sessionID;

				var onePlayer:Dynamic = Reflect.field(thePlayers, StringTools.trim(sessionid));
	
				var ID:String = Reflect.field(onePlayer, &quot;ID&quot; );
				if(ID != null &amp;&amp; ID.length &gt; 0)	trace(&quot;playerlist One Player . ID : &quot;+ID);
				var Name:String = Reflect.field(onePlayer, &quot;Name&quot; );
				if(Name != null &amp;&amp; Name.length &gt; 0) trace(&quot;playerlist OnePlayer . Name : &quot; + Name);
				
			} // for all sessionIDs in the room
			
</code></pre>
<p>Now it can get the ID and Name from the Player Class !</p>
<p>This seems a lot better than the previous approach.</p>
<p>I can also now use the availableRooms construction since I use a method on the requestJoin where an option is given when joining a room as oposed to creating a new one...</p>
<p>I might need to use the RoomData for the name of the Room. But maybe someone else has some opinions about it?!</p>
]]></description><link>http://discuss.colyseus.io/post/664</link><guid isPermaLink="true">http://discuss.colyseus.io/post/664</guid><dc:creator><![CDATA[mdotedot]]></dc:creator><pubDate>Invalid Date</pubDate></item><item><title><![CDATA[Reply to Stencyl (HaXe) Extension on Invalid Date]]></title><description><![CDATA[<p>Client debugging ... Leaving both current and joining room with just one room.leave() call ....</p>
<p>HTML5 works well, Windows is doing well most of the time, but Mac and Android are having troubles in leaving and joining. I suspect that Windows problems are caused by the same issue, but couldn't steadily reproduce that.</p>
<p>It is the same HaXe client-code due to being a HaXe extension.<br />
There are only differences in Player Name gathering on HTML versus  native. Didn't test iOS/Linux.</p>
<p>What I think is happening is that room.leave() is done twice on Mac/Android?!?<br />
What can be the cause of this?!</p>
<p>HTML5 debug:</p>
<pre><code> Colyseus.hx:156:  JoinRoom to joinID: BWNT-kGd0  Calling Room Leave with room.id: NRL_w4txR
 Colyseus.hx:421: leavecounter: 1 room.onLeave RoomID: NRL_w4txR Session ID: XqE4dF-s6  
 Colyseus.hx:275: (Client: )p6_HgFPtE join room to JoinID : BWNT-kGd0
 
Good: 
 Colyseus.hx:304:  joinRoom : joinCounter: 2  Joined Room BWNT-kGd0 sessionID : VXeeGm4oI
</code></pre>
<p>Debug Mac:</p>
<pre><code> Colyseus.hx:156:  JoinRoom to joinID: z40eavIgr  Calling Room Leave with room.id: Ge_RICPir
 Colyseus.hx:421: leavecounter: 1 room.onLeave RoomID: Ge_RICPir Session ID: f2c1YeU3i  
 Colyseus.hx:275: (Client: )9EoXglrY9 join room to JoinID : z40eavIgr
 Colyseus.hx:421: leavecounter: 2 room.onLeave RoomID: z40eavIgr Session ID: null  
</code></pre>
<p>Never reached joinRoom!!<br />
And it does TWO leave rooms !!!</p>
<p>The output on server side is the same (of course not the IDs and names ...)</p>
<p>HTML5</p>
<pre><code>Request join : this.roomId: NRL_w4txR  options.Type:  undefined PlayerName:  APlayer3642  OldMax:  1
Number of clients in room:  1  the room id is :  NRL_w4txR
Request join : this.roomId: NRL_w4txR  options.Type:  undefined PlayerName:  APlayer7523  OldMax:  100
Request join : this.roomId: NRL_w4txR  options.Type:  undefined PlayerName:  APlayer7523  OldMax:  100
StateHandlerRoom created! { PlayerName: 'APlayer7523',
  RoomName: 'Room5672',
  requestId: 2,
  clientId: '3VTAK8HPh',
  lobby: { rooms: [] } }
Request join : this.roomId: BWNT-kGd0  options.Type:  undefined PlayerName:  APlayer7523  OldMax:  1
Number of clients in room:  1  the room id is :  BWNT-kGd0
Number of clients in room:  0  the room id is :  NRL_w4txR
Dispose StateHandlerRoom :   remove room.id     :  NRL_w4txR
Request join : this.roomId: BWNT-kGd0  options.Type:  JOIN PlayerName:  APlayer3642  OldMax:  100
Number of clients in room:  2  the room id is :  BWNT-kGd0
Number of clients in room:  1  the room id is :  BWNT-kGd0
</code></pre>
<p>MAC:</p>
<pre><code>Request join : this.roomId: Ge_RICPir  options.Type:  undefined PlayerName:  APlayer7255  OldMax:  1
Number of clients in room:  1  the room id is :  Ge_RICPir
Request join : this.roomId: Ge_RICPir  options.Type:  undefined PlayerName:  Player5710  OldMax:  100
Request join : this.roomId: Ge_RICPir  options.Type:  undefined PlayerName:  Player5710  OldMax:  100
StateHandlerRoom created! { PlayerName: 'Player5710',
  RoomName: 'Room1021',
  requestId: 4,
  clientId: 'vJGYZCiJ5',
  lobby: { rooms: [] } }
Request join : this.roomId: z40eavIgr  options.Type:  undefined PlayerName:  Player5710  OldMax:  1
Number of clients in room:  1  the room id is :  z40eavIgr
Number of clients in room:  0  the room id is :  Ge_RICPir
Dispose StateHandlerRoom :   remove room.id     :  Ge_RICPir
Request join : this.roomId: z40eavIgr  options.Type:  JOIN PlayerName:  APlayer7255  OldMax:  100
Number of clients in room:  2  the room id is :  z40eavIgr
Number of clients in room:  1  the room id is :  z40eavIgr
</code></pre>
<p>I even used a timer to call join after the leave so that it does it 5 or 10 seconds later.<br />
As soon as I do the join the leave call is executed !!!</p>
]]></description><link>http://discuss.colyseus.io/post/671</link><guid isPermaLink="true">http://discuss.colyseus.io/post/671</guid><dc:creator><![CDATA[mdotedot]]></dc:creator><pubDate>Invalid Date</pubDate></item><item><title><![CDATA[Reply to Stencyl (HaXe) Extension on Invalid Date]]></title><description><![CDATA[<p>Colyseus : Leaving room</p>
<p>Since a couple of weeks I'm debugging the leaving room situation. It is kind of driving m.e. nuts.</p>
<p>Today I started over since I was not sure if my player information was ruining stuff or the leaving room situation.</p>
<p>All seems well with HTML5. But the CPP builds (Windows and Android) are giving me problems.</p>
<p>Most of the time the Windows build performs well, unless I try to do a Windows debug build. Then it crashes immediately.</p>
<p>Running the Android version gives me almost immediately problems. (I estimate that it is doing leave room twice so the new room is left immediately)</p>
<pre><code>trace(&quot;input.readBytes catch : &quot;+e);				
if(Std.is(e,Error)) trace(&quot;isError&quot;); // still OK
/* Output:
input.readBytes catch : Custom(EOF)
isError 
*/
// Below line crashes: debug build 
//if( (e:Error).match(Error.Custom(Error.Blocked)) ) trace(&quot;ErrorCustom&quot;);  // Null Pointer Exception
 
 // And since it is used in the needClose detection it fails
                     needClose = !(e == 'Blocking' || (Std.is(e, Error) &amp;&amp; (
                        (e:Error).match(Error.Custom(Error.Blocked)) ||
                        (e:Error).match(Error.Blocked))
                    ));
</code></pre>
<p>So I cannot debug using Visual Studio...</p>
<p>But I don't care if Windows Debugger works as long as the issue can be resolved without it ...</p>
<p>This is the code that works:</p>
<pre><code>
  public static function joinRoom(ID:String){
	  if(isInit){
		var theOptions:Map&lt;String, Dynamic&gt;=new Map();
		theOptions.set(&quot;Type&quot;, &quot;JOIN&quot;);
		theOptions.set(&quot;PlayerName&quot;, &quot;TESTPLAYER&quot; );
		//if(room!=null) room.leave();				
		room =  client.join(&quot;&quot;+ID, theOptions);
	  }
	  
  }// joinRoom
  
  public static function createRoom(RoomType:String){
	if(isInit){
		var theOptions:Map&lt;String, Dynamic&gt;=new Map();
		theOptions.set(&quot;Type&quot;, &quot;NEW&quot;);
		theOptions.set(&quot;PlayerName&quot;, &quot;TESTPLAYER&quot; );
		//if(room!=null) room.leave();
		room =  client.join(RoomType, theOptions);  
	}
  }
  

</code></pre>
<p>But when I comment out the room.leave so that it actually leaves to current room and then Android gives me problems and<br />
sometimes Windows crashes or gives the same problem (0 clients in room and then the room will be autodisposed)</p>
<p>Any suggestions are appreciated!</p>
<p>By the way : if I don't use room.leave and use the colyseus monitor to dispose them it works fine(!)</p>
<p>Also, I tried using a timer behind the room.leave to allow the engine to dispose the room but it looks like leave is called when I initiated another room.</p>
<p>I also tried using an Array of rooms where I leave the room[roomCounter] but this acts like it is also leaving the initiated room</p>
]]></description><link>http://discuss.colyseus.io/post/707</link><guid isPermaLink="true">http://discuss.colyseus.io/post/707</guid><dc:creator><![CDATA[mdotedot]]></dc:creator><pubDate>Invalid Date</pubDate></item><item><title><![CDATA[Reply to Stencyl (HaXe) Extension on Invalid Date]]></title><description><![CDATA[<p>Colyseus leaving room part 3</p>
<p>There hasn't been made any client side communication yet and I have worked for over a month on this room leaving situation.<br />
I really hope this isn't the way that all the other stuff is going to turn out :(</p>
<p>Sending 'LEAVE' to the server and let the server disconnect the client is also not reliable!</p>
<p>Modified SocketSys.hx to avoid crash on windows:</p>
<pre><code>					// Do not use        (e:Error).match(Error.Custom(Error.Blocked)) ||
                     needClose = !(e == 'Blocking' || (Std.is(e, Error) &amp;&amp; (
                        (e:Error).match(Error.Blocked))
                    ));
					
</code></pre>
<p>New direction :        Plan for failure!<br />
Since I cannot do a steady leave room and since there can be other situations that lead to errors: I decided that the client/game needs to react on the errors.</p>
<p>This led to changes to the Colyseus HaXe code since some errors (websocket and connection) aren't passed to Room.onError<br />
Connection.hx</p>
<pre><code>	// This does not throw onError on room .. this message cannot be detected
	this.ws.onerror = function(message) {
            this.onError(message);  // this isn't caught in Room.onError !!!!
			// Stencyl notification (import com.stencyl.behavior.Script.*;)
			if(getGameAttribute(&quot;ColyseusErrorMessage&quot;) == null)setGameAttribute(&quot;ColyseusErrorMessage&quot;, &quot;&quot;); setGameAttribute(&quot;ColyseusErrorMessage&quot;, &quot;&quot;+getGameAttribute(&quot;ColyseusErrorMessage&quot;)+&quot; : &quot;+message); //M.E.

        }

</code></pre>
<p>Unfortunately Mac OSX build still produces crash sometimes</p>
<pre><code>
[My Game] 2019-02-25 00:36:22.937 My Game[28583:2109033] -[NSPersistentUIWindowSnapshotter writeWindowSnapshot:length:width:height:bytesPerRow:toFile:inDirectory:encryptingWithKey:uuid:checksum:fd:]: 0 == ftruncate(fd, finalFileSize) failed on line 797: Bad file descriptor
[My Game] 2019-02-25 00:36:22.939 My Game[28583:2109033] -[NSPersistentUIWindowSnapshotter writeWindowSnapshot:length:width:height:bytesPerRow:toFile:inDirectory:encryptingWithKey:uuid:checksum:fd:]: 0 == ftruncate(fd, fileLength) failed on line 868: Bad file descriptor
DEBUG [Thread-17] stencyl.sw.util.net.SocketServer: _disconnected: Socket[addr=/127.0.0.1,port=49807,localport=18525]

</code></pre>
<p>As well as the Android build for which I am unable to get logs.<br />
But it happens less than before.</p>
<p>There are also situations where there are rooms left with 0 clients in them, even when the application/game is killed. And even the Colyseus monitor</p>
<p>Now it is time to work on the room information like a playerlist. Hopefully this does not take much time and doesn't interfere with the current workaround.</p>
<p>Still, if anyone has any tips , experiences or possible things I can try relating to the     <strong>(e:Error).match(Error.Custom(Error.Blocked)) ||</strong><br />
or the <strong>Mac OSX Bad file descriptor</strong><br />
I very much like to know!!</p>
]]></description><link>http://discuss.colyseus.io/post/709</link><guid isPermaLink="true">http://discuss.colyseus.io/post/709</guid><dc:creator><![CDATA[mdotedot]]></dc:creator><pubDate>Invalid Date</pubDate></item><item><title><![CDATA[Reply to Stencyl (HaXe) Extension on Invalid Date]]></title><description><![CDATA[<p>hey <a class="plugin-mentions-user plugin-mentions-a" href="http://discuss.colyseus.io/uid/282">@mdotedot</a>, are you going to open-source your Stencyl extension? I'd like to check the errors you're having, calling <code>.leave()</code> really shouldn't crash the application. Cheers!</p>
]]></description><link>http://discuss.colyseus.io/post/710</link><guid isPermaLink="true">http://discuss.colyseus.io/post/710</guid><dc:creator><![CDATA[endel]]></dc:creator><pubDate>Invalid Date</pubDate></item><item><title><![CDATA[Reply to Stencyl (HaXe) Extension on Invalid Date]]></title><description><![CDATA[<p>If all goes well the Stencyl Extension will become available to the Stencyl Community.</p>
<p>It would be awesome if you could help me with the crash-code.</p>
<p>Maybe you know of an alternative way to do the match(Error.Custom(Error.Blocked) line.</p>
]]></description><link>http://discuss.colyseus.io/post/711</link><guid isPermaLink="true">http://discuss.colyseus.io/post/711</guid><dc:creator><![CDATA[mdotedot]]></dc:creator><pubDate>Invalid Date</pubDate></item><item><title><![CDATA[Reply to Stencyl (HaXe) Extension on Invalid Date]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="http://discuss.colyseus.io/uid/282">@mdotedot</a> would you mind sharing your extension on GitHub? if you don't wanna make it public for now, you can invite me privately first maybe. Cheers</p>
]]></description><link>http://discuss.colyseus.io/post/712</link><guid isPermaLink="true">http://discuss.colyseus.io/post/712</guid><dc:creator><![CDATA[endel]]></dc:creator><pubDate>Invalid Date</pubDate></item><item><title><![CDATA[Reply to Stencyl (HaXe) Extension on Invalid Date]]></title><description><![CDATA[<p>Steps to reproduce:</p>
<p>Followed : <a href="https://www.wikihow.com/Install-Node.Js-on-Windows" rel="nofollow">https://www.wikihow.com/Install-Node.Js-on-Windows</a> to install NPM</p>
<ul>
<li><a href="https://nodejs.org/en/" rel="nofollow">https://nodejs.org/en/</a>  Download and run: \users\Administrator\Downloads\node-v10.15.1-x64.msi</li>
</ul>
<pre><code>set PATH=c:\&quot;Program Files&quot;\nodejs;%HAXE_PATH%;%NEKOPATH%;%PATH%
node -v

npm install typescript
</code></pre>
<p>Download colyseus examples: <a href="https://github.com/colyseus/colyseus-examples" rel="nofollow">https://github.com/colyseus/colyseus-examples</a>  : Clone/Download ZIP<br />
Extract in C:\</p>
<pre><code>cd \colyseus-examples-master
npm install

npm run bundle-colyseus-client
npm start
</code></pre>
<p><strong>Now for the HaXe Part</strong>:</p>
<p>Download <a href="https://github.com/HaxeFoundation/haxe/releases/download/3.4.4/haxe-3.4.4-win64.exe" rel="nofollow">https://github.com/HaxeFoundation/haxe/releases/download/3.4.4/haxe-3.4.4-win64.exe</a></p>
<pre><code>c:&gt; haxe-3.4.4-win65.exe
</code></pre>
<p>let it create default c:\HaxeToolkit :</p>
<p>Setting DOS Environment:</p>
<pre><code>set HAXE_PATH=c:\HaxeToolkit\haxe
set NEKOPATH=c:\HaxeToolkit\neko
set PATH=%HAXE_PATH%;%NEKOPATH%;%PATH%

haxelib setup c:\HaxeToolkit\haxe\lib
haxelib --global update haxelib

haxelib install openfl
haxelib run openfl setup
haxelib run lime setup 
lime create HelloWorld
cd HelloWorld
lime test html5

lime setup windows
</code></pre>
<p>Download Visual Studio 16<br />
vs_community__956414624.1551197993.exe<br />
Choose : Desktop development with C++      AND    Click C++/CLI support</p>
<pre><code>lime test windows
</code></pre>
<p>The installed 4.0.8 hxcpp does not contain run script apparantly , so set to original hxcpp:</p>
<pre><code>haxelib set hxcpp hxcpp 
</code></pre>
<p>When 'Error : Could not process asset libraries'  then do:</p>
<pre><code>openfl rebuild tools
</code></pre>
<p><strong>COLYSEUS</strong><br />
Download ZIP from GitHub : <a href="https://github.com/colyseus/colyseus-hx" rel="nofollow">https://github.com/colyseus/colyseus-hx</a><br />
Extract the archive to c:\HaxeToolkit    so that the project.xml is in c:\HaxeToolkit\colyseus-hx-master</p>
<p>Modify the Main.hx: to mkae sure that the localhost line is active and the  &quot;ws://colyseus-examples.herokuapp.com&quot;); is commented out</p>
<pre><code>          this.client = new Client(&quot;ws://localhost:2567&quot;);
</code></pre>
<p>Build the NyanCat example</p>
<pre><code>c:&gt; cd \HaxeToolkit\colyseus-hx-master\example\NyanCat
C:\HaxeToolkit\colyseus-hx-master\example\NyanCat&gt;lime build project.xml html5
</code></pre>
<p>Error: Could not find haxelib &quot;haxe-ws&quot;, does it need to be installed?</p>
<p>Install haxe-ws      1.0.5</p>
<pre><code>haxelib install haxe-ws 

lime test html5
</code></pre>
<p>It should now produce the nyancat window where you can move around with the cursor keys</p>
<pre><code>C:\HaxeToolkit\colyseus-hx-master\example\NyanCat&gt;lime build project.xml windows

lime test windows 
</code></pre>
<p><strong>LEAVING ROOM Crash:</strong></p>
<p>Now we change the Main.hx to include leaving room</p>
<pre><code>this.client = new Client(&quot;ws://localhost:2567&quot;);
	//this.client = new Client(&quot;ws://colyseus-examples.herokuapp.com&quot;);
this.room = this.client.join(&quot;state_handler&quot;);
var timer = new haxe.Timer(5000); 
timer.run = function() {
	trace(&quot; Leave Room &quot;);
	this.room.leave();
	var timer2=new haxe.Timer(2000);
	timer2.run = function (){
   	   timer2.stop();
	   trace(&quot; Create new room ... &quot; );
	   this.room = this.client.join(&quot;state_handler&quot;);
    };
};
</code></pre>
<p>Build and lime test the windows version</p>
<p>When you see CLIENT: ERROR  you should stop the program and start the program again.</p>
<p>Repeat to use lime test windows</p>
<p>After a while; approximate &lt; 10 minutes; it will crash</p>
]]></description><link>http://discuss.colyseus.io/post/716</link><guid isPermaLink="true">http://discuss.colyseus.io/post/716</guid><dc:creator><![CDATA[mdotedot]]></dc:creator><pubDate>Invalid Date</pubDate></item><item><title><![CDATA[Reply to Stencyl (HaXe) Extension on Invalid Date]]></title><description><![CDATA[<p>After two weeks of further debugging I've now came up with a work around so that it does not crash.</p>
<p>These are the modifications that I needed to make to avoid null pointer crashes:</p>
<p>SocketSys.hx (haxe/net/impl/SocketSys.hx)</p>
<pre><code>					// M.E. the match error.custom(error.blocked) caused null pointer crash
					/*
                    needClose = !(e == 'Blocking' || (Std.is(e, Error) &amp;&amp; (
                        (e:Error).match(Error.Custom(Error.Blocked)) ||
                        (e:Error).match(Error.Blocked))
                    ));
					*/
					if((&quot;&quot;+e).indexOf(&quot;Block&quot;) &lt; 0 &amp;&amp; (&quot;&quot;+e).indexOf(&quot;Custom(EOF)&quot;) &lt; 0){
						trace('closing socket because of $e');
						needClose=true;
					}
				}
</code></pre>
<p>And further down I don't close the socket which caused blocking and crashing things on Android</p>
<pre><code>	if (needClose) {
		//	    close();  // M.E. This will cause Android problems
	}
</code></pre>
<p>Room.hx : avoid null pointer exception</p>
<pre><code>private function patch( binaryPatch: Bytes ) {
        // apply patch
		// M.E. Check for null on binaryPatch
		if(binaryPatch == null || this == null || this._previousState == null){
trace(&quot;BINARY PATCH IS NULL or this._previousState == null !&quot;);
		}else{
			 
			this._previousState = FossilDelta.Apply(this._previousState, binaryPatch);
			// trigger state callbacks
			this.set( MsgPack.decode( this._previousState ) );
			this.onStateChange(this.state);
		}
        
        
    }
</code></pre>
<p>FossilDelta.hx in Apply to avoid null pointer exception</p>
<pre><code>	var total=0;
	// M.E. Check for null on src
	  if(src == null)return haxe.io.Bytes.alloc(0);
	  if(delta == null) return haxe.io.Bytes.alloc(0);
	  // M.E. End of modification
	  
</code></pre>
<p>And I needed to inform Stencyl about errors in Room.onError or the extension would still use room functions ...</p>
<p>Room.hx connect function</p>
<pre><code>	this.connection.onError = function (e) {
			var message=&quot;Possible causes: room's onAuth() failed or maxClients has been reached.&quot;;
			if(getGameAttribute(&quot;ColyseusErrorMessage&quot;) == null)setGameAttribute(&quot;ColyseusErrorMessage&quot;, &quot;&quot;); setGameAttribute(&quot;ColyseusErrorMessage&quot;, &quot;&quot;+getGameAttribute(&quot;ColyseusErrorMessage&quot;)+&quot; &quot;+message); 
            trace(message);
            this.onError(e);
        };
</code></pre>
<p>In the application I created an onError routine and that would be hit sometimes but then it will do a new client instance and it starts creating rooms again.</p>
<p>So we don't close the socket on <a href="http://haxe.net" rel="nofollow">haxe.net</a> level but detect problems in Room and Client on Colyseus level.</p>
<p>Hopefully these changes don't bite me later. I really want to continue working on other methods than Lobby mechanism!</p>
<p>Mac OSX, iOS Simulator, iPhone 5, Windows and Android all work without crashes when creating and leaving rooms now.<br />
I ran a demo-game that left and created rooms every 10 seconds and they kept working for an hour.<br />
Android crashed on one device after an hour. It had done over 100 room creations by that time.<br />
I need to keep that in mind when doing more stuff later on and see if it reoccurs.<br />
(HTML5 never gave problems as it didn't use <a href="http://haxe.net" rel="nofollow">haxe.net</a>)</p>
]]></description><link>http://discuss.colyseus.io/post/753</link><guid isPermaLink="true">http://discuss.colyseus.io/post/753</guid><dc:creator><![CDATA[mdotedot]]></dc:creator><pubDate>Invalid Date</pubDate></item><item><title><![CDATA[Reply to Stencyl (HaXe) Extension on Invalid Date]]></title><description><![CDATA[<p>This week I've made progress on a simple room where players can be joined and walk around.<br />
I made it so that players would be moved simultaneous to see if the server could handle it.</p>
<p>It didn't quite run well with 2 or more browser sessions at the same time. Also a windows publication didn't fare well.</p>
<p>Yesterday I found out that the CPU on Windows and memory on HTML5 where draining. So today I made a simple version on my NyanCat project. I had it running on both html5 and windows and it had the same effect.</p>
<p>Then I stripped colyseus from the nyancat so that only the image was left with controlling keys and there was no problem with CPU.</p>
<p>With Colyseus:<br />
<img src="http://photoquesting.com/Colyseus/HaxeColyseusCPU.png" alt="alt text" class="img-responsive img-markdown" /></p>
<p>And the non-colyseus version:</p>
<p><img src="http://photoquesting.com/Colyseus/HaxeNyanCatNoColyseus.png" alt="alt text" class="img-responsive img-markdown" /></p>
<p>So Haxe client is consuming a lot of CPU !</p>
<p>At least it wasn't my client implementation since both have the same problem. I guess I need multiple computers from now on to do tests ....</p>
]]></description><link>http://discuss.colyseus.io/post/759</link><guid isPermaLink="true">http://discuss.colyseus.io/post/759</guid><dc:creator><![CDATA[mdotedot]]></dc:creator><pubDate>Invalid Date</pubDate></item><item><title><![CDATA[Reply to Stencyl (HaXe) Extension on Invalid Date]]></title><description><![CDATA[<p>Last days I've worked on refactoring code and CPU investigations.</p>
<p>Connection.hx modifications to avoid CPU consumption</p>
<pre><code> #if sys
		while(!this.isClosed){ //M.E. After 200 reconnections the CPU was gone to 92%
			this.ws.process();
				
			 Sys.sleep(0.005); // M.E. Avoid CPU consumption by introducing a really small sleep
        }
 #end
 public function close () {
		this.isClosed=true; //M.E. add for thread checking
        this.ws.close();
 }
		
</code></pre>
<p>Perhaps the this._enqueuedSend mechanism can be altered as well to check for the isClosed state?!?! But I'm not sure what the enqueued mechanism needs this...</p>
<p>Running with over more than 200 client initialization tests (and client.closing them) the CPU consumption kept relatively steady.<br />
Now the Windows executable doesn't take much of the CPU.</p>
<p>Remains Javascript that consumes a lot of memory. But this couldn't easily be reproduced on the HaxeKit version, so it might be something related to other parts of HaXe and Stencyl.</p>
<p>I was able to switch rooms on Android, Windows and HTML5 though. I need to test the other targets with the latest build to make sure I didn't break anything for them.</p>
<p>Current state:</p>
<ul>
<li>Initialize Colyseus (tested 200x re-initializations)</li>
<li>Create Room (Lobby, State_Handler) : Also done together with the 200x initializations</li>
<li>Get room list (getAvailableRooms)</li>
<li>Join Room</li>
<li>Leave Room</li>
<li>Player list</li>
<li>Send Data</li>
<li>Receive Data</li>
</ul>
<p>TODO:</p>
<ul>
<li>Investigate Javascript memory consumption</li>
<li>Publication to all Stencyl targets</li>
<li>Ping / latency mechanism</li>
<li>Broadcast investigations</li>
<li>onAuth investigations</li>
<li>Different Room Types : RawData,TurnBased,LockData,SimplePhysics,Chat</li>
</ul>
]]></description><link>http://discuss.colyseus.io/post/761</link><guid isPermaLink="true">http://discuss.colyseus.io/post/761</guid><dc:creator><![CDATA[mdotedot]]></dc:creator><pubDate>Invalid Date</pubDate></item><item><title><![CDATA[Reply to Stencyl (HaXe) Extension on Invalid Date]]></title><description><![CDATA[<ul>
<li>javascript memory consumption was a Stencyl bug. It has to do with drawing stuff, which I obviously did in my test application. Filed a PR on Stencyl Forum for this.</li>
<li>Publications:<br />
iPhone Simulator<br />
iPhone (Should be fine on iPad as well)<br />
Mac OSX<br />
Linux<br />
Windows<br />
Android (Tablet+Phone)<br />
HTML5</li>
</ul>
<p>So all is fine to continue working on the RoomTypes.</p>
]]></description><link>http://discuss.colyseus.io/post/762</link><guid isPermaLink="true">http://discuss.colyseus.io/post/762</guid><dc:creator><![CDATA[mdotedot]]></dc:creator><pubDate>Invalid Date</pubDate></item><item><title><![CDATA[Reply to Stencyl (HaXe) Extension on Invalid Date]]></title><description><![CDATA[<p>Hello! do you use haxe only for client code or you have created externs for server as well?</p>
]]></description><link>http://discuss.colyseus.io/post/772</link><guid isPermaLink="true">http://discuss.colyseus.io/post/772</guid><dc:creator><![CDATA[serjek]]></dc:creator><pubDate>Invalid Date</pubDate></item><item><title><![CDATA[Reply to Stencyl (HaXe) Extension on Invalid Date]]></title><description><![CDATA[<p>Hello Serjek,</p>
<p>Currently I'm working on Stencyl Extension which uses (modified) HaXe Colyseus Client code.<br />
The server is still running on TypeScript. A HaXe server would be awesome to have but I currently have my hands full with Client Code !</p>
<p>Kind regards from<br />
M.E.</p>
]]></description><link>http://discuss.colyseus.io/post/780</link><guid isPermaLink="true">http://discuss.colyseus.io/post/780</guid><dc:creator><![CDATA[mdotedot]]></dc:creator><pubDate>Invalid Date</pubDate></item><item><title><![CDATA[Reply to Stencyl (HaXe) Extension on Invalid Date]]></title><description><![CDATA[<p>This weekend I made:</p>
<ul>
<li>PingTime</li>
<li>PlayerID from SessionID block</li>
<li>Player in Seat : This has to be changed to server-side, since it now apparently goes wrong sometimes (see pictures)</li>
</ul>
<p>Made a milestone today: LockRoomType</p>
<p>This is one of the main goals of the Stencyl Extension.<br />
I have wanted a lock-mechanism behavior for a long time.<br />
The idea is that you have a grid-based game where the players 'lock' the part of the grid that will be changed.<br />
When a lock is granted the player can alter the grid (move/push/pull/alter state).<br />
Once data has been modified an unlock is send.</p>
<p>What I have is still flawed by leaving/killing or anyother type of disconnection.<br />
When there is a lockstate it will not be unlocked.<br />
That will be altered by a time-exceeded-system so that the server will unlock the set of grid positions<br />
that the player/client had locked.<br />
I probably need to use a 'previous' data mechanism as well so that data can be reversed when it only partially has been changed.</p>
<p>Made a prototype so that moves are done automatically.</p>
<p>Current Progress:</p>
<p><img src="http://photoquesting.com/Colyseus/Colyseus_v70.gif" alt="alt text" class="img-responsive img-markdown" /></p>
<p>Hmm... will need to double check system because running for over an hour it created another block :(</p>
<p><img src="http://photoquesting.com/Colyseus/Colyseus_v70bug.png" alt="alt text" class="img-responsive img-markdown" /></p>
<p>At least the player positions (the colorblocks) are in sync!</p>
]]></description><link>http://discuss.colyseus.io/post/781</link><guid isPermaLink="true">http://discuss.colyseus.io/post/781</guid><dc:creator><![CDATA[mdotedot]]></dc:creator><pubDate>Invalid Date</pubDate></item><item><title><![CDATA[Reply to Stencyl (HaXe) Extension on Invalid Date]]></title><description><![CDATA[<p>This week I've worked on :</p>
<ul>
<li>Player in Seat - ServerSide</li>
<li>TurnBased RoomType: NextTurn, isTurn</li>
<li>MasterPlayerID for Client Side logic Room Type</li>
<li>Lock Mechanism</li>
</ul>
<p>The lock mechanism was flawed by not release locks and to not compare clientside grid with serverside grid.</p>
<p>CLIENT<br />
For example when the client pushes a block from position 25 to 15 it will need to send 15=0,25=2,35=1000 to the server and request a lock on them:</p>
<pre><code>grid[15]=0; 	// free space
grid[25]=2; 	// block
grid[35]=1000; 	// playernr
</code></pre>
<p>SERVER<br />
Server receives the lockrequest (15=0,25=2,35=1000)<br />
It checks his own grid if the positions match the client request lock. If the grids are out of sync it will send an error back.<br />
The client will then request a complete grid from the server as it is apparently behind.</p>
<p>If the server grid position matches the requested lock positions a lock will be attempted: (pseudo-code)</p>
<pre><code>attemptposition=new Array();
isOK=true;
for each lockposition{
	if(isOK &amp;&amp; gridlock[lockposition] == 0){
		gridlock[lockposition]=time; 
		attemptposition.push(lockposition)
	}else{
		isOK=false;
		// there is a lock on one of the 
		for(each attemptpositon p) gridlock[p]=0;
	}
}
</code></pre>
<p>When the server was able to lock all gridpositions it will send a success to the client</p>
<p>CLIENT<br />
The client will do a grid request if the return state was an error.<br />
The client will send the changed data to the server when it was success, otherwise it will not do the move as there was/is a lock.</p>
<p>SERVER<br />
When server receives the griddata it will set the new grid values and afterwards set the lockpositions to 0-time.</p>
<p>After each request the server checks the gridlock table if the currenttime - locktime &gt; 2 seconds .. when it finds one it will reset the lock.</p>
<p>CLIENT<br />
Sends unlock to server.</p>
<hr />
<p>A room with four player-bots ran for over 4 hours and still they were in sync.</p>
<hr />
<p>Next I will need to figure out how to do classes with overloading / inheritence in TypeScript.<br />
I want all the room types to share code that are common in all rooms.</p>
<p>For instance I need PlayerInSeat, PingTime, getPlayersInRoom etc.. code in all typescript rooms.</p>
]]></description><link>http://discuss.colyseus.io/post/791</link><guid isPermaLink="true">http://discuss.colyseus.io/post/791</guid><dc:creator><![CDATA[mdotedot]]></dc:creator><pubDate>Invalid Date</pubDate></item><item><title><![CDATA[Reply to Stencyl (HaXe) Extension on Invalid Date]]></title><description><![CDATA[<p>Subject:    Colyseus HaXe Externs &amp; Colyseus version 0.10</p>
<p>Took a break from the Colyseus Extension, but I'm back.<br />
I was asked to create a MicroPhone HaXe extension for iOS and Android so that did take some time.</p>
<p>Also, I wanted to wait a bit till the version 0.10 was done on both of the client and server side.</p>
<p>Thanks to Serjek and Endel for their contributions, I was able to get a HaXe combination running with the Nyan Cat example.</p>
<p>Server Side: Oracle Linux</p>
<ul>
<li>Download : <a href="https://github.com/serjek/colyseus-hxjs" rel="nofollow">https://github.com/serjek/colyseus-hxjs</a></li>
<li>Download : <a href="https://github.com/serjek/colyseus-hxjs-examples" rel="nofollow">https://github.com/serjek/colyseus-hxjs-examples</a></li>
<li>extract in /root/serjek directory</li>
<li>Install npm  : curl -sL <a href="https://rpm.nodesource.com/setup_6.x" rel="nofollow">https://rpm.nodesource.com/setup_6.x</a> | sudo -E bash -</li>
<li>yum install -y nodejs`</li>
<li>npm -version<br />
6.5.0-next.0<br />
HaXe</li>
<li>Download install-haxe.hs :  <a href="https://gist.github.com/jgranick/8cc40e2e0f277146725f" rel="nofollow">https://gist.github.com/jgranick/8cc40e2e0f277146725f</a></li>
<li>sh <a href="http://install-haxe.sh" rel="nofollow">install-haxe.sh</a></li>
<li>export LD_LIBRARY_PATH=/root/haxe/neko</li>
<li>haxelib setup<br />
/usr/lib/haxe/lib</li>
<li>cd /root/serjek/colyseus-hxjs-examples-master/</li>
<li>npm i lix -g</li>
<li>lix download</li>
<li>Upgraded haxe to 4.0.0 preview 4 from : <a href="https://haxe.org/download/file/4.0.0-preview.4/haxe-4.0.0-preview.4-linux64.tar.gz/" rel="nofollow">https://haxe.org/download/file/4.0.0-preview.4/haxe-4.0.0-preview.4-linux64.tar.gz/</a></li>
<li>Updated the <a href="http://install-haxe.sh" rel="nofollow">install-haxe.sh</a> to reflect that .tar.gz</li>
<li>ran <a href="http://install-haxe.sh" rel="nofollow">install-haxe.sh</a> again</li>
<li>haxe -version<br />
4.0.0-preview.4+1e3e5e0</li>
<li>lix use haxe 4.0.0-rc.2</li>
<li>Make sure that you are in the serjek/colyseus-hxjs-examples-master directory</li>
<li>haxe server.hxml</li>
<li>cd bin/server</li>
<li>npm i yarn -g</li>
<li>yarn</li>
<li>node index.js<br />
src/MainServer.hx:39: -- listening on 0.0.0.0:2567... --</li>
</ul>
<p>New Session</p>
<ul>
<li>export LD_LIBRARY_PATH=/root/haxe/neko</li>
<li>/usr/local/bin/haxe</li>
<li>lix use haxe 4.0.0-rc.2</li>
<li>haxe -version<br />
4.0.0-preview.4+1e3e5e0</li>
<li>cd /root/serjek/colyseus-hxjs-examples-master</li>
<li>haxe client.hxml</li>
<li>cd bin/client</li>
<li>yarn</li>
<li>node index.js</li>
</ul>
<p>Test will run.</p>
<p>Now for the HaXe Client on Windows: <a href="https://github.com/colyseus/colyseus-hx" rel="nofollow">https://github.com/colyseus/colyseus-hx</a></p>
<ul>
<li><a href="https://github.com/HaxeFoundation/haxe/releases/download/3.4.4/haxe-3.4.4-win64.exe" rel="nofollow">https://github.com/HaxeFoundation/haxe/releases/download/3.4.4/haxe-3.4.4-win64.exe</a></li>
<li>set HAXE_PATH=c:\HaxeToolkit\haxe</li>
<li>set NEKOPATH=c:\HaxeToolkit\neko</li>
<li>set PATH=%HAXE_PATH%;%NEKOPATH%;%PATH%</li>
<li>haxelib setup c:\HaxeToolkit\haxe\lib</li>
<li>haxelib --global update haxelib<br />
Current version is 3.3.0</li>
<li>haxelib install openfl<br />
8.9.0</li>
<li>haxelib run openfl setup<br />
7.3.0</li>
<li>haxelib run lime setup<br />
Up to Date</li>
<li>lime create HelloWorld</li>
<li>cd HelloWorld</li>
<li>lime test html5</li>
<li>extract the colyseus hx master  to \haxetoolkit\colyseus-hx-master</li>
<li>cd \HaxeToolkit\colyseus-hx-master\example\openfl\Source</li>
<li>notepad Main.hx<br />
Edit: the ws connection so that it points to the Linux Server mentioned above.</li>
<li>cd  \HaxeToolkit\colyseus-hx-master\example\openfl</li>
<li>haxelib install haxe-ws</li>
<li>haxelib set hxcpp 3.2.94<br />
(installing)</li>
<li>lime build project.xml html5<br />
Error:</li>
</ul>
<pre><code>Source/Main.hx:55: characters 48-50 : Array&lt;Unknown&lt;0&gt;&gt; should be Null&lt;Map&lt;Strin
g, Dynamic&gt;&gt;
Source/Main.hx:55: characters 48-50 : Array&lt;Unknown&lt;0&gt;&gt; should be Map&lt;String, Dy
namic&gt;
Source/Main.hx:55: characters 48-50 : For optional function argument 'options'
</code></pre>
<p>Edit : c:\HaxeToolkit\colyseus-hx-master\src\io\colyseus\Client.hx</p>
<pre><code>			// M.E. @:generic    public function join&lt;T&gt;(roomName: String, ?options: Map&lt;String, Dynamic&gt;, ?cls: Class&lt;T&gt;): Room&lt;T&gt; {
        //this.room = this.client.join(&quot;state_handler&quot;, [], State);
		this.room = this.client.join(&quot;state_handler&quot;, new Map&lt;String,Dynamic&gt;(), State);
</code></pre>
<p>Now the lime build project.xml html5 followed by lime test html5 work with the externs by Serjek.</p>
<p>That leaves me the task of creating a new Stencyl Extension that utilizes the<br />
<code>this.room.state.players.onAdd = function(player, key)</code><br />
methodology rather than the<br />
<code>this.room.listen(&quot;players/:id&quot;, function(change) {</code><br />
methodology.</p>
]]></description><link>http://discuss.colyseus.io/post/843</link><guid isPermaLink="true">http://discuss.colyseus.io/post/843</guid><dc:creator><![CDATA[mdotedot]]></dc:creator><pubDate>Invalid Date</pubDate></item><item><title><![CDATA[Reply to Stencyl (HaXe) Extension on Invalid Date]]></title><description><![CDATA[<p>Haxe Client and Server on v0.10</p>
<p>Using the externs by Serjek I was able to create a very Simple Colyseus Server with a StateHandler Room that handles string data. The data is send to the clients and everything works as it supposed to.</p>
<p><strong>But only for HTML5 !!!</strong></p>
<p>I again have lots of problems to get it to work on anything else than HTML5.</p>
<p>Here are the (non-stencyl) HaxeToolkit steps that I made:</p>
<pre><code>set HAXE_PATH=c:\HaxeToolkit\haxe
set NEKOPATH=c:\HaxeToolkit\neko
set PATH=%HAXE_PATH%;%NEKOPATH%;%PATH%
haxelib setup c:\HaxeToolkit\haxe\lib
haxelib --global update haxelib
</code></pre>
<p>haxelib is up to date<br />
<code>haxelib install openfl</code><br />
8.9.1<br />
<code>haxelib run openfl setup</code><br />
7.5.0<br />
<code>haxelib run lime setup</code><br />
Up to Date</p>
<p>Get GIT from :<br />
<a href="https://git-scm.com/download/win" rel="nofollow">https://git-scm.com/download/win</a></p>
<pre><code>git clone https://github.com/colyseus/colyseus-hx.git
cd \HaxeToolkit\colyseus-hx\example\openfl\Source
notepad Main.hx
</code></pre>
<p>Edit: the ws connection so that it points to the docker server<br />
Also Edit the this.client.join line on number 55:</p>
<pre><code class="language-//">        //this.room = this.client.join(&quot;state_handler&quot;, [], State);
		this.room = this.client.join(&quot;state_handler&quot;, new Map&lt;String,Dynamic&gt;(), State);
</code></pre>
<p>Build the project:</p>
<pre><code>cd \HaxeToolkit\colyseus-hx\example\openfl
haxelib install haxe-ws
haxelib set hxcpp 3.2.94
</code></pre>
<p>(installing)</p>
<pre><code>lime build project.xml html5
lime test html5
</code></pre>
<p>It works like a charm with the Serjek externs in the Colyseus Docker .</p>
<p>But Android and Windows give again connection problems:</p>
<pre><code>cd \HaxeToolkit\colyseus-hx\example\openfl
haxelib set hxcpp 4.0.8
lime build windows

lime test windows
</code></pre>
<p>The connection is attempted but not made:</p>
<pre><code> - src/lime/utils/AssetCache.cpp  [haxe,release]
Link: ApplicationMain.exe
   Creating library ApplicationMain.lib and object ApplicationMain.exp
Main.hx:48: CLIENT CLOSE
Connection.hx:66: WebSocket connection has been closed, stopping the thread!
Main.hx:29: ERROR! timeout
</code></pre>
<p>(I've tried the alterations on the haxe-ws library that I made for the 0.9 but they didn't solved it now)</p>
<p>I am very curious if anyone got a different target to run with haxe other than HTML5 ??!??</p>
]]></description><link>http://discuss.colyseus.io/post/847</link><guid isPermaLink="true">http://discuss.colyseus.io/post/847</guid><dc:creator><![CDATA[mdotedot]]></dc:creator><pubDate>Invalid Date</pubDate></item><item><title><![CDATA[Reply to Stencyl (HaXe) Extension on Invalid Date]]></title><description><![CDATA[<p>Hi <a class="plugin-mentions-user plugin-mentions-a" href="http://discuss.colyseus.io/uid/282">@mdotedot</a>, have you tried the <code>haxe-ws</code> fork here? <a href="https://github.com/colyseus/haxe-ws" rel="nofollow">https://github.com/colyseus/haxe-ws</a></p>
<p>You can install it via:</p>
<pre><code>haxelib git haxe-ws https://github.com/colyseus/haxe-ws.git
</code></pre>
<p>I've fixed the WS handshake on sys targets on this fork. Let me know if the CPP target works for you using it. Cheers!</p>
]]></description><link>http://discuss.colyseus.io/post/848</link><guid isPermaLink="true">http://discuss.colyseus.io/post/848</guid><dc:creator><![CDATA[endel]]></dc:creator><pubDate>Invalid Date</pubDate></item><item><title><![CDATA[Reply to Stencyl (HaXe) Extension on Invalid Date]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="http://discuss.colyseus.io/uid/1">@endel</a> said in <a href="/post/848">Stencyl (HaXe) Extension</a>:</p>
<blockquote>
<p><a href="https://github.com/colyseus/haxe-ws" rel="nofollow">https://github.com/colyseus/haxe-ws</a></p>
</blockquote>
<p><strong>Endel you are a true Master!</strong></p>
<pre><code>C:\HaxeToolkit\haxe\lib&gt;haxelib git haxe-ws https://github.com/colyseus/haxe-ws.git
Installing haxe-ws from https://github.com/colyseus/haxe-ws.git
Library haxe-ws current version is now git

C:\HaxeToolkit\haxe\lib&gt;haxelib list
actuate: [1.8.9]
box2d: [1.2.3]
haxe-ws: [git]
haxelib: [3.3.0]
hxcpp: 3.2.94 [4.0.8]
layout: [1.2.1]
lime-samples: [7.0.0]
lime: 7.2.1 [7.5.0]
openfl-samples: [8.7.0]
openfl: 8.8.0 [8.9.1]
</code></pre>
<p>Now to build / test it again:</p>
<pre><code>cd \HaxeToolkit\colyseus-hx\example\openfl
lime build windows
lime test windows
</code></pre>
<p>Error:</p>
<pre><code>Can't find a secure source of random bytes. Reason: [file_open,\Device\KsecDD]
</code></pre>
<p>Debugging leads me to this part</p>
<pre><code>trace(&quot;WebSocketGeneric.hx . initialize ... Before this.key 		&quot;);
        //this.key = Base64.encode(Crypto.getSecureRandomBytes(16)); // This generates the secure source of random bytes
		this.key = Base64.encode(haxe.io.Bytes.ofString(&quot;ABCDEFGHIJKLMNOP&quot;));
trace(&quot;initialize key : &quot;+this.key);
</code></pre>
<p>After this ofString-&quot;16-bytes&quot; the error was gone and hand-shake was made!!!</p>
<p>Windows and Android publication worked out of the box.</p>
<p>I will test iOS/Mac later this week!</p>
]]></description><link>http://discuss.colyseus.io/post/849</link><guid isPermaLink="true">http://discuss.colyseus.io/post/849</guid><dc:creator><![CDATA[mdotedot]]></dc:creator><pubDate>Invalid Date</pubDate></item></channel></rss>