• Content count

  • Joined

  • Last visited

Community Reputation

185 Neutral

About Mitchell314

  • Rank
  1. MMO Server questions

    Also, when you start talking about large scale applications (MMO*), you probably should start studying distributed computing, load balancing, and IPC concepts in depth first before diving in. These are pretty advanced topics, and creating efficiently scaling systems is very difficult. It may also help to move from the mindset of one monolithic server process controlling the game to thinking in terms of multiple modular programs running in parallel to spread the work load.
  2. MMO Server questions

    Not to mention that Windows servers tend to be more expensive for running the same tier of hardware compared to Linux on EC2.
  3. [solved] Calling recv() in a loop

    Thanks, that clears up my question. The protocols I'm using are just based around arbitrarily-length string messages separated by delimiters; message size is not communicated by any process. I've been burnt quite badly in the past by assuming that TCP preserves packet boundaries, hence the rotating buffers. :P   I've just never seen anybody else do it that way.
  4. [solved] Calling recv() in a loop

    Ah thanks. That code was made up for this thread for simplicity's sake, the actual code does use select() and handles the memory buffers. The strategy I'm using is to keep a linked list of buffers per connection, where each recv() reads data into a new buffer, and if any data is written it is added to the end of the linked list. The buffers are freed when the parser processes the list later. According to the man pages for recv(2):         But it doesn't say which. And since I've been having networking-related bugs, I want to make sure that I'm not accidentally dropping data while not being susceptible to buffer overflow bugs/exploits. Blocking isn't too much of an issue; the program is supposed to be a daemon anyways. The program is connecting to game server instances, which may stream small or large amounts of data, and connecting to admin tools, which stream short commands. However, there is no set packet size, so I want to know if I can play it safe by reading from a socket into a growing list of buffers until it is dry.
  5. When reading a tcp socket for arbitrarily sized packets, is it safe to keep calling recv() until it returns a negative number? For simplicity's sake, I'm assuming no other error is raised, just that return value of 0 means connection closed, and -1 means there's no data left to be read at the time.   For example, would the following code properly read all of the socket's contents? The other end of the connection is sending data in the format of "<text> \n <text> \n <text> \n .... <text> \n" /* Make believe string structure */ struct resizableString string; int bufferSize = 100; int socket = connectToOtherHost(); while (-1){   char *pBuffer = calloc(bufferSize); int bytesRead = recv(socket, pBuffer, bufferSize, 0);   if (bytesRead == 0) {   printf("Client closed connection\n");   } else if (bytesRead >0) { /* Appends fix-length buffer to a string */   appendBufferToString(string, pBuffer, bufferSize);  } else { /* Done reading */ free(pBuffer);   break;  } } parsePacket(&string);
  6. On mice and scripting

    So the game server has been ported to linux (debian). Unfortunately, the networking code took the most changing, and as a result, it is throwing a complete fit. So, that's a thing. So, a big focus in the past week is scripting. Particularly, built-in scripting for the server, and remote scripting. I've written a command line tool for integrating communication with shell scripts. So far, it looks good, but I can't fully test it until I get the server running properly again. I still have some code to enable running on windows, but I don't really have any plans to port back. In fact, I do want to eventually rewrite a large chunk of the networking code, and that will likely involve cutting out said code. Anywho, this should helpfully make it easier to develop admin tools. Next on the plate is integrated server side scripting. A big nagging theme is boilerplate overload with coding in the api, and the business logic could be greatly simplified if it ran atop a simple scripting engine. The issue is that coding in a scripting issue is a non-trivial amount of work. And adds more places for bugs to hide. Ah well, I'll work on it once I get a bare-bones operation up and running.
  7. The Joys Of Nesting

    Excessive code!   But on a serious note, I've been taught a rule of thumb that whatever reduces complexity tends to be the lesser evil.
  8. The Joys Of Nesting

    Hah, yeah, modularity is a good thing. :P   Then again, the old versions of towny's code was a nightmare to work with. And yet it is an excellent and popular plugin.
  9. initialCommit()

    Seavax is my current project to develop a multi-player, turn-based strategy game with a focus on world exploration, discovery, building, and conquering. Inspirations: Here are some of the main games that gave me the thoughts of "hey, this would be a cool idea to play around with" Freeciv: (The Freeciv project) --- Underlying client-server code design --- Procedurally generated worlds --- 2d tile based world --- Turn based Globulation2: (Globulation2 Team) --- Delegating micro-management away from the player --- Focus on unit development --- AI Minecraft: (Mojang) --- Combination of survival/build attitude --- Randomly generated terrain and biomes --- Permission system (more from the mod community) --- Why whitelists are a good thing --- Tech tree. There's no tech tree in mc, but the crafting progression influenced how I designed mine. --- Much of my exposure to game dev is from looking at the open source mods. --- Community-server relationship Setting: The terrain is generated procedurally to make a climate template, then when a new game is started a map is created from the template. The first thing generated is the raw height map; a number of points are chosen to have the terrain raised around it, and sea level is relative to average height. Next, temperature is calculated by latitude and altitude. Finally, ocean currents and temperatures are calculated, and from that the precipitation map is made. The final result is the template file, representing an evenly spread 2d array of points describing elevation, precipitation, and temperature. Alternatively a template could be made by hand or by some 3rd part software; the file format is a pretty simple list of tab separated values. Future server versions may (and probably will) have the terrain generator tweaked and changed, but the format shouldn't change much. The idea is for them to have the basic information to generate a full map, but be easily transferred or modified while being version agnostic. And also be reusable by default. A game map contains the information for the current game instance: a 2d region map of an of array of tiles, the players involved in the game, the entities, etc. The game map will likely be stored in a light database; my current plan is to use sqlite. The data stored on disk will be the game state at the latest turn. The internal data format may very well be version-specific, and not easily transferable. The region map will be generated by reading a template, and deducing flora/fauna distributions, local weather patterns, rivers, mineral deposition, player starting positions, and whatever else I may dream up. Plot: There really isn't much one outside of 'conquer everything'. It's more or less up to server owners and players to decide how a game should be played: cooperatively, competitively, aggressively, passively, or trying to reach some custom objective. However, the overall goal is to survive, build, and thrive on the regional map by collecting resources, growing a population, and building infrastructure. Challenges will be managing and distributing resources for each player's population, defending against wild monsters (the main obstacle), surviving in the facing of changing weather (affecting things like crop growth), competing and fighting with other players. Game Mechanics: When a game starts, all of the players get placed in semi-random locations scattered across the map with beginning stock resources and starting characters. Players placed in less friendly areas will be given more to start with as compensation. Characters are the units of the game and they have traits and affinities. Traits are the ability to do tasks more efficiently, whereas affinities for traits are the ability to learn traits faster. Characters build up traits by doing work in the related field, whereas affinities come from the distribution of parent traits and can be temporarily modified by leader traits. Hence as the game progresses, a player's population starts off generalized and progresses towards specialization. For instance the population of characters controlled by a player based in a cold icy biome would naturally specialize in things like hunting and fighting, while a population in a temperate fertile area would have better skills with farming and building. Population growth is tied to happiness of characters. Unhappy and/or sick characters will not reproduce. What raises happiness is: food surplus, access to multiple types of food, good health, pets, high success rates at getting tasks finished, better housing and resources, and access to luxury goods. Game time progresses per turn. My idea is somewhere around 1/100th of a year to 1/20th of a year per turn; I haven't really decided. Turns will have a time limit set by 125% of the time it took for the first person to finish after 50% of the players have already finished their turn. The numbers may be configurable, and minimum and maximum limits may be set. Players that finish earlier have their and their AI's actions committed before those who finish later. Now, there may appear to be a problem here. It would seem that the game would easily get dull and slowed down with long turns that represent a relatively short amount of time in game. It wouldn't be so bad if the turns were much shorter in length, hence the time limits. But there are so many things to get done! Management (The Central Game Mechanic): Well, this is where the main game mechanic comes in: leadership and delegation. So at simple as it can get: a character can do assigned tasks. A task is composed of getting required resources, following a set of steps, and having some end goal done. The internal set of steps can also invoke other tasks. A character does tasks based on priorities. If a character is automated by itself; the priorities are more or less survival. Get food, find/maintain shelter, and that's about it. Enter the leader, who's job is to look at the task lists of the subordinates, figure out the collective needs, and assign priorities to different tasks. Naturally, the next step is to allow leaders to manage lower-level leaders, with the idea that higher level leaders can look at the needs and abilities of subgroups, and shift around responsibilities and goods. Now, information about what subordinate characters need doesn't come free, and doesn't move around instantaneously. For one, either the leader-subordinate must meet in person, or a carrier must transfer over information about a sub-groups needs, resources, and capabilities. Furthermore, characters have very bad memories. So after the lowest level, record keeping facilities will be needed for more advanced and larger networks. Thus, as the game advances and the player's population grows in size and abilities to do new tasks, it'll become important to develop an efficient bureaucracy to micro-manage and leave the higher-level decision making to the player. How the characters are organized into the hierarchy of command is left up to the player; the game itself has no notion of predefined governments or economies. Networking Protocol: The low-level protocol for communicating with a game server is simple. A client sends a command packet in the form of " | ;", and gets a response in the form of " | ; ; ". All text based, so it's possible to communicate with the server telnet. The echo string is predominately for the client's use; the server just spits back the echo string the client sent to help the latter track packets. The server's responses are all in table form, being as a lot of the data the server works with is tabular anyways. The server API are the set of commands, and are bound to their string names during run-time. The API commands also have basic information describing their functionality, as well as their associated parameters. For instance, when the client sends "con|/dat/lsf -d /chat/msg;", it is asking the server to display info on the parameters of messaging function in the chat domain, which is the command that clients use to send text to the server's chatrooms. The server responds with "con|Query:name|letter|minArg|maxArg|minUse|maxUse|info:message|m|1|1|1|1|Message to say:room|r|1|1|1|Chat room for message", which pretty printed looks like:[code=nocode:0]Header: Query+---------+--------+--------+--------+--------+--------+----------------+| name | letter | minArg | maxArg | minUse | maxUse | info |+---------+--------+--------+--------+--------+--------+----------------+| message | m | 1 | 1 | 1 | 1 | Message to say || room | r | 1 | 1 | 1 | 1 | Chat Room |+---------+--------+--------+--------+--------+--------+----------------+ The commands are grouped together in domains, and domains can be nested. For instance, account management commands are grouped in /acc. Admin related commands are in /acc/man, whereas non-privileged account commands for player clients to use are in /acc/log. The server life cycle is more or less to start up, load basic information like command bindings and the account index, load up incomplete games, then sit and wait for incoming packets. Except for time-sensitive jobs, much of the game specific code will be called from the command functions, as opposed to being called directly in the main loop. The client life cycle is to start up, connect to a server, then log in to an account if available. By default, the only permissions newly-connected clients have on the server is to talk in the main chat lobby, log into accounts, and submit tickets to server ops to create a requested account. So playing on a server is white-listed, but connecting isn't. Now onto the permission system. Like the command system, the permissions are nested in a tree of domains. Permissions are granted when there is an entry that matches the command name, or any domain containing the command. For instance, to give an account admin privileges over account management, just add the entry /acc/man. Or to give all admin privileges, just add / to their permissions file. Connected clients not logged into an account get the default client privileges set out in the clientPermissions file. Thus this gives the server operators a good deal of fine-tuned control on customizing who has access to what, while not requiring extra code for each special case. Modding, Scripting, and Extensibility These features will probably not be worked on until after release, and have low priority. The simplest form of modding is overwriting existing commands or just adding new commands to the API. In the future, I may add the ability to load new/overwriting command functions from dll's as plugins. Command binding is already done dynamically, so this isn't a huge stretch to implement. Scripting may be done with a simple interpreter that understands some basic operators (add, subtract, string operations, etc), variables and the table data structure (ed accessing specific fields of a row), flow control (eg for (row in table) {*stuff*}), and calling the API commands. Again, low priority, getting the game playable comes first. But batch-like processing would be a nice touch.
  10. Proper way to sync data to disk?

    There are some really great suggestions here, and I'm very thankful . . . but I don't feel confident about my skills as a programmer to implement a complex and advanced system like effective journalling and recovery. I mean, I probably could find a way to do it poorly, but I'm already pushing my novice skills as is. My focus is more on getting the game finished while having it useable and stable. I've seen how easy it is for a game project to fall into the void of never-getting-finished due to feature creep, and there's only one of me after all.   Now, SQL is something I am a little bit familiar with. Though I'm not too knowledgeable about performance for it, is that something I need to worry about? So far the load I'm planning on supporting is roughly up to 24 concurrent clients/players (hard limit at 64 due to select(), but the more the merrier), and some players can have the server take over for them while they're gone. Also, I'm expecting that there can be many small updates to game data as players plan their actions out.   So my current plan is this. I have two rough sets of data: data specific to a game instance (game data), and everything else (system data). I've already programmed in a good chunk of the system data, and it's all read/written as tab-separated text files. A lot of that data is simple, irregularly changed (ie password hashes), and if corrupted, easy for server operators to spot and fix by hand. Game data on the other hand, is much more transient, sizable, homogenous, and the context may not be as obvious (whereas "name=john_smith" has very obvious context in a client account file). Hence the dual focus on efficient saving, and where data corruption becomes a much bigger concern in diagnosing and fixing. So I may go with a database there, and save the data every turn. If I want to push it, I could copy the game data to new structures after every turn, and then in a separate thread write the old data to disk. But I don't know if writing to the disk will cause the entire process to block, it's also not a subject I'm terribly familiar with. For me, getting it done takes precedence over being fancy.
  11. Proper way to sync data to disk?

    SQlite sounds like a good idea; I'm using a lot of relational data anyways. The game I'm developing is a turn-based strategy game with tiled maps, so there is a lot of data to be stored per player/map, and a game could last longer than the lifetime of the server process.
  12. Hello.   I'm new to game development, and I'm trying to make a multi-player game server. One design issue I've run into is trying to find a fast but safe way to keep server data (account info, game states, etc) and file data synchronized. I thought about just saving directly to the file whenever any internal data structure is changed, but I don't know how much that would impact performance to constantly write to the disk. I also want to minimize the chance of putting the files in an inconsistent state in the event of a crash. Which the current server gleefully makes a hobby of doing.     So what's a good disk I/O strategy to keep the performance decent, the data consistent, and code complexity/size down?
  13. Sending messages in Objective C?

    Thanks. I tried it that way, but then I ran into the problem that I need to use class methods for one to communicate to the other. But I don't know how to set any variables using class methods, and I don't know where the instances (I assume the framework is creating them) are.
  14. How am I supposed to send messages between classes in different files? I've got a controller for intercepting buttons to change the screen's colors, in "MyColorController.m," and an associative header. I've also got a controller for an OpenGL screen in "myOGLview.m," which also has a header. My goal is to have this flow: Step 1: User presses button Step 2: MyColorController sets it's own color value according to buttons pressed Step 3: A miracle happens, and myOGLview class some how gets the new color Step 4: myOGLview draws a simple flat shaded rectangle Steps 1,2, and 4 are all accomplished, I know how to do that stuff. But I can't get step 3 to work. According to the "MyColorController" files, the other files don't exist, and vice versa. Global variables don't work. And everything I google tends to pull up stuff I already know or don't need to know for the moment.
  15. Counting lines of source code using Bash?

    Quote:Original post by Null and Void Quote:Original post by Mitchell314 fileSize=`wc -l < $thisFile` echo "$thisFile has $((filesize)) lines of code" I get a result of 0. The file exists, and I can see the number of lines within a file, but I can't manage to get the result into a variable. BASH is case-sensitive. fileSize=`wc -l < $thisFile` echo "$thisFile has $fileSize lines of code" Ouch. I'm an idiot. The sad thing is that I knew it was case sensitive. Thanks. This will help a lot.