Jump to content

  • Log In with Google      Sign In   
  • Create Account

Interested in a FREE copy of HTML5 game maker Construct 2?

We'll be giving away three Personal Edition licences in next Tuesday's GDNet Direct email newsletter!

Sign up from the right-hand sidebar on our homepage and read Tuesday's newsletter for details!

We're also offering banner ads on our site from just $5! 1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.

Dave Weinstein

Member Since 08 Mar 2006
Offline Last Active Yesterday, 07:59 PM

#5165165 I've got problems with interviews

Posted by Dave Weinstein on 06 July 2014 - 07:45 PM

I cannot imagine ever hiring for a programmer position without having the candidate white board one or more programming problems.


I say this, because I've been the "technical interview" for people being hired in as programmers who really were not at all qualified. The resume looked great, they absolutely nailed the "let's talk about process, and how we work together" process interviews, as well as the "let's talk about programming without actually doing any" interviews. And then I asked them to whiteboard, and they absolutely cratered.


One of the questions I used to use when looking at candidates who listed on their resume a proficiency with C/C++ was a simple opener. 


Please implement this function:

/* Implement a simplified version of integer to ascii, supporting only base 10, and assuming a 32 bit value on a 2s-Complement architecture */
char * itoa(Int32 value)

This is not a hard question per se (as with most of my interview questions, I stole it from questions I was asked in an interview). There are a couple of ways to approach it, and while there is a corner case, I don't hold missing it against the candidate. Getting it on the other hand is a bonus. Mostly, I want to see you approach the problem.


And yet, one candidate confidently wrote this:

char *itoa(Int32 value)
   return (char *) value;

Not only did he confidently write it, it took a fair bit to convince him he was wrong. Even with a lot of prompting, what was supposed to be the first 15 minutes of the interview took the whole hour, and he never did get the problem solved.


And that is why I'll always want anyone being hired for a development role to actually write code as part of the interview. Because I've *seen* people with the right resume say all the right things, and flunk the ability to actually write anything. I no longer assume "basic coding competence".


[As a side note, having been on both sides of whiteboarding questions, it is *always* easier to spot the bug while you are sitting there watching them write. That's why the interviewer always seems to have a laser focus on the bug when you haven't seen it. As a candidate, as soon as you finish writing it down (and you should talk about what you are doing and why as you go), say something to the effect of "Now to step through this and look for bugs", and out loud start debugging what you wrote with example cases.] 

#5089058 Data compression/optimization strategies

Posted by Dave Weinstein on 25 August 2013 - 09:40 PM

The most compact data is the data that you do not send.

Work very hard on not sending data.


This, this, a thousand times this.


The art of multiplayer game development is knowing what not to send, and how often to not send it. That is where the craftsmanship comes in.


Connecting machines together with well defined APIs is not a difficult task. Basic housekeeping tasks like matching up network ports and game identity are not hard things to master.


There are two arts to master. One is how to hide or design around latency (since if you have a work-around for the speed of light, you have bigger fish to fry). The other is how to maximize the efficient use of bandwidth. The former is fundamentally a design issue (although technological mistakes can make it worse). The latter is fundamentally an engineering issue (although design mistakes can make it worse).


If you aren't making sure your networking and game architecture makes it easy for the network developers to easily route traffic such that nothing unnecessary hits the wire, all of your bit packing efforts are fundamentally just optimizing a bubble sort.

#5083411 Game server DoS / DDoS mitigation strategies?

Posted by Dave Weinstein on 05 August 2013 - 08:28 PM


 I've dug deep into cryptography to design a protocol which I feel fairly confident in. Mostly because it's basically an implementation combining two well known protocols. Still, I know it's a risk.




Don't do this.


Seriously, this is a bad idea.


Either use a well known cryptographic solution, which has been subject to peer review, or, if you are a cryptographer, and you see a need for a new approach, publish a paper on it, and if the paper holds up after a few years, then use it.


But rolling your own cryptography almost inevitably leads to a much much worse outcome than using something that has actually been subject to peer review.

#5075159 More of a security type question.

Posted by Dave Weinstein on 03 July 2013 - 07:34 PM

That's a really really bad idea.


If you want to download executables off the network for updating, you're going to need to strongly sign them, and then have the installer (and auto-updater) verify the signature of the executable on download.


Copying it off of a random network share is just unwise.

#5074060 Unity Network.Destoy problem.

Posted by Dave Weinstein on 29 June 2013 - 10:16 PM

So I guess Unitys built in networking is completely useless for any serious project? Guess I'll have to switch to Lidgren.


Every networking scheme has exactly the same vulnerability.


If the Client isn't supposed to be able to destroy an object, you need to block that functionality at the Server.

#5073388 Client/server movement when to update?

Posted by Dave Weinstein on 27 June 2013 - 04:54 PM

Send MoveStart and MoveStop the frame they happen. Limit MoveUpdate to a 10hz frequency. Combine all movement updates sent in a given frame into one packet.


That should give you decent baseline performance, and you can tune from there.

#5068261 Scalability issues (UDP)

Posted by Dave Weinstein on 08 June 2013 - 11:43 AM

