Jump to content

  • Log In with Google      Sign In   
  • Create Account

Awesome job so far everyone! Please give us your feedback on how our article efforts are going. We still need more finished articles for our May contest theme: Remake the Classics

Ravyne

Member Since 26 Feb 2007
Offline Last Active Yesterday, 01:28 PM
****-

#4780767 Am I thinking right OO way?

Posted by Ravyne on 01 March 2011 - 06:19 PM

You shouldn't need an enemy class. Since the enemy and player are BOTH paddles. If you really want to put the AI in a class, make Paddle a base class and inherit from it. Make a

Player:Paddle(){}
and
Enemy:Paddle(){}


Good observation, wrong conclusion.

Inheriting player and enemy from Paddle violates the spirit of the Liskov Substitution Principle (that is, neither the player nor the AI *are* a paddle) and composition (both player and enemy *have* a paddle) would be a better pattern to apply.

As a general rule, composition should be preferred over inheritance whenever inheritance is unnecessary. Here, a properly written Paddle will provide all of the interfaces necessary to control it and query it's state from the outside, so neither player nor enemy should be required to inherit from it in order to control it through overridden methods, rather they can be separate entities who control a paddle.


#4779776 is C frowned upon?

Posted by Ravyne on 27 February 2011 - 01:35 PM

Really? No one's said this already?

You'll have to be able to code in whatever language the boss tells you to.


Focus on being a good, language-agnostic programmer. If I claim to be a chef, but I can only work with a particular brand of oven/stovetop, I severely limit my utility in a restaurant setting. No one's going to change around their entire kitchen to suit me, especially not when what they have in place already works for them. If you're content running your own small restaurant, where you get to decide the equipment, then you might be fine, and likewise, if you manage to be in charge then you might get to influence the equipment purchases (but, you still have to consider what skills are available in your geographic area).

Practically, this means being a good problem solver with solid understanding of CS fundamentals like algorithms, data structures, etc. It probably also means that you've had moderate exposure to at least 2, and probably 3 or more, programming paradigms (not just different languages) and a sampling of languages.

For security work, you probably want to know at least one systems language such as C, C++, D or Go, as well as assembly, probably x86/x64 now, and ARM in the near future.


