Jump to content


Photo
* * * * * 13 votes

Networking With C# And Gml


  • Please log in to reply
173 replies to this topic

#1 FatalSleep

FatalSleep

    FatalSheep?

  • GMC Member
  • 3974 posts
  • Version:GM:Studio

Posted 13 May 2014 - 08:18 AM

  • Title: Sharp Server
  • Description: Server application base programmed in C# to mimic GameMaker: Studio's Networking functionality.
  • Other Languages: C#
  • Source Type: Repository
  • GitHub: Repository
  • Tags: TUTORIAL, CSHARP, C#, GML, GMS, NETWORKING.

Examples

This section is for examples made by the community for the community for helping get started with the SharpServer framework. Please do not claim any of the following works as your own.

 

Update v3.0

Jumping to update 3.0--major changes. After looking over the source code a few times a while back I realized this could be a lot better. There's quite a bit in the old server that I just found to be horrible in terms of both implementation as well as application: pre-defined code that you have to fill in, function consistency--especially with buffer functions--etc. Jumping forward over a full year I think I waited way too long to do this re-write and it's taken too long for me to do it right, unless of course I come back to it next year and find it just as revolting as old version below. Ignore my rant and let's get onto major changes...

 

All examples I add--or if someone wishes to contribute--will be added to the GitHub repository as well as this post. So far, no examples yet!

 

