Jump to content

  • Log In with Google      Sign In   
  • Create Account

Theis_Bane

Member Since 29 Feb 2012
Offline Last Active Jun 07 2014 10:30 AM

Topics I've Started

Map Zooming and Detail

20 May 2014 - 04:22 PM

I had an odd thought the other day. Say you had a continent level map, detailing the shape of the land, terrain features, and interesting locations. Now, say you wanted to be able to zoom in and out of that map to get a greater level of detail, but you didn't want to go in and draw out multiple levels of detail for every inch of the landscape.

Would it be possible to generate say, beach shape, on the fly as you zoom in by using a seeded randomly generated number to calculate terrain variations based on the main image and previous zoom levels? If so, how would one go about calculating this? Am I even making sense?

WPF and maps

26 March 2014 - 02:50 PM

Don't know if this the right forum but here goes. I'm planning a setting building program/game where you can either draw out a map and add zones like towns and forests, or scan a hand drawn map and define the different zones. For now, the main purpose will be information storage (like town info and maps, forest encounter tables and general info). I picture it almost like a DM's setting assistant.

However, I've done little to no graphics programming, so I'm unsure how to proceed. Do I use tiles? I don't even know. In the future, I'd like to be able to add animation to my natural features ( like trees blowing in the wind). I operate mostly I WPF. Any advice on where to begin?

WPF DataBinding

27 September 2013 - 11:53 PM

OH THE GODS!!!! This problem has me ready to EAT THIS COMPUTER.

 

I have a character sheet designed in WPF that I am attempting to bind to a global Character object that holds all the information for the player's avatar.  Each TextBlock that displays info looks like this:

<TextBlock x:Name="tbkStrTotal" Grid.Row="1" Grid.Column="4" HorizontalAlignment="Right"
                       Foreground="White" Background="Black" Text="{Binding Strength}"

Because I wanted changes to my Character object to update my CharacterSheet window, I went through and implemented INotifyPropertyChanged.

Relevant code:

public class CharacterInfoModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private string m_Strength = "20";

        public string Strength
        {
            get
            {
                return m_Strength;
            }
            set
            {
                m_Strength = value;
                OnPropertyChanged("Strength");
            }
        }

        protected void OnPropertyChanged(string name)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(name));
            }
        }

Next, after initializing all of my windows, I hooked my CharacterInfoModel object to my CharacterSheet window's DataContext property.

public CharacterScreen()
        {
            InitializeComponent();
            this.DataContext = GameInfo.Character;
            
        }

The whole thing works great, until I try to change the value of Strength through code.  It won't update.  My PropertyChanged handler is always null, even though I thought it was supposed to get wired up automatically when I bound my CharacterInfoModel object to my CharacterSheet window's DataContext property.  Well, I think that's how it works.  I can't actually find anyone on the Google that can explain how it gets wired up, only that it NEEDS to be wired up.  So, halp.  Thanks in advance.


Writing a basic TCP Socket programming tutorial - Interest?

23 February 2013 - 06:44 PM

I've been struggling with basic socket programming for the past few months, and I believe, with the help of local guru Kylotan, that I've finally gotten a handle on the basics.  It's been a rough journey, trying to piece together what I need to know from books, forums, and web articles... a journey that I believe could have been made MUCH less painful if I had had access to the right information.

 

Of course, right for me might not be right for you, or anyone else for that matter.  However, I feel like many of these sources either assume a level of comprehension far above most beginner's capabilities (and thereby barely touching on some very key points), focus their attention on a very specific aspect of using sockets, or are just copypasta'd from someone else and then explained from a basis of limited understanding.  Not to mention the articles written by people for whom English is NOT their first language.

 

So I'm considering writing a ground-up, first-time user TCP socket programming tutorial (using C#) that touches on all the problems that I went through as I tried to learn, and hopefully some of the ones that I saw coming and successfully sidestepped.  My question:  Would this be of any interest to anyone out there, or would I be wasting my time?  As a beginner, I plan on throwing it out there for the more experienced to digest and critique, knowing full-well that I'm not the most qualified on the subject. Still, I think my proximity to the subject and relatively shallow experience base could really serve those in a position similar to my own.

 

Thoughts?


TCP Server NetworkModel for MUD

17 February 2013 - 10:46 PM

So, after taking the advice of the forum some 6 months ago to start my game-making career off with a simple text adventure, I am now neck-deep in a (somewhat) working MUD.  What can I say?  Go big or go home.  Up until a few days ago, the networking portion of my MUD was working beautifully, but as I started sending more and more messages between client and server, I began noticing some odd behavior.  Namely, my poorly implemented NetworkModel class had no way to deal with message overlap.  I have since attempted to remedy this problem, as I will show you shortly. 

 