The art of the network engineer is knowing what not to send, and how often to not send it.


So, first, look for everything that can be inferred by another piece of information. If a specific gun firing always generates the same sound, and you know what gun the actor has, then you don't send both a FireGun message and a PlaySound message, the one is inferred from the other.


Next, measure. What packets are you sending the most often. Optimize these down to as compact a form as you can.


Next, throttle. If you send a change of direction packet for the player every time their vector changes slightly then human mouse interactions are going to generate a lot of unneeded traffic. So for an FPS, you want to send an updated movement packet (here is my facing, position, speed) at a throttled rate, with exceptions for things like starting and stopping which will be really obvious if held.


Then, affinity filtering. Send information based on what they need to know. In the original Rainbow Six, every actor in the game had its position updated in the game over a reliable channel to all players on a 1 hz strobe. However, if another actor was in the same room, in an adjacent room, or there was a line of sight relationship (these were cached by the engine anyway), you would get unreliable updates (throttled as above) for them as movement changed.

#5067720 Handling Messages

Posted by Dave Weinstein on 05 June 2013 - 04:30 PM

The approach isn't wrong, but it is inherently more dangerous than a switch statement precisely because of the risk of an out of bounds index to a function pointer table.


If you get a switch statement wrong, it will do the wrong thing. If you get a function pointer wrong, it will do an arbitrary thing, and in this case, arbitrary is exactly what an attacker is looking for.

#5057645 Beginner Packet Encryption

Posted by Dave Weinstein on 28 April 2013 - 10:54 PM

So, XOR is meaningless. Really, seriously, honestly, you might as well ROT-13 it, meaningless.


Here are some basics on cryptography for data-at-rest.

One, don't write your own. Just don't go there. Get a tested library, use that.


Two, in an ideal world, you want to be able to swap out your crypto algorithm if a problem arises in it. So your code shouldn't be deeply tied to the cryptographic routine you are using. This is generally termed "crypto-agility".


Three, salts and hashes. So, a cryptographic hash is a one way conversion. You take a value (say, a password), and you generate a hash of it. In order to get the original from the hash, you would have to just generate values until you got one that matched the same hash (more on this later). You then store the hash in your database (so you never keep the actual plaintext of the password in your database). A salt is a value that you derive deterministically from the account (whether it is intrinsic to the account or simply a random value stored with the account) that you add to the password before hashing it. What this does is mean that if Bob has password "123456" and Alice also has password "123456", they still have different hashes in your database. Otherwise, if I hash "123456", I can immediately get every account that used that password. On the other hand, if I get your database, and I want to get Bob's password only, it doesn't make a difference.


Which brings us to four, hashes continued. Counter-intuitively, you want to use *slow* algorithms for hashing when you are picking your algorithm. The reason for this is that you can afford the extra time to hash a password on login, but you make it much harder for someone to brute force things. Remember how we said you'd have to algorithmically generate strings until we got our hash again? That's why you want a slow algorithm (ex. bcrypt).


Now most of what I just said only applies to the password.

Storing other information is also important, and can have real legal repercussions depending on where the servers are located (for example, if you were suddenly running on a server in the EU, you fall into EU privacy laws), and if you start dealing with Credit Cards you have all sorts of contractual headaches about data storage. The easiest way to secure data is not to have it, so always consider whether or not you need a piece of information at all.


If you are storing it, consider what parts of your server actually need it, and when, and keep the data encrypted at rest. You may want to have the service that actually needs that information on a separate server (one that doesn't handle the untrusted input that is user interactions on a regular basis), such that even if someone were able to get control of the game server, they wouldn't be able to pivot to get the user information.


And finally, I am not a cryptographer. It is entirely possible that I made an error, especially since I'm just jotting this post off, and I'm certainly not a lawyer.

#5051404 Starting the multiplayer part of game

Posted by Dave Weinstein on 08 April 2013 - 10:52 PM

"You can't put multiplayer in at the end. You can try, but you'll end up discovering you put it in in the middle."


(If I could accurately remember the sourcing on that statement, I would cite it)

#5050749 Education-related questions from a beginner.

Posted by Dave Weinstein on 06 April 2013 - 08:57 PM

There are two issues here.


First, you have to develop the programming skills that will allow you to succeed as a professional programmer.


Second, you want to get into the game industry.


Clearly, you do not need a degree to develop programming skills. However, a good college program may well be the most time efficient mechanism to get those skills; one of the drawbacks of being self-taught in anything is that by definition you are learning from someone who doesn't know what they are doing.


So, one way or another you need to develop professional grade skills. Could be a college program, could be the various online free college courses, could be sitting down and just working through it and reading a lot as you go.


Which brings us to the second issue. I'm assuming you actually want someone to pay you (since if you were doing it entirely on your own you wouldn't be worried about finding a job).


So, here is the problem. Games are one of the few  parts of high tech (if not the only part) in which there is a glut of entry level talent. And the thing is, there isn't a simple "do this, then do that, then do this other thing, yay job!" list to give you. People get jobs without degrees. People get jobs without prior experience. People get jobs without demos. None of that helps you unless you are one of those people, and if you were, you wouldn't be asking this question.