Changes:

  • Re-write! I've redone everything to make the process of programming using my system a lot more bearable.
    However! The actual system itself has not changed fundamentally, it's simply been refined.
  • New buffer system! I re-did the entire buffer system, using function overloading and primitive type checking to
    remove the functions with their type in the name of the function, e.g. Writeu8, ReadStr, etc.
  • Events! Previously you had to fill in pre-defined functions to get the server to work--no more. The server automatically
    calls these events when necessary, all you have to do is subscribe your own methods to these events to do what you want.
  • New socket handling method. Now to make sure sockets are correctly handled, I've added the SocketBinder and SocketContainer
    classes. The SocketBinder manages--binds and unbinds--socket IDs for all sockets created for your server. This lets you find all
    sockets that pertain to any specific SocketBinder.
  • PacketStream and DatagramStream. Previously you'd use SendTcp() or SendUdp() within a buffer instance to send a packet. Now
    PacketStream for sending via TCP and DataGramStream for sending via UDP. Both now provide SYNC and ASYNC send calls.
  • IPServicer. You can now call the IPServicer to use supported web APIs to obtain your public IP address for whatever reason.
    Honestly though, not entirely needed since you don't need your public IP address to startup a server. Pretty cool nonetheless.
    The APIs currently supported are: IPify, IPInfo, IPAPI and Check IP DynDNS. WhatsMyIP was recommended by Google, but I didn't
    include it since it requires account registration.
  • IP Automation. When you create a TCP server--UDP servers don't require an IP on creating a UDP server--you can now now long have
    to specify an IP address (it's optional). If you don't provide an IP address the server will default to listening on ALL IP addresses available
    to your machine. Naturally though, to connect a client globally you'll still need to connect via your public IP address.
  • Better documentation. The function documentation now provides you with better descriptions as well as any possible exceptions that could
    be thrown by a method.
  • No more hidden exception handling--IPServicer doesn't count, it's supposed to do that for the timeout. Previously I stealthily managed all
    exceptions without prompting you for any errors that occurred, which is pretty bad. This no longer happens. Your errors, your problem.
  • Removed PakcetHeader. The TCP and UDP ServerHandler classes do not include a PacketHeader now--it's unnecessary, You should be
    managing this, not me.
  • I have now included a method for restarting your server.
  • Better alignment. Alignment is more efficient and correct using Mike Daily's fast alignment algorithm: "index + ( alignment - 1 ) & ~( alignment -1 );"
    Of course though, I've done some pre-computing so that the (alignment - 1) and ~(alignment - 1) math happens before any of the alignment happens.

On another note I did change a lot of the naming conventions, so you'll need to get used to that, but that shouldn't be an issue. Here is a major list
of name changes:

  • CSServerGMS -> SharpServer (Namespace name).
  • TcpListenerSocket -> TcpServerHandler.
  • TcpClientSocket -> TcpClientHandler.
  • UdpServerSocket -> UdpServerHandler.
  • ByteBuffer -> BufferStream.
  • ByteBuffer.Send(Udp/TCP) -> SendAsync()/SendSync() -> PacketStream.* for TCP and DatagramStream.* for UDP.
  • SocketSystem -> SocketBinder.
  • Added SocketContainer for actual sockets. The *Handler classes derive from this class.
  • Removed TcpPackets and UdpPackets.

I won't be writing a new tutorial like for the old post. If you need a re-fresher read the old post and then get aligned with all the changes. Rekt, I um, accidentally deleted the old post when editing this, whoops. However I will be outlining all the major changes below to avoid frustration.

 

API Changes:

  • Sockets used to be bound using SocketSystem by calling static methods-- no longer. Now you'll need to create an instance of SocketBinder.
    Then pass SocketBinder to your TCP and/or UDP server. Example: (server creation with SocketBinder further down)
    SocketBinder binder = new SocketBinder();
  • Previously you'd create an instance of TcpListenerSocket and that would auto-start your server. Instead you'll call *.Start() manually when
    you create a server via TcpServerHandler. Example:
    /*
        This creates a TCP server with:
        PORT of 64000
        MAX CONNECTIONS of uncapped(<= 0 is uncapped)
        ALIGNMENT of 4
        TIMEOUT of 5,000ms(5sec)
            This is the number of milliseconds before the client checks it's connection
            to see if it's still connected or if it disconnected.
        IPADDRESS of ANY
    */
    in port = 64000, maxConnections = 0, alignment = 4, timeout = 5000;
    TcpServerHandler serverTCP = new TcpServerHandler( binder, port, maxConnections, alignment, timeout, null );
    serverTCP.Start();
  • For UDP you'll do the same as the TCP ServerHandler. You'll create an instance and manually start the server yourself. Example:
    /*
        This creates a UDP server with:
        PORT of 64000
        ALIGNMENT of 4
    */
    in port = 64000, alignment = 4;
    UdpServerHandler serverUDP = new UdpServerHandler( binder, port, alignment );
    serverUDP.Start();
  • Creating buffers is pretty much the same, just a name change. Example:
    /*
        This creates a buffer with:
        LENGTH of 1024 bytes.
        ALIGNMENT of 4 bytes.
    */
    int length = 1024, alignment = 4;
    BufferStream buffer = new BufferStream( length, alignment );
  • Then you can read / write from the buffer via Write() and Read() overloaded methods. Example:
    /*
        C#'s equivalent of GMS's buffer types:
        bool = boolean
        byte = u8
        sbyte = s8
        ushort = u16
        short = s16
        uint = u32
        int = s32
        float = f32
        double = f64
        string = string
        byte[] has no equivalent. Instead read out the number of bytes individually.
    */
    
    /*
        This will write the specified value casted to a byte to the BufferStream.
        Supported Types: bool, byte, sbyte, ushort, short, uint, int, float, double, string, byte[]
    */
    buffer.Write( (byte) 127 );
    
    /*
        This will read the specified type from the buffer and store it in the indicated variable.
        Supported Types: bool, byte, sbyte, ushort, short, uint, int, float, double, string, byte[]    
    
        The OUT modifier basically says: Take the reference to the passed variable and give it to the function.
        This lets the function give the variable the specified value by passing the value to the variable via it's reference.
    */
    byte data;
    buffer.Read( out data ):
  • You used to have to fill in the UdpPackets and TcpPackets class, no more. Now subscribe your own methods to your server and voila. Example:
    /*
        NOTE: Events are OPTIONAL. You can choose to use all none, or only a few events if you want.
        Whatever events you don't use will either not be called by the server or the server will call
        a default handler instead. ClientCreatedEvent is the only event with a default handler so far.
    
        This will apply your methods to each TCP server event.
        NOTE: The method names can be whatever you want.
        If you're curious--yes the += does mean you can subscribe multiple methods to one event.
    */
    
    // This event is called AFTER the server starts and BEFORE the server begins accepting client connections.
    server.StartedEvent += StartedEventMethod;
    
    // This event is called to create a new client and MUST always return a new non-null client.
    server.ClientCreatedEvent += ClientCreatedEventMethod;
    
    // This event is called BEFORE the server finally closes.
    server.ClosedEvent += ClosedEventMethod;
    
    // This event is called AFTER the client is accepted and BEFORE the client starts receiving packets.
    server.ConnectedEvent += ConnectionEventMethod;
    
    // This event is called BEFORE the client finally is disconnected.
    server.DisconnectedEvent += DisconnectedEventMethod.
    
    // This event is called AFTER a packet is received by a client, so the packet can be processed.
    server.ReceivedEvent += ReceivedEventMethod;
    
    // This event is called AFTER a client timesout on the server and BEFORE the client's connection status is re-checked.
    // Generally you'd use this event to send a verification packet to the client to check the state of the client's connection.
    server.AttemptReconnectEvent += AttemptReconnectEventMethod;
    
    public void StartedEventMethod( TcpServerHandler server ) { ... }
    public void ClosedEventMethod( TcpServerHandler server ) { ... }
    public TcpClientHandler ClientCreatedEventMethod( SocketBinder binder, TcpServerHandler server, uint ClientTimeout timeout ) { ... }
    public void ConnectedEventMethod( TcpClientHandler client ) { ... }
    public void AttemptReconnectEventMethod( TcpClientHandler client ) { ... }
    public void ReceivedEventMethod( TcpClientHandler client, BufferStream readBuffer ) { ... }
    public void DisconnectedEventMethod( TcpClientHandler client ) { ... }
    /*
        This will apply your methods to each UDP server event.
        NOTE: The method names can be whatever you want.
        If you're curious--yes the += does mean you can subscribe multiple methods to one event.
    */
    // This event is called AFTER the server starts and before the server starts receiving packets.
    server.StartedEvent += StartedEventMethod;
    
    // This event is called BEFORE the server finally closes.
    server.ClosedEvent += ClosedEventMethod;
    
    // This event is called AFTER a packet is received, so the packet can be processed.
    server.ReceivedEvent += ReceivedEventMethod;
    
    public void StartedEventMethod( UdpServerHandler server ) { ... }
    public void ClosedEventMethod( UdpServerHandler server ) { ... }
    public void ReceivedEventMethod( UdpServerHandler server, BufferStream readBuffer, IPEndPoint endPoint ) { ... }

The cool part here is that you can write your entire server in a single CS file since you're no longer restricted by pre-defined fill in files.
I went and wrote a small sample to show you how its done. This simply accepts a client connection and displays the client's packet output
to the console when the server receives a packet from the client.

using System;
using SharpServer.Buffers;
using SharpServer.Sockets;
 
namespace SharpServer {
    class Source {
        public static void Main() {
            SocketBinder binder = new SocketBinder();
            TcpServerHandler server = new TcpServerHandler( binder, 64000, 0, 4 );
            server.StartedDelegate += server_StartedEvent;
            server.ClosedDelegate += server_ClosedEvent;
            server.ConnectedDelegate += server_ConnectedEvent;
            server.ReceivedDelegate += server_ReceivedEvent;
            server.DisconnectedDelegate += server_DisconnectedEvent;
            server.Start();
 
            while( server.Status ) {
                System.Threading.Thread.Sleep( 1 );
            }
 
            System.Threading.Thread.Sleep( 1000 );
        }
 
        public static void server_ClosedEvent(TcpServerHandler host) {
            Console.WriteLine( "CLosed Server..." );
        }
 
        public static void server_StartedEvent(TcpServerHandler host) {
            Console.WriteLine( "Started Server..." );
        }
 
        public static void server_ConnectedEvent(TcpServerHandler host,TcpClientHandler guest) {
            Console.WriteLine( "Client Connected: " + guest.Socket.ToString() );
        }
 
        public static void server_ReceivedEvent(TcpServerHandler host,TcpClientHandler guest,BufferStream readBuffer) {
            Console.WriteLine( "Client Sent Packet: " + guest.Socket.ToString() );
 
            for( int i = 0; i < readBuffer.Length; i ++ ) {
                Console.WriteLine( readBuffer.Memory[ i ].ToString() );
            }
        }
 
        public static void server_DisconnectedEvent(TcpServerHandler host,TcpClientHandler guest) {
            Console.WriteLine( "Client Connected: " + guest.Socket.ToString() );
        }
    }
}

As a side note, the project on GitHub is setup to be built as a class library, e.g. DLL. You can use class libraries in C# like you

can use DLLs in GameMaker. When you open the project, hit F7 to build the project. Check the output window for the file path

to the output DLL file.

 

Then go ahead to your new server's project, go to the menu Project -> Add Reference. In the Reference Manager go to Browse

and then hit the Browse button. Find the DLL and click OK, then OK in the Reference Manager. Voila, you have added the SharpServer

source code as a DLL to your project. You can now reference the SharpServer namespace to access the server API.

 

This is a small alternative to importing the actual source code into your project.

 

On another note, I find it funny that this is easier to create a server with than in GameMaker: Studio!


Edited by FatalSleep, 16 December 2015 - 01:16 AM.

  • 27

#2 chance

chance

    GMC Member

  • Global Moderators
  • 8762 posts
  • Version:GM:Studio

Posted 13 May 2014 - 10:24 AM

Honestly, I have no idea how much clarity the information above will have for strictly GML programmers or GML programmers of medium/low caliber. 

 

Nor do I.  But one way to find out is to post this and see what discussion evolves.  So let's see.

 

Normally, we might not allow tutorials that contain significant non-GM portions.  But I feel this deserves an exception since it supports (and relies upon) a specific GM application.   I believe there are many members who want to set up their own servers to support their GM games, but need help doing so.  Perhaps your example can help them.


  • 3

#3 FatalSleep

FatalSleep

    FatalSheep?

  • GMC Member
  • 3974 posts
  • Version:GM:Studio

Posted 13 May 2014 - 10:29 AM

 

Honestly, I have no idea how much clarity the information above will have for strictly GML programmers or GML programmers of medium/low caliber. 

 

Nor do I.  But one way to find out is to post this and see what discussion evolves.  So let's see.

 

Normally, we might not allow tutorials that contain significant non-GM portions.  But I feel this deserves an exception since it supports (and relies upon) a specific GM application.  I believe there are many members who want to set up their own servers to support their GM games, but need help doing so.  Perhaps your example can help them.

 

Awesome, thank you! I've done my very best to make this as easy to use as possible by pre-setting up everything that no one wants to mess with as well as perfectly matching GameMaker Studio's buffer system. It was quite difficult, but I am pretty sure I got everything right. :)

 