I've recently mused over what 5 language technologies I would choose, if those were the only languages I could learn. Mine are:
  • D (because it's a multi-paradigm systems language with rich meta-programming support)
  • Scala (because its a nicer language than Java, and runs primarily on the JVM (but also on .Net) -- its a good applications language.)
  • JavaScript (because its a dynamically-typed scripting language that supports functional programming, and the only mainstream language with prototypical inheritance (which really suits scripting))
  • SQL (because you need to know how to query and build large data sets)
  • XML/XSLT (because sometimes markup is a good solution, particularly for data interchange).
My choices are my own, of course -- so you might read that as "a systems language, an applications language, a dynamic scripting language, a query language, and a markup language) -- but I've chosen these specific languages myself due to a combination of distinct application as well as the breadth of paradigms that are represented between them and having that breadth makes you a stronger programmer all-around.


#4778793 video on x86 code optimization

Posted by Ravyne on 24 February 2011 - 10:43 PM

The content was quite good and too the point, with very clear examples.

Will you be covering how to effectively use the memory hierarchy as well (a'la data-oriented design)?

What else is planned to be covered in more depth?


#4773199 Opinions on my 3D vector class

Posted by Ravyne on 12 February 2011 - 12:13 AM


Vector3 operator+(Vector3 lhs, Vector3 const &rhs) // Note that 'lhs' is passed by value, this is intentional.
{
  return lhs += rhs;
}


Why? To save a temporary? Just asking


Well, first and foremost, by using this pattern of implementing '+' in terms of '+=' (and similarly for the other operators) you reduce the amount of redundant code, because the act of adding a vector is now only defined in one place. It also has the benefit (and this is where the increased encapsulation I mentioned before comes in) that it reduces the footprint of functions which have direct access to your class internals (since I recommend everything be public because there are no invariants to maintain, it isn't increasing encapsulation in this case specifically, but it does whenever you have protected or private member variables or functions).

As to the operation of the above quoted code, yes, the gist is that you can save some temporaries by doing things in this way -- a good compiler doesn't always need to see this pattern to recognize when the return value optimization can be applied, but the above is generally recognized as most-likely to cause RVO to be induced. Plus, we get all the benefits mentioned above. Specifically, what happens above is that 'lhs' just gets re-used as the return value object, which would otherwise be constructed (and possibly copied, IIRC) at the point of return typically. The form above just makes the pattern very explicit and leaves no wiggle room for the compiler to get it wrong.

But, the important thing is that its not just better code, and not just (potentially) faster code -- its both of these things at once; a rare opportunity that should be grabbed when presented.


#4773105 Opinions on my 3D vector class

Posted by Ravyne on 11 February 2011 - 05:16 PM

Don't return by const reference, just return by reference.

Accessors (GetX, etc) are pointless here, since you're not maintaining any invariants. just make the stuff public.

The static methods (Add, etc.) are of dubious merit, at best.

// Binary functions should (arguably) be implemented as non-member
// functions rather than member functions.



I wouldn't say this is arguable. It increases encapsulation -- however, to do so they must be non-friend in addition to non-member. 'friend' actually creates a stronger relationship than even inheritence, its basically only one step down from making everything public.


You should only need to implement the self-modifying operators (*=, /=, +=, -=) as member functions. With this, their non-modifying counterparts can be implemented in terms of their self-modifying counterparts as free functions within the same namespace -- They are every bit as much a part of the class as non-modifying member functions as you have now (Due to Koenig lookup), but better for encapsulation. It also enables the Return Value Optimization.

As a member function:
Vector3& operator+=(Vector3 const & rhs)
{
  this.x += rhs.x;
  this.y += rhs.y;
  this.z += rhs.z;

  return *this;
}

As a non-member, non-friend function in the same namespace:
Vector3 operator+(Vector3 lhs, Vector3 const &rhs) // Note that 'lhs' is passed by value, this is intentional.
{
  return lhs += rhs;
}

If you want to enable SSE, you'll want to align your data and wrap it in a union with __m128 or a similar construct.

Also, SSE shouldn't be used for everything -- a simple vector add might actually be slower in SSE, due to the need to set up for SSE first. One place you will want to use it is when transforming a batch of vectors through a matrix -- SSE2, IIRC, can optimize this from a ~100 cycle per-call cost, down to 20 cycles per vector, amortized over any reasonable number of vectors, and down to 17 cycles for the common cases whereing the homogenous W component is set to 0 or 1 (vectors or points, respectively).


#4771669 Review my resume

Posted by Ravyne on 08 February 2011 - 08:03 PM

Objective:
Drop "I am" in general -- More to the point, consider customizing your objective to each specific position, at least those that you are more excited about. Also, word it in a way that displays enthusiasm but avoids "this is what I want to get  out of it" -- Companies don't care what you want to get out of an internship, so focus on what you want to do for them instead.

Programming Languages and Libraries + Tools:
Roll this all into a "Skills" section -- remain general as to not pigeonhole yourself, but its OK to mention specific examples for illustrative purposes: "Experienced in industry-standard IDEs such as Visual Studio and Eclipse."

Related Coursework:
Cut this back to stuff you're extremely interested in, or extremely good at, mentioning work you've done with it. Somewhere, perhaps in the Education section, mention where you currently are at in your education -- that will give them a good enough idea of what general CS topics to expect you to have some familiarity with.

Related Experience:
There are some wording issues here: "Integrated C++ program with Java to make it online based." English may not be your native tongue, though you seem to have a fair command of it, just be careful. If in doubt, ask someone else how they would say what you're trying to convey. Also, that particular example is vague -- How did you integrate the two? What online features were enabled by your efforts?

Other work history:
I can take it or leave it -- generally an employer won't care about unrelated experience, but since you're a student its not unexpected to see this, and having been a cashier (with references available) at least speaks to the fact that someone in a business setting found you trustworthy -- If you've done this job part time during college or high school, consider mentioning that (if you don't cut it entirely) because that will speak to your ability to manage your time and responsibilities.

Honors:
Who is the Mayor of Connecticut? Did you mean Mayor of a town or City, or did you mean Governor/senator or some other official? Be sure that the title of the award is exact, and include the year you were awarded.

Interests:
Dump basketball unless it was collegiate-level.
Consider dumping languages (Neither Nepali or Hindi is likely to be much use, the space is better spent elsewhere.)
Be specific about tutoring topics, and if you have any success stories, share. If you helped little Timmy go from a C student to an A student, it might be worth mentioning, but only if there's proof.


#4770046 Is Method Chaining a Best Practice rule?

Posted by Ravyne on 05 February 2011 - 11:23 AM

It can also be a powerful tool for crafting DSLs (Domain Specific Languages), for example Linq in the .NET world is built on this pattern (there is the nicer, sql-like syntax, but it just translates to something similar to the named parameter idiom -- that is, a chain of method calls -- which you can use directly also). I used the same pattern to build predicate expression trees from a small language. Code looked something like this:

Boolean result = (Record(n).Field("name").BeginsWith("foo")).And(Record(n).Field("size") < 12);

The expression trees could be built to any size and depth easily with a simple recursive-decent parser.

Now, you can certainly abuse this idiom, and I would say that favoring it over a void return type "just because" is certainly abuse in my book. It's also worth mentioning that languages that support named parameters can go a long way towards relieving the need for this idiom. Also, you might consider implementing it for construction not on the object itself, but on a separate object which describes the object you want to construct. Then you simply create one constructor on the first object which takes the second "descriptor" object as its sole parameter.

You'd end up with code looking like this:

File f = File(FileDescription("foo.txt")
                .readonly()
                .createIfNotExist()
                .appendWhenWriting()
                .blockSize(1024)
                .unbuffered()
                .exclusiveAccess()
);


Then you're not cluttering up the object itself with all these pointless methods (though it may expose analogues in other ways when appropriate).


#4768921 Console Advice

Posted by Ravyne on 03 February 2011 - 02:05 AM

Would just using DirectInput's KEY_DOWN function that fills a data structure for all the keys of the keyboard be sufficient for the full keyboard input or is there a more efficient way?

I already have a method for rendering the text.


I may be wrong, but I believe that these types of functions usually are just giving you a state that represents whether a key was pressed or released since the keyboard was last poled -- or, perhaps it does work off of keydown/keyup type events, but that this information is lost. For game input, you normally don't care so much about the order in which keys were pressed or released, as long as we're within a single frame. Obviously, for typing text the order of presses and releases is very important. I imagine you'll need to hook into the key messages as they occur. Direct3D may provide this functionality in some form, but I don't think so. Other frameworks (SDL, SFML, etc) might provide it... I'm not familiar with either. Worst-case scenario, you should be able to tap into the Windows Event system to process the messages in order.

Is there a sort of tutorial around for how to build a tokenizer? I get it a fair bit, but I'd probably mess it up trying to build it. What specifically is a token? An array of characters? And for the parser too? I get the parser more than the tokenizer though.


Any book on writing text processing, scripting languages or compilers will treat tokenizers extensively. A Google search for Tokenizer/Tokenization should turn up good info. Also, Tokenization almost always shows up as a sort of preamble to any resource on parsers or parsing -- mostly because tokenization is a necessary step to parsing, but doesn't do much good on its own.

Tokens themselves are very simple creatures. At the bare minimum a token is simply a string which contains text from a larger string. The token string was simply singled out from the larger string as being some kind of cohesive "thing" (a word, a number, a quoted string, whitespace). Usually though, you want to take advantage of the fact that you've figured out what category of "things" it belonged to already, so you store that along with the string so you don't have to figure it out again later; we call this the token's "type". So there you have it, a token is just an object that contains a type and a string. Sometimes people will optimize for space by only including the string only if the string cannot be inferred directly from the token (eg, if you have a token who's type is 'COMMA', then you can simply assume that the string is ",", rather than storing it every time you parse a comma.), but this is an optimization. Get things working first before you worry about a few lost bytes here and there.

Lets assume we've defined a tokenizer that recognizes words, numbers, quoted strings, and whitespace. As part of that system assume we've included std::string, and that we've defined the following types:


enum token_type_t {
  EOF,           	// End of File
  WHITESPACE,        // Space, Tab, Return/Newline
  WORD,              // any contiguous characters that are not EOF, WHITESPACE, NUMBER or inside a STRING
  NUMBER,            // any contiguous digits
  STRING         	// any characters, digits or whitespace between quotation mark pairs
};

struct token {
  token_type_t type;
  std::string  text;
};


If we turn our tokenizer loose on the string ["Holy Cow!" That's more than 100!"], we would get a list of tokens back like this:
<STRING, "Holy Cow!">
<WORD, "That's">
<WORD, "more">
<WORD, "than">
<NUMBER, "100">
<WORD, "!">
<EOF, "<whichever code represents EOF>">

Finally, if you're willing to invest in a book, I've been reading a book called "Language Implementation Patterns" which covers several different techniques for tokenization, parsing and beyond (the book itself addresses creating scripting and programming languages, so it then goes into managing scopes, typing, intermediate representations, analysis, optimization and code generation) -- its more than you need for a simple developers console, but it is quite exhaustive of the parts you do need and is also quite approachable. If you were instead to pick up a book on creating a compiler, you would find that they soon become lost in a world of grammars, state-machines, graphs, etc... Useful stuff, but stuff that would get in the way of a relatively simple goal in your case.


#4768829 Console Advice

Posted by Ravyne on 02 February 2011 - 07:42 PM

Over the past week, I have been trying to build a developer console to learn just how to do it (and I didn't know if there was any other method than to build one in-house). But, as I got farther and farther into it, it got more convoluted and confusing and I'm starting to wonder if there's a better way to do it.

So, what I want to ask is: is there any DirectX, Windows or something similar like a function that will be a good way to manipulate text? Or is there a tutorial on how to build a developer console?

Basically is there any better way than building the developer console in-house or is that the only way?


There really shouldn't be anything that difficult about it.

You'll need:
  • A way of getting full keyboard input.
  • A workable solution for text rendering (there are many).
  • A means of tokenizing the input strings.
  • A means of parsing the token stream.
  • a means of executing the parsed commands.
The tokenizer is fairly straight-forward, basically you scan characters left-to-right, taking as many characters into a "token" as are in the same category (letters for words, digits form numbers, strings are anything between two quote marks, etc) -- then you record the type of the token (word, number string) paired with its string value (repeat, 4, "Hello, World!"). Regular expressions are extremely handy here, even for grammars of a fairly complex nature... Regex should be capable of tokenizing any grammar where the the type of a token cannot be affected by preceding tokens.

The parser is the most difficult, but I would say that most interactive console commands can be parsed with a simple recursive-decent parser. Basically recursive-decent parser looks at one token at a time, in order, and determines the next set of possible tokens based on that -- if the next token isn't one of the expected ones, its an error. The way you'd probably structure this in a console is defining the set of global command tokens (things your console can 'do', sometimes you call these verbs in grammar parlance), and each of these has its own parse function which is handed the token stream and consumes as many tokens as it needs, according to its own rules -- in other words, the "repeat" command from above knows that it should consume a number, and then a string. If it finds them as expected in the next two tokens (order counts) then it takes them from the token stream and has all the information it needs to execute the command (usually, each command has a native-code function to perform its action) so you do any last necessary conversions (string of a number to a real number, for example) and call that function and return. You might also need to pass in a console context implicitly to each of these native code handler functions so that it can print to the console, or perhaps read state (variables) that have been set in the console. If at any point a command finds a token it doesn't know how to deal with, then there's a syntax error in the command.

There are systems for generating tokenizers and parsers, however they are often non-trivial to learn, and most of them spit out vanilla C code littered with gotos and non-sensical labels and variables. For large or complex grammars, the learning curve can be a worthwhile investment. But I don't think there's much value in them for anything that can be handled by a simple recursive-decent parser -- its probably just as quick to build one by hand than to use the tools, so unless you plan to make a habit of using the tool I wouldn't recommend learning it.

If you do deem it of sufficient necessity (or curiosity) then the typical tools are lex/yacc, flex/bison, Boost::Spirit and ANTLR among many others.


#4765320 Creating file extension similiar to .viv or .big (or almost rar)

Posted by Ravyne on 26 January 2011 - 05:05 PM

Zlib looks good, but i have a Q. Can i access files in real-time or i need to "extract" them to read?


Actually, it even tends to be faster in many cases -- since reading from disk can be quite slow it can actually be slower to read more raw data from disk than to read less compressed data and decompress it. Make sense? The CPU is so fast at decompressing stuff that it frequently sits around waiting for more data from the drive. This is probably less and less true now with SSDs becoming more common, but it is definitely true of optical discs, and presumably even of fast magnetic hard drives -- pretty much any recent console game is doing this now and you've never noticed, so it's more than fast enough for production use.


#4765169 Creating file extension similiar to .viv or .big (or almost rar)

Posted by Ravyne on 26 January 2011 - 12:35 PM

Hi, can someone describe etc. how to create (in c++) file extension similiar to EA's .big or .viv (in one file can be stored multiple files, like in .rar) because loading one file is faster than thousands of them.
Thanks.


In three easy steps --

  • Open file.
  • Put a bunch of stuff in it.
  • Profit?
Seriously though -- that's basically all it takes. The only difference from a normal file is that you have to have some way of identifying individual items out of the jumble of bits. Generally you'd do this with some sort of header that lays out where things are and gives each item some sort of unique name. You can do this as a "flat file" of sorts -- where every item exists in the same "directory", or it can be hierarchical where you can organize items into subgroups recursively, just like your typical OS file system. In fact, reading up on how various file systems work would be a good idea, just to get your head around how this sort of thing works -- you won't need to worry about low-level issues such as chaining disk clusters together, of course (at least not on a hardware level), but the high-level idea is essentially identical.

From there you can add features like arbitrary metadata, compression, etc.

The easier path, though, would be to simply leverage zlib using the optional password protection (if you're worried about your resources being cracked -- not that you should because they can *always* be stolen, no matter what you do.) Depending on how you intend to use your data you might also consider something like SQLlite -- but something like zlib, or a custom solution, is probably what you want for typical game content.


#4750330 IDE without WORKSPACES/SOLUTIONS

Posted by Ravyne on 24 December 2010 - 04:16 PM

Honestly, I think you're probably the only one looking for a "solution" to this "problem". For short, throw-away code it may seem a bit over-engineered, but no one writes real code like that. Every "real" project you undertake might legitimately require different setups -- one project might like version 1.21 of boost, and another might like 1.35.

As others have said, there are tools to help make things easier, you just need to learn to wield them. I wouldn't seriously recommend forgoing all the wonderful Visual Studio Features in favor of some spartan IDE where you don't have to click "new project" every now and again. Seriously, how many new projects are you creating anyhow? Is this really a bottleneck for you?

Another possible solution is to create new test projects within a test solution -- You ought to be able to configure many, if not most/all things at the solution level, IIRC, and the projects will inherit.


If you think this is bad, try setting up an embedded systems project in eclipse with a JTAG debugger and a third-party plugin to deploy code to the hardware over a serial connection. The first time took me two hours with a 30-page document. Even after practice it still takes 20 minutes or so every time I start a new project.


#4748107 [web] SQL vs PHP

Posted by Ravyne on 19 December 2010 - 02:29 PM

You seem to be muddling up your technologies -- SQL and PHP are two entirely different technologies which do entirely different things. You may have applied PHP to get similar results to what you might have done with SQL, but they are not fundamentally opposing technologies.

By your description, it seems you've used PHP to implement a web page which retrieves data dynamically from your own collection of formatted files residing on the server. What you've essentially done is create a database of sorts, of your own design and implementation. You could just have well have implemented the same PHP-based page, but using SQL to store and retrieve the data.

SQL itself is not necessarily the be-all, end-all of data storage (in fact, non-relational databases like CouchDB have become quite popular in some applications as of late) but you should prefer to adopt established systems over your own one-off solution unless your solution provides a compelling difference to, and advantage over, time-tested solutions such as SQL.

Here are a few advantages something like SQL has over your one-off solution:

1- Its proven. SQL has been deployed in 10s of thousands of applications.
2- Its scalable. SQL databases scale in size to billions of rows. Try doing that in a text file.
3- Its fast. Its been the life work of many very smart people to build SQL engines such that they optimize their search strategy to perform queries optimally. There are probably hundreds of man-years invested in optimization alone. You should take advantage of that.
4- Its distributed. Your SQL database can be run on another machine, or cluster of machines, when your data access needs outgrow a single machine.
5- Its free. There are plenty of good, free SQL servers available -- everything from SQLlite to MySQL. If time is money, then using one of these systems is actually the cheaper alternative to rolling your own.


Now, something like SQL isn't always ideally suited to every problem -- non-relational databases might be better, even flat text files or binary files could be better in some situations, its just a matter of determining what fits the need -- but if something like a relational database can be made to model the data in a reasonable way, then the advantages surely outweigh the cons 95% of the time.


#4393472 Make Games, Not Engines?

Posted by Ravyne on 31 January 2009 - 08:32 PM

So, you've seen that piece of advice around the forums, have you read the blog from which the advice originates?

The topic came up earlier today in this thread. Inside you'll find a link to the original piece, my summary, and a follow-up from the original author.

The original article is a good read, unfortunately the title makes a good sound-bite, but doesn't fully convey the meaning of the article.


#4393408 Write Games, Not Engines

Posted by Ravyne on 31 January 2009 - 03:49 PM

I think the primary point the article was trying to make, and Josh can come along and correct me if he likes, is that its far too easy to get bogged down with creating your perfect, infinitely extensible game engine; so much so that, well, you never get around to actually writing the game. The second point, is that it takes a good deal of experience to write an engine, because until you've written several games, you haven't written enough code to find the common threads, let alone to extrapolate those threads into new technology for a game that's not even properly designed yet. Its like taking a hike with no map or compass, and assuming the path you've chosen will take you to your desired destination.

The article does not expressly say "Don't use an engine", nor does it advise you to "never write an engine". Its really advising you to have the humility to recognize when you are not yet ready to write an engine up-front, and to be sure of the requirements of your game and that you are writing code to fit the game, rather than writing some misshapen code and then trying to shoehorn your game into it.

Go ahead and use an engine if you like, exposure to an established engine will be enlightening -- though be careful to view it realistically. Every engine has things it does well, and things it does not so well. Under no circumstances should you take an engine like, say, OGRE or even a commercial engine like Unreal Engine 3, and assume its construction is doctrine.




PARTNERS