It is entirely possible that last year a studio in your area hired someone who was almost exactly the same on paper as you are today. That doesn't mean you'd get a job there today, maybe another studio had a layoff and there are now people with professional experience on the market. It is entirely possible that the person tossing your resume in the trash bin had inferior credentials to yours when they got in to the industry. None of that matters.


If you really, seriously, truly want to get in, and you want to get in as a pro, you need to come across as the best qualified person for the job at the time they are making a hiring decision. For entry level, you want to have a degree, references, good networking, and a great demo or demos. Also, you want to be lucky.


So, do you need to go to College? No. But you do need the skills. And if all the programming you've ever done is some HTML, it is likely that formal instruction will get you the skills in a shorter amount of time than doing it on your own. Also, a good CS degree will help you if (as is likely) you end up leaving the game industry before you leave the workforce.

#5050060 Game Server security

Posted by Dave Weinstein on 04 April 2013 - 01:23 PM

Divide the problem into two areas.

Cheating issues are in general threats to game integrity. If someone has a wall hack, or a teleport cheat, or has found an item-duplication bug in an MMO, these are threats to the integrity of the game as a game, but not to the security of the server itself.

Security issues are those in which an attacker has the ability to control the server (whether by running arbitrary code or simply causing the server to be unavailable).

I'm going to completely ignore game integrity issues in this post.

Picture a Venn diagram of two circles. One is "Specified Server Functionality", the other is "Actual Server Functionality". The area that is in the first circle but not the second is an easily quantifiable bug. "The quest is supposed to end when I have recovered the McGuffin, and it doesn't".

What is more interesting is the case where instead of failing to execute specified behavior, the code executes behavior that wasn't specified one way or another. This is (in general) where you are going to find your security bugs.

The best way to find networking security bugs is to use a tool called a fuzzer. A network fuzzer will generate large amounts of deliberately malformed data, and monitor the server for failure. Especially since you already know C#, I'd recommend getting a copy of Peach 3 (it's free), and setting up a network fuzzer against your server.

The goal is that fuzzing should do nothing beyond generating your *designed* "hey, I got an invalid message" behavior. Anything else is a problem.

#5046976 Client - non dedicated server architecture

Posted by Dave Weinstein on 26 March 2013 - 12:10 PM

You need to be clear on your terminology:

Peer-to-Peer is a network architecture. You are discussing a client-server architecture, so there is no "peer-to-peer" here.

Dedicated server versus server-with-local-player is an implementation issue.

Consumer-hosted versus Publisher-or-Developer-hosted is a business model.

If you have a lobby server or master-server list in the clear, it can do NAT tunneling for you, so there is no need for someone to have a firewall setup correctly.

#5044263 Sending structures through UDP sockets

Posted by Dave Weinstein on 18 March 2013 - 10:57 AM

That usually flies in the face of object oriented programming in many ways , but if you MUST have the speed to make the game work the choice is simple.


Direct binary "globbing" makes sense for level-load, where seek time can kill you.


But the amount of time spent unpacking game messages is a rounding error on a rounding error of your frame rate; you are better off making the code readable and maintainable. Moreover, for network traffic, you are going to have to validate all the messages anyway, so you don't gain even that minuscule speedup



#5042476 Multiple Sockets Per Client

Posted by Dave Weinstein on 12 March 2013 - 04:18 PM

Rainbow Six and Rogue Spear used a hybrid TCP/UDP model for networking.


All combat traffic and a reliable movement strobe (1hz for all entities in the game world) went out via TCP. UDP packets handled interstitial movement packets for entities that were determined to be "near" the player.


There are some distinct advantages to this:


1. Writing an efficient ordered/reliable transport layer on top of UDP is not a trivial task.

2. With an ordered/reliable transport layer you get de-facto delta compression on your traffic. Since the key to network game design is knowing what data not to send, and how often to not send it, this is a big win.

3. At the time, a significant percentage of the player base were still on modems. While the UDP header is 28 bytes versus 40 for the TCP header, with header compression (which is supported on TCP but not UDP for historical reasons), that drops down to 5 bytes or so.


You'll note that the key points there were code complexity and bandwidth reduction. All ordered/reliable traffic (TCP or roll-your-own) has a known issue, which is "hitching". If a packet in the middle is lost, you need to hold the later packets which have arrived until the middle packet has been resent. 


Later generations of Red Storm games (starting with Ghost Recon 2, if I recall correctly) had everything rolled up into a custom protocol over UDP that handled unreliable, ordered/reliable, and reliable-but-unordered traffic. 


The reason had nothing to do with TCP per-se, and everything to do with the change in the consumer environment. By that point in time, a significant percentage of the customer base were behind NAT. It is fairly straightforward (assuming you have a matchmaking service) to bypass NAT over UDP, and impossible to do it with TCP without having the players set up port forwarding for the server. 


With all that, my recommendation would be to find a well-tested library that does what you need over a combined reliable/unreliable protocol on top of UDP, and use that. As a general rule, unless you are a very experienced network developer, you should not be implementing your own reliable layer on top of UDP, it is too easy to get wrong.