If for some reason that my explanations did not help, I will clarify anything that was vaguely explained as well as answer any questions you guys might have.


  • 0

#4 syntaxibles

syntaxibles

    Vault Dweller

  • GMC Member
  • 974 posts
  • Version:GM:Studio

Posted 13 May 2014 - 11:57 AM

I'll definitely have a play around with this! Networking in proper programming languages always seems so scary and it looks like you've done a good job of making it easier for people like me to understand.

Thanks!


  • 1

+rep me if you dig my stuff :-)

 


#5 gnysek

gnysek

    GMC Member

  • GMC Member
  • 613 posts
  • Version:GM:Studio

Posted 13 May 2014 - 12:34 PM

Github maybe?


  • 1

Previously game developer at YoYoGames, Currently PHP developer in DB-Team
Programming and working with: GML/C#/PHP/JS/MySql/CSS/HTML

Follow 
@GameMakerUpdate to get info about latest versions of GM when they are released: https://twitter.com/GameMakerUpdate or visit website.

(it's managed by bot, not by human, remember)


#6 FatalSleep

FatalSleep

    FatalSheep?

  • GMC Member
  • 3974 posts
  • Version:GM:Studio

Posted 13 May 2014 - 07:27 PM

@Syntaxibles I hope you can make something of it. Networking outside of GM can be pretty scary, it's quite intimidating. So hopefully

my project here will remove that intimidation and bring forth some good results.

 

@Gnysek I could post it on Github, I actually originally planned to do it. Then forgot!

EDIT: Update with GitHub link added to the original post.


Edited by FatalSleep, 13 May 2014 - 09:35 PM.

  • 0

#7 Debels

Debels

    GMC Member

  • GMC Member
  • 3029 posts
  • Version:GM:Studio

Posted 13 May 2014 - 09:52 PM

What a nice add, I was about to start learning how to make a server with C#, I already know basics on it, so it should be quite easy to start :)


  • 1

"Give a man a fish, and you feed him for a day; show him how to catch fish, and you feed him for a lifetime."

(Chinese axiom)


#8 FatalSleep

FatalSleep

    FatalSheep?

  • GMC Member
  • 3974 posts
  • Version:GM:Studio

Posted 13 May 2014 - 11:00 PM

What a nice add, I was about to start learning how to make a server with C#, I already know basics on it, so it should be quite easy to start :)

Perfect. :) Trust me though, you honestly do not want to do this from scratch. Good programming xp, but terrifyingly annoying to program!

There were so many annoying and daunting tasks to fix: dynamic buffer system to match GMS, identifying/verifying merged TCP packets,

byte alignment and learning about wtf a null-terminated string was(lol...). Yeah I've been working on this for a few months off and on, but I

only learned a week ago about the beauty of null-terminated strings.


  • 0

#9 FatalSleep

FatalSleep

    FatalSheep?

  • GMC Member
  • 3974 posts
  • Version:GM:Studio

Posted 15 May 2014 - 01:57 AM

To those that tried to use the Host-A links, my apologies, for now please use the GitHub repository until Host-A is back online.


  • 0

#10 Debels

Debels

    GMC Member

  • GMC Member
  • 3029 posts
  • Version:GM:Studio

Posted 15 May 2014 - 02:58 AM

Having 1 thread per client looks like an overkill and probably is an overkill if your going to host many players at the same time.


  • 0

"Give a man a fish, and you feed him for a day; show him how to catch fish, and you feed him for a lifetime."

(Chinese axiom)


#11 FatalSleep

FatalSleep

    FatalSheep?

  • GMC Member
  • 3974 posts
  • Version:GM:Studio

Posted 15 May 2014 - 04:20 AM

Possible, but Threads are far faster than using for loops to process clients. Besides, it was either threads or classes.

Take your pick. :P

 

Or do you know of a better way? :D I'm open to ideas!


  • 0

#12 rm2kdev

rm2kdev

    GMC Member

  • GMC Member
  • 54 posts
  • Version:GM:Studio

Posted 15 May 2014 - 04:34 AM

Using 1 thread per client bottlenecks your CPU like crazy in a real... full sized game you'd be lucky to get 30 players connected on a single core VPS (which realistically is what most  beginner users would buy in their dream efforts to make their first mmo's :P)

 

A better approach would be asynchronous events with pooled threads this way you'd be specifying 4 - 5 threads dedicated to handling 'all the players' evenly but like i said in a single core system threads don't matter so much and spawning 1 thread per client will bottleneck that cpu further and become far more efficient than if you had just sequentially processed them using a foreach.

 

 

An even simpler solution would be to ditch c# in favour of nodejs as its non blocking asynchronous event architecture works tremendously well for game servers and its only ever so slightly diffrent to implement. Plus you can even run the server on linux, which you couldn't do using a c# project w/out mono and thats just opening a new can of worms to deal with.... :)

 

Anyway, i might release a more practical example until then hopefully these points can point you in the right direction :) good luck!


  • 0

YYG-Promo-2-150px.png Smooth-Cameras-150-150x150.jpg GMUI-Sig1.png Virtyal-Joy-150x150.png

RPG Creation Kit | Smooth Cameras | GM UI Framework | Virtual Joy

http://www.rm2kdev.net For game maker tutorials tips tricks and games


#13 FatalSleep

FatalSleep

    FatalSheep?

  • GMC Member
  • 3974 posts
  • Version:GM:Studio