First, let me explain my strategy.  I'm sending strings separated with ` and ~ to denote the various parts of the message.  These strings are then split, routed, and examined by the engines on both sides to generate an effect.  Pretty standard.  When a client connects to my server, I store the open connection in two dictionaries - one by characterID, the other by acccountID.  Both are filled outside of the class by the Game Manager class.  Requests are added to a list that the Game Manager pulls from, executing the top-most request then discarding it.  Both dictionaries and the list are custom thread-safe class I've designed (cuz I'm using VS 2008).

 

Alright, code avalanche incoming.

public class ClientInfo
    {
        public Socket WorkSocket = null;        
        public byte[] Buffer;
        public byte[] BackBuffer;
        public string RecIncom = "";

        public ClientInfo(Socket client, int buffersize)
        {
            WorkSocket = client;
            Buffer = new byte[buffersize];
            BackBuffer = new byte[buffersize];
        }
    }
    
    public class NetworkModel
    {
        public const int BUFFER_SIZE = 1024;
        private const string HEADER = "``";
        private const string FOOTER = "~~";
        
        #region PROPERTIES

        private Socket Server;        
        public SafeDictionary<string, Socket> ConnectionsbyCharacter;
        public SafeDictionary<string, Socket> ConnectionsbyAccount;        

        public SafeList<RequestModel> RequestQueue;

        #endregion PROPERTIES

        #region CONSTRUCTORS

        public NetworkModel(int port, SafeList<RequestModel> requests)
        {
            ConnectionsbyAccount = new SafeDictionary<string, Socket>();
            ConnectionsbyCharacter = new SafeDictionary<string, Socket>();
            RequestQueue = requests;
            
            Server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint EndPoint = new IPEndPoint(IPAddress.Any, port);
            Server.Bind(EndPoint);
        }

        #endregion CONSTRUCTORS

        #region METHODS
        
        public void Begin()
        {
            Server.Listen(20);
            Server.BeginAccept(new AsyncCallback(Accept), null);
        }
        
        private void Accept(IAsyncResult Result)
        {
            ClientInfo newClient = new ClientInfo(Server.EndAccept(Result), BUFFER_SIZE);
            Server.BeginAccept(new AsyncCallback(Accept), null);            
            newClient.WorkSocket.BeginReceive(newClient.Buffer, 0, 1024, SocketFlags.None,
               new AsyncCallback(ReceiveMessage), newClient);
        }

        public void Send(Socket client, string ToSend)
        {           
            byte[] Message = Encoding.ASCII.GetBytes(HEADER + ToSend + FOOTER);
            client.BeginSend(Message, 0, Message.Length, SocketFlags.None,
                    new AsyncCallback(SendMessage), client);
        }

        public void Send(string ID, string ToSend)
        {            
           Socket Client = ConnectionsbyCharacter[ID];
           byte[] Message = Encoding.ASCII.GetBytes(HEADER + ToSend + FOOTER);
           Client.BeginSend(Message, 0, Message.Length, SocketFlags.None,
                   new AsyncCallback(SendMessage), Client);            
        }

        public void SendToAllConnected(string ToSend)
        {
            foreach (Socket client in ConnectionsbyCharacter)
            {
                Send(client, ToSend);
            }
        }

        private void SendMessage(IAsyncResult Result)
        {
            Socket Client = (Socket)Result.AsyncState;
            int AmountSent = Client.EndSend(Result);
            //Look into comparing amount sent vs. size of original message?          
        }

        private void ReceiveMessage(IAsyncResult Result)
        {
            ClientInfo thisClient = (ClientInfo)Result.AsyncState;
            
            string Received = "";
            try
            {
                int AmountReceived = thisClient.WorkSocket.EndReceive(Result);

                //If we've received any sort of message...
                if (AmountReceived > 0)
                {
                    //Translate the message and determine begin points and end points
                    string Contents = Encoding.ASCII.GetString(thisClient.Buffer, 0, AmountReceived);
                    int HeadLoc = Contents.IndexOf(HEADER);
                    int TermLoc = Contents.IndexOf(FOOTER);

                    //If we have a begin point...
                    if (HeadLoc > -1)
                    {
                        //...and an end point, and begin comes first...
                        if (TermLoc > -1 & HeadLoc < TermLoc)
                        {
                            //...we've received one whole message!
                            Received = Contents.Substring(HeadLoc, TermLoc - HeadLoc + 1);

                            //Now we need to check if there is another message, partial or otherwise, also stored in the buffer
                            if (TermLoc != 1022 & thisClient.Buffer[TermLoc + 2] != null)
                            {
                                //If so, copy the unused buffer portion to temp storage while we clear the main buffer, then
                                //copy back so we can begin receiving it again
                                int Len = thisClient.Buffer.Length - TermLoc - 1;
                                Array.Copy(thisClient.Buffer, TermLoc + 2, thisClient.BackBuffer, 0, Len);
                                thisClient.Buffer = new byte[BUFFER_SIZE];
                                Array.Copy(thisClient.BackBuffer, thisClient.Buffer, Len);
                                thisClient.BackBuffer = new byte[BUFFER_SIZE];
                                thisClient.WorkSocket.BeginReceive(thisClient.Buffer, 0, 1024, SocketFlags.None,
                                    new AsyncCallback(ReceiveMessage), thisClient);
                            }
                            else
                            {
                                //Otherwise, just clear the main buffer
                                thisClient.Buffer = new byte[BUFFER_SIZE];
                            }
                        }
                        //...and an end point, but end comes first...
                        else if (TermLoc > -1 & TermLoc < HeadLoc)
                        {
                            //This means we are looking at the end of a previous message, so get the last bit of the last message
                            //and add it to the previous.
                            thisClient.RecIncom += Contents.Substring(0, TermLoc + 2);
                            Received = thisClient.RecIncom;
                            thisClient.RecIncom = "";
                            //Now we need to move the next message to a temp buffer to clear the main buffer, then copy it all back
                            //and start receiving again
                            int Len = thisClient.Buffer.Length - TermLoc - 1;
                            Array.Copy(thisClient.Buffer, TermLoc + 2, thisClient.BackBuffer, 0, Len);
                            thisClient.Buffer = new byte[BUFFER_SIZE];
                            Array.Copy(thisClient.BackBuffer, thisClient.Buffer, Len);
                            thisClient.BackBuffer = new byte[BUFFER_SIZE];
                            thisClient.WorkSocket.BeginReceive(thisClient.Buffer, 0, 1024, SocketFlags.None,
                                    new AsyncCallback(ReceiveMessage), thisClient);
                        }
                        //...but no end point
                        else
                        {
                            //This means we have a partial message.  This partial goes into a holding string while we 
                            //clear our buffer and start receiving the rest of the message
                            thisClient.RecIncom = Contents.Substring(0, AmountReceived);
                            thisClient.Buffer = new byte[BUFFER_SIZE];
                            thisClient.WorkSocket.BeginReceive(thisClient.Buffer, 0, 1024, SocketFlags.None,
                                    new AsyncCallback(ReceiveMessage), thisClient);
                        }
                    }
                    //If we DON'T have a begin point...
                    else
                    {
                        //...but we DO have an end point
                        if (TermLoc > -1)
                        {
                            //This is the rest of a partial message, so we just add the two together and clear our buffer!
                            Received = thisClient.RecIncom + Contents.Substring(0, TermLoc + 1);
                            thisClient.RecIncom = "";
                            thisClient.Buffer = new byte[BUFFER_SIZE];                            
                        }
                        //...and we don't have an end point
                        else
                        {
                            //This is more of a partial message, so just add it, clear the buffer and start receiving again
                            thisClient.RecIncom += Contents;
                            thisClient.Buffer = new byte[BUFFER_SIZE];
                            thisClient.WorkSocket.BeginReceive(thisClient.Buffer, 0, 1024, SocketFlags.None,
                                    new AsyncCallback(ReceiveMessage), thisClient);
                        }
                    }
                }

                //If a complete message was received, parse it out into RequestModel object and add it to the game loop
                if (Received != "")
                {
                    Received = Received.Substring(2, Received.Length - 2);
                    string[] Split = Received.Split('`');
                    string[] AccountSplit = Split[0].Split('~');
                    string[] MessageSplit = Split[1].Split('~');

                    //Message received format = AccountID~CharacterID`ect~ect.
                    RequestModel Request = new RequestModel();
                    Request.Client = thisClient.WorkSocket;
                    Request.AccountName = AccountSplit[0];
                    Request.CharacterID = AccountSplit[1];
                    Request.Request = MessageSplit;
                    RequestQueue.Add(Request);
                }

                //Do I need this?
                thisClient.WorkSocket.BeginReceive(thisClient.Buffer, 0, 1024, SocketFlags.None,
                    new AsyncCallback(ReceiveMessage), thisClient);
            }
            catch
            {
            }            
        }            

        #endregion METHODS
    }

 

I plan on implementing something very similar to this client-side. I THINK I have all my message overlap problems ironed out, but I would like some advice from those with more experience.  I couldn't find much more than theory when it came to solving message overlap, so I had to pretty much make this up as I went.  Is there anywhere I can shore this up?  Will it cause me problems in the future? Is it going to be too slow?  Thanks in advance!


PARTNERS