Posted 15 May 2014 - 04:58 AM

You sure nodejs would be any better than C#? I don't see how it could if I'm using async events in C# just as I would in nodejs.

I don't know though, I don't know much of nodejs.

 

I'll look into your suggestions and adjust the server accordingly.


  • 0

#14 Debels

Debels

    GMC Member

  • GMC Member
  • 3029 posts
  • Version:GM:Studio

Posted 15 May 2014 - 07:14 PM

I would do something like 1 thread per 10 players, it really depends on the type of server your creating and the code your doing.

 

If your going to make a simple chess game then 1 thread per 50-100 players (maybe its to much or maybe to little), but reason being is that chess is a slow paced game that doesn't require much processing, besides checking if its a valid move.

 

For this example in my opinion the safest bet is to do 1 thread per 10 players and 1-2 (yet again it depends on the size of the game and traffic) thread for server related, such as login, register, channel select, character select and such.


  • 0

"Give a man a fish, and you feed him for a day; show him how to catch fish, and you feed him for a lifetime."

(Chinese axiom)


#15 FatalSleep

FatalSleep

    FatalSheep?

  • GMC Member
  • 3974 posts
  • Version:GM:Studio

Posted 15 May 2014 - 07:57 PM

I would do something like 1 thread per 10 players, it really depends on the type of server your creating and the code your doing.

 

If your going to make a simple chess game then 1 thread per 50-100 players (maybe its to much or maybe to little), but reason being is that chess is a slow paced game that doesn't require much processing, besides checking if its a valid move.

 

For this example in my opinion the safest bet is to do 1 thread per 10 players and 1-2 (yet again it depends on the size of the game and traffic) thread for server related, such as login, register, channel select, character select and such.

That won't work because now, you'll be sacrificing CPU instead of RAM due to having to foreach the client processes inside each thread.

On the other hand, it could work as well, but really only for very low process/slow paced games, but most games people would make will most likely

be related to faster paced or semi-fast paced action games. I plan to implement either threadpooling or async socket IO methods in order to speed

up the system.


  • 0

#16 Debels

Debels

    GMC Member

  • GMC Member
  • 3029 posts
  • Version:GM:Studio

Posted 15 May 2014 - 07:58 PM

 

I would do something like 1 thread per 10 players, it really depends on the type of server your creating and the code your doing.

 

If your going to make a simple chess game then 1 thread per 50-100 players (maybe its to much or maybe to little), but reason being is that chess is a slow paced game that doesn't require much processing, besides checking if its a valid move.

 

For this example in my opinion the safest bet is to do 1 thread per 10 players and 1-2 (yet again it depends on the size of the game and traffic) thread for server related, such as login, register, channel select, character select and such.

That won't work because now, you'll be sacrificing CPU instead of RAM due to having to foreach the client processes inside each thread.

On the other hand, it could work as well, but really only for very low process/slow paced games, but most games people would make will most likely

be related to faster paced or semi-fast paced action games. I plan to implement either threadpooling or async socket IO methods in order to speed

up the system.

 

I have threadpool's on my Java server and it works like a charm. Really recommend it :)


  • 0

"Give a man a fish, and you feed him for a day; show him how to catch fish, and you feed him for a lifetime."

(Chinese axiom)


#17 FatalSleep

FatalSleep

    FatalSheep?

  • GMC Member
  • 3974 posts
  • Version:GM:Studio

Posted 20 May 2014 - 05:38 AM

Alright, so I made my adjustments as necessary and uploaded the changes to GitHub and Host-A!

Just a simple update. :) Once again, if you find any issues, please let me know!

 

An extra bit of info. I ran a somewhat odd test on the server with a simple client application that ran

around 350 clients without any issues on the server. Although the server application had a bit of trouble

running due to me having to test while running 350 client connections and the server application on my

home computer. The server can run more clients, but 350 was the max amount I could test with my limited

testing hardware.


  • 0

#18 Zachary Rottmann

Zachary Rottmann

    GMC Member

  • New Member
  • 2 posts
  • Version:GM:Studio

Posted 22 May 2014 - 11:49 PM

if i wanted to get this thing running do i place the code under the create event for any obj?


  • 0

#19 FatalSleep

FatalSleep

    FatalSheep?

  • GMC Member
  • 3974 posts
  • Version:GM:Studio

Posted 23 May 2014 - 12:37 AM

Pretty much, it's best to have a single object dedicated to handling all the networking on the client, it simplifies everything. You can really initiate the networking however you want. For example, you could have the client start the networking and connect to the server after the client hits enter or clicks a button on screen.


  • 0

#20 GMS

GMS

    GMC Member

  • GMC Member
  • 18 posts
  • Version:GM:Studio

Posted 23 May 2014 - 01:07 AM

Thanks for the great post i have small experience with C# and this was exactly what i was looking for. Glad you didn't use node.js.

 

I was wondering if I wanted to host my game on amazon ec2 for example i need to place the url given by them in    network_connect_raw and myIP (IP Address),in part 2 spoiler?

 

In spoiler part 4 myEndPoint.Address & myEndPoint.Port can be used to get the ip and port. This means clients don't have to manually insert there ip correct?

 

I should upload these classes to the server some how right?


  • 0

#21 FatalSleep

FatalSleep

    FatalSheep?

  • GMC Member
  • 3974 posts
  • Version:GM:Studio

Posted 23 May 2014 - 04:05 AM

The server has the IP and Port with the endpoint read and passed as parameters to the read method for you to use. So yes, you don't need

to write either the port or IP address of the client to the packets manually. The TCP and UDP systems do this themselves.

 

Yes, all you need to do is provide the URL in place of the IP address in order to connect to your server hosted behind the URL.


  • 1

#22 apalapa

apalapa

    GMC Member

  • GMC Member
  • 34 posts

Posted 24 May 2014 - 08:21 PM

Assuming that Studio:HTML5 still doesn't support a lot of networking functions, has this been tested on HTML5? Would it work?


  • 1

#23 FatalSleep

FatalSleep

    FatalSheep?

  • GMC Member
  • 3974 posts
  • Version:GM:Studio

Posted 25 May 2014 - 07:02 AM

Unfortunately no, HTML5 does not support networking, so it won't work. I one day might get to making a Javascript extension, but we'll see.

For now you can however use networking on Android, iOS, Windows, Linux, etc. Literally everything but HTML5.


  • 0

#24 Greenhawk

Greenhawk

    Gue Games

  • GMC Member
  • 722 posts
  • Version:GM:Studio

Posted 03 June 2014 - 02:26 PM

So if I was able to put this in my game, I wouldn't have to do much but sync the objects using the GM:S client?


  • 0

Games Made:

 

Youtube Channels:

One of the many GMC Gurus.


#25 FatalSleep

FatalSleep

    FatalSheep?

  • GMC Member
  • 3974 posts
  • Version:GM:Studio

Posted 03 June 2014 - 02:58 PM

Most likely unless you absolutely need major server side processing.

Usually everything can be done client side except for things like registry, log in and payment verification if you actually were to use any of that.

So yup, you'd mostly be doing object syncing with dead reckoning and latency masking most likely client side along with whatever else is

necessary for your game to function.


Edited by FatalSleep, 03 June 2014 - 03:00 PM.

  • 0

#26 autukill

autukill

    GMC Member

  • GMC Member
  • 144 posts
  • Version:GM:Studio

Posted 05 June 2014 - 01:52 AM

Could you combine with Protobuff or JSON?


Edited by autukill, 05 June 2014 - 02:01 AM.

  • 1

#27 FatalSleep

FatalSleep

    FatalSheep?

  • GMC Member
  • 3974 posts
  • Version:GM:Studio

Posted 05 June 2014 - 05:42 AM

I'll look into it, I've never used either, so we'll have to see.


  • 0

#28 chaz13

chaz13

    GMC Member

  • GMC Member
  • 4214 posts
  • Version:Unknown

Posted 17 June 2014 - 10:16 AM

This is a really useful guide, was looking for something just like this. Thanks man!


  • 0

#29 FatalSleep

FatalSleep

    FatalSheep?

  • GMC Member
  • 3974 posts
  • Version:GM:Studio

Posted 17 June 2014 - 08:50 PM

No problem! Glad it's helping people. If you have any questions on either the GML or C# side of things,

make sure to ask.


  • 0

#30 AcTiViSioN

AcTiViSioN

    GMC Member

  • GMC Member
  • 69 posts
  • Version:GM:Studio

Posted 18 June 2014 - 01:46 PM

It does not work in HTML5, right? Will guide, how to use the network in HTML5? I want to write a game online, but so far it only connected with MySql, but this is only database. I definitely need a server for other calculations, fielding timers etc.

Edited by AcTiViSioN, 18 June 2014 - 01:53 PM.

  • 0

#31 FatalSleep

FatalSleep

    FatalSheep?

  • GMC Member
  • 3974 posts
  • Version:GM:Studio

Posted 18 June 2014 - 04:25 PM

Well the server itself is Windows based, so it can't be used as a web application. However this isn't an issue, this is normal for servers.

The CLIENT should be HTML5 though, if that's your focus. However, GMS does not currently support web sockets at the moment.

If you want web sockets, you'll need to search out for a JavaScript extension that handles the web sockets for you.


  • 1

#32 wnsrn3436

wnsrn3436

    GMC Member

  • GMC Member
  • 194 posts
  • Version:GM:Studio

Posted 30 June 2014 - 06:46 AM

I can not connect 'host-a.net' page.
Can you give me the another link?
  • 0

#33 FatalSleep

FatalSleep

    FatalSheep?

  • GMC Member
  • 3974 posts
  • Version:GM:Studio

Posted 30 June 2014 - 08:30 AM

I have migrated the links to Dropbox from Host-A, check the main post again for the download. :)


  • 0

#34 wnsrn3436

wnsrn3436

    GMC Member

  • GMC Member
  • 194 posts
  • Version:GM:Studio

Posted 30 June 2014 - 09:17 AM

Good! :) As I see it, this source & class's function is very useful.
I was to save time to create similar to it. Thanks to you.

Edited by wnsrn3436, 30 June 2014 - 09:17 AM.

  • 0

#35 FatalSleep

FatalSleep

    FatalSheep?

  • GMC Member
  • 3974 posts
  • Version:GM:Studio

Posted 30 June 2014 - 10:09 AM

Good! :) As I see it, this source & class's function is very useful.
I was to save time to create similar to it. Thanks to you.

No problem, I am all about saving time, especially with networking!

I am glad it's helping people, literally took a month of on and off working on it to finish it.

On top of this, I had to run it alongside a GMS client for testing haha. The buffer system

literally perfectly fits with GMS for networking purposes, took ages to test out the bugs lol.


  • 0

#36 n0997

n0997

    GMC Member

  • New Member
  • 6 posts
  • Version:Unknown

Posted 11 July 2014 - 03:44 PM

I found with the c# server open and open the client, the client never draws.

 

It does however connect.. I can see the connection on the c# server (tc[count)

 

But without a window to close it gets stuck in memory.


  • 0

#37 FatalSleep

FatalSleep

    FatalSheep?

  • GMC Member
  • 3974 posts
  • Version:GM:Studio

Posted 11 July 2014 - 04:15 PM

Heh, I am not sure how to fix that without specific details. If the client doesn't draw that's not really an

issue with my server. When the client "doesn't draw" is it not responding, frozen? If so you could be

doing something to cause the client to stop working.

 

I cannot fix that without details. Also what's this about not having a window to close? You'll need to be

a bit more specific for me to be able to help.


  • 0

#38 n0997

n0997

    GMC Member

  • New Member
  • 6 posts
  • Version:Unknown

Posted 11 July 2014 - 11:58 PM

Well I was just using the Client in your networking tutorial so I can see this all working.

 

I haven't done anything except change the ip on the c# server to 192.168.1.2 , (edit: ohh and I had to change the port on the gm client to the same as the c# server)

 

So your gm client and c# server

 

The hanging is like it is chatting between the server and client so much that it never gets to the part to draw the gamemaker window.

But like I said the server does indeed see it connected, and the CPU use is 10% for the gamemaker client.


Edited by n0997, 12 July 2014 - 12:01 AM.

  • 0

#39 FatalSleep

FatalSleep

    FatalSheep?

  • GMC Member
  • 3974 posts
  • Version:GM:Studio

Posted 12 July 2014 - 12:35 AM

Well I was just using the Client in your networking tutorial so I can see this all working.

 

I haven't done anything except change the ip on the c# server to 192.168.1.2 , (edit: ohh and I had to change the port on the gm client to the same as the c# server)

 

So your gm client and c# server

 

The hanging is like it is chatting between the server and client so much that it never gets to the part to draw the gamemaker window.

But like I said the server does indeed see it connected, and the CPU use is 10% for the gamemaker client.

"hanging is like it is chatting between the server and client so much that it..." This is odd, this should happen at all,

even at sending 60 packets per second or maybe even more. The issue could be on your end with GML?

 

However, 192.168.1.2 is not a valid IP address, this is actually what looks to be your default-gateway IP address, so the issue

could be that GameMaker is trying to validate a connection to the server, but is failing to do so. Check your IP again, change/correct

it if possible and reconnect.


Edited by FatalSleep, 12 July 2014 - 12:35 AM.

  • 0

#40 n0997

n0997

    GMC Member

  • New Member
  • 6 posts
  • Version:Unknown

Posted 12 July 2014 - 02:04 AM

192.168.1.2 Is the IP of the computer I am running both server and client on.

 

192.168.1.1 Is my default gateway.

 

Your time is appreciated, I am trying to understand this process for a community game we are creating, using gamemaker will speed up the development of the client 100%. But we need c# processing speeds on the server side, so your solution is going to be best for us I think.


  • 1

#41 n0997

n0997

    GMC Member

  • New Member
  • 6 posts
  • Version:Unknown

Posted 21 July 2014 - 11:03 PM

Just an update:
 
To get it working I had to change network_connect_raw() into network_connect()

 

Well not sure what I did but its working now... on both raw and not raw.

 

Thanks for this .. its a great first step for me.


Edited by n0997, 21 July 2014 - 11:07 PM.

  • 0

#42 FatalSleep

FatalSleep

    FatalSheep?

  • GMC Member
  • 3974 posts
  • Version:GM:Studio

Posted 21 July 2014 - 11:41 PM

Just an update:
 
To get it working I had to change network_connect_raw() into network_connect()

 

Well not sure what I did but its working now... on both raw and not raw.

 

Thanks for this .. its a great first step for me.

Don't connect to a non-GML based server with network_connect(), if you do that,

you'll be asking for trouble...


  • 0

#43 n0997

n0997

    GMC Member

  • New Member
  • 6 posts
  • Version:Unknown

Posted 22 July 2014 - 11:32 AM


Don't connect to a non-GML based server with network_connect(), if you do that,

you'll be asking for trouble...

 

Ok, thanks for the tip.


  • 0

#44 Chinafreak

Chinafreak

    GMC Member

  • GMC Member
  • 353 posts
  • Version:GM:Studio

Posted 23 August 2014 - 11:47 AM

Hello,

this is a great tutorial, I've understand a bit how the server and client work... But I've some problem on C# server, yes I'm noob and I want learn more about this!

Spoiler

 

Thank you! :)

 

And Thank you for this wonderful Tutorial!


Edited by Chinafreak, 23 August 2014 - 11:48 AM.

  • 1

#45 FatalSleep

FatalSleep

    FatalSheep?

  • GMC Member
  • 3974 posts
  • Version:GM:Studio

Posted 23 August 2014 - 12:23 PM

@Chinafreak you aren't too much of a noob, I failed on implementing some core features...
+1 for helping bring them to light.

  1. The issue is that you're using "MyEndPoint" not "myIPEndPoint" which is the variable name for the EndPoint of the function! :)
  2. The IP info is all related to the client's EndPoint, this is "myIPEndPoint.Port" and "myIPEndPoint.Address" in the EndPoint.

    NOTE: This is that part where you shoot me because I didn't implement the concept of socket IDs to be consistent with GameMaker...
    Due to this, I will be rewriting the C# server to be more... user friendly, socket ID friendly and class friendly, because I jump right on
    threads without considering too much how nice it'd be to handle clients via classes! You'll see what I mean in the rewrite...

    Without a socket ID system, you can easily send a message to the server and have it relay the message back to the client that sent
    the message. However, it gets a bit difficult to had in conditional situations. E.g. send to client with socket ID of X, Y and Z..

    Honestly, you can do conditional situations using the NetworkStream and TcpClient list via TcpSocketList for comparisons and from
    what it looks like, that is what I was going for, and I feel terrible about it now.
  3. As for #3, the issue could be that you're flooding the network with messages because the TcpPacketSend() method runs constantly.
    So if you send a message here, it'll constantly be sending at max speed, no FPS or speed cap. So you could be trying to send thousands
    of messages a second and not realizing.

 

... Please forgive me here, I'll rewrite the system base and should have it up in about a week or so.
Don't get me wrong, there isn't really nay issues with the current system, it's simply missing some... major features.
Feel free to fiddle with it as much as possible and implement some features on your own, but only until I get the new
update out.


Edited by FatalSleep, 23 August 2014 - 01:01 PM.

  • 1

#46 Chinafreak

Chinafreak

    GMC Member

  • GMC Member
  • 353 posts
  • Version:GM:Studio

Posted 23 August 2014 - 10:19 PM

@FatalSheep oh, I've just though I'm stupid, because I've thought I've not read tutorial correctly. :D
Okay, then I'll wait. Thank you for your answers. I'll wait if you've rewrite the C# server. :) This is perfect for my multiplayer games! At the moment my server is running under GUI-Application and this is not professional but it's work. ^^

Let see. :)
  • 1

#47 FatalSleep

FatalSleep

    FatalSheep?

  • GMC Member
  • 3974 posts
  • Version:GM:Studio

Posted 28 August 2014 - 06:33 PM

@FatalSheep oh, I've just though I'm stupid, because I've thought I've not read tutorial correctly. :D
Okay, then I'll wait. Thank you for your answers. I'll wait if you've rewrite the C# server. :) This is perfect for my multiplayer games! At the moment my server is running under GUI-Application and this is not professional but it's work. ^^

Let see. :)

Alright, so it took me around 8 hours, but I completely rewrote the server, added the socket system(completely identical to GameMaker Studio)

and made the whole thing a bit more user friendly. I'll test it for a day or so, then upload it for you along with a brand new documentation,

walk-through and everything you might need to get going again.


Edited by FatalSleep, 28 August 2014 - 06:33 PM.

  • 1

#48 FatalSleep

FatalSleep

    FatalSheep?

  • GMC Member
  • 3974 posts
  • Version:GM:Studio

Posted 30 August 2014 - 07:51 AM

Update released! Please read the main post for more information!


  • 1

#49 Chinafreak

Chinafreak

    GMC Member

  • GMC Member
  • 353 posts
  • Version:GM:Studio

Posted 04 September 2014 - 02:17 PM

Hey FatalSheep,
 
Good work! It's look easier now! But I've a error:

Spoiler


And a small question:
 
My currently GUI Server is working on Box2D (I know, this is not nice, but I need Box2D calculations. For a good reason), so how can I teach the server that also expects calculation exactly from GM:S Box2D?

Sorry for the noob questions. Hurr.

- Chini

(And congratulation! You've 700 like/reputation!)

Edited by Chinafreak, 04 September 2014 - 02:42 PM.

  • 0

#50 FatalSleep

FatalSleep

    FatalSheep?

  • GMC Member
  • 3974 posts
  • Version:GM:Studio

Posted 04 September 2014 - 06:08 PM

My apologies, looks like you're using the GitHub Repository, which has the issue.

I accidentally uploading the wrong code for the UdpNetwork.cs file! D: I've fixed it

and here is a quick link to it for convenience!

 

Umm... physics aren't exactly my thing, I've not actually ever used Box2D, so I

cannot help in that field. My apologies!


  • 1