Bad Monkey

Members
  • Content count

    400
  • Joined

  • Last visited

Community Reputation

145 Neutral

About Bad Monkey

  • Rank
    Member
  1. Monster Classes

    Two words: data-driven. Not to pick on the personal beliefs of anyone here, but class heirarchies hundreds of levels deep that differentiate SmallGoblinWithTwoWarts from LargeGoblinWithThreeWarts make me want to cry. While the idea of "Animal->Mammal-Dog" style hierarchies works well in the land of academia when trying to demonstrate principles such as inheritance and polymorphism, they tend to be quite painful in real life if you do not take great care in making them flexible, and even then there are just some things that you will find you cannot do (and often not until its very late). As an off-the-cuff example (and prodding poor Joe's nice informative post... no offence meant Joe [smile]), I think a "monster" class is NOT a good candidate for a deep inheritance hierarchy... I just don't see the need to classify them more than one or two levels deep I would tend to stop sub-classifying at a higher level than Joe's example, typically making all "monsters" on an equal level in the tree, and trying to keep the number of abstract sub-classifying levels to a minimum... and focus on making everything more driven by parameters (provided by serialized instances in a file, or passed by calling code, such as an AI agent governing the instance of the monster). Please bear in mind this is totally of the top of my head, and I may recant at any time [smile]... and apologies, but I will be using C#-style syntax and including method bodies in the class definitions... so sue me public abstract class GameObject { // some root class which is often useful for providing functionality such as logging, diagnostics, persistence entry points, etc across many different kinds of game objects... } // class that represents any active unit in the game, whether enemy or friendly npc public abstract class Unit : GameObject { private Avatar avatar; // reference to an object which contains and manages the visual representation of the unit... i.e. model and animation info, textures, etc // any other common attributes that apply to most units private Vector3D position; private Vector3D orientation; private Vector3D velocity; private long hitPoints; private long attackStrength; // etc... // set of virtual methods that are intended to be overridden by your concrete implementations public virtual void Move(...){} public virtual void Attack(...){} // etc... } public class Goblin : Unit { public override void Move(...) { // set the properties governing movement of this goblin according to any special rules you need... } public override void Attack(...) { // select and execute an attack according to current state of this goblin and/or any parameters passed in } // etc... } Again, I apologise that this is such a rudimentary and incomplete example, and sorry if this makes my point no clearer... Anyway, in short: inheritance is way overrated, and should be used judiciously, and data-driven designs (using composition) may very well make extending and tweaking your "monster" catalogue much easier down the track (especially if you can make it possible without having to recompile code Some other ways to think about: - parameterising every possible thing you can think of to do with monsters (i.e. giving them a metric buttload of fields to describe their state and control their behaviour), and have the Unit (or Monster, if you prefer) class methods try and perform actions according to the current values of all these properties. This method requires a LOT of fore-thought as to what your monsters will and will not be able to do, but really opens the game up for tweaking by non-programmers, as all that is required is fiddling of data values rather than deriving from a base class. - write your Unit class to load and run scripts, meaning that again you wouldn't have to derive new classes and compile code in order to come up with new monster types and behaviours. This method would allow for some unseen requirements down the track, but some serious thought has to go into defining the code interface to allow this level of dynamicism. Hope that was some food for thought anyways, and not horribly confusing [smile]... Adam
  2. Experiment with a (real) ant.

    Quote:Have you ever had a cat, or know someone who had one? I mean, a baby cat that only know to "defecate", eat, and wonder around. When this cat grows up, isn't able to play cat-chasing-games, or hunt birds if you let it in your backyard? Where did that cat learn to "behave" like a cat? From TV? ;) Behavior comes imprinted into its DNA, commonly known as instincts. That's kind of like saying that humans are born with the innate knowledge of how to climb trees and catch frogs [smile]... play is all about trying things out to see the consequences and glean information from the experience. The tendency towards different kinds of play for different species (which may evolve into different survival techniques) can be explained by th differences in how the organism is composed (e.g. lack of hands means climbing things or throwing-catching games are less appealing to a cat). Take the concept that cats and dogs don't get along... exmaples of that can be seen everywhere... so explain why my cat and my dog play together, and my cat cuddles up with dog to sleep... where's the "imprinted behaviour" reflecting millenia of animosity between the species? I propose that this animosity is not really imprinted behaviour, but information that was learned by each cat and dog as they came across each other and came into conflict over resources such as food and territory/shelter. Remove that conflict and fear, and they get along fine.
  3. Experiment with a (real) ant.

    Quote:So, HTF do they evolve? Surely it is obvious that the worker ants fill out TPS reports detailing their daily encounters and experiences, which are then collected and evaulated by the higher-ups in the colony... didn't you get the memo? [smile] I tend to think that most "knowledge", other than really basic biological functions, are learned through experience... the only shortcut around this process is to have the knowledge passed on by communication with those who have the experience, be that spoken, written, shown by example, chemical exchange, morse code via antennae, or whatever. A side note: You could probably even say that stuff like breathing (yes, breathing) is a learned behaviour... when you are born, your body stops receiving oxygen from the placenta, you begin to suffocate and cells begin to die at an accelerated rate (a Bad Thing TM), so your body tries things to rectify the situation... how many babies "evacuate" when they are born... maybe because the system consisting of their body and "mind" is going nuts trying to adapt to the new environment and twitching muscles left, right, and centre. Its something you have to learn over a *very* short space of time, but it can still be regarded as learned. Anyway, how feasible is it that ants pass on "knowledge" when they bump into other ants? ("hey, there's a giant lump of sugar back there, and as we know from Uncle Fred, sugar is good", or "don't go this way, coz I just saw Jim and Bob get drowned... I hink large amounts of running water are bad... pass it on!") It doesn't sound right to me that an ant pops out of an egg, and goes "damn, I think I'm off to harvest some grain for the good of our illustrious colony!"... surely there is some form of "basic training" where other ants clue it in on what the hell is going on as it wanders around taking its first steps. Then, as it meanders around the world looking for this "food" thing that someone mentioned, it experiences stuff and finds solutions by experimenting (based on what it knows already), and gets "told" other stuff by other ants who have had their own experiences. Relating to the lion example, and the concept of "play"... isn't this just experimentation based on stuff the cub has learned so far? (i.e. gravity makes me fall, biting hurts things, clawing hurts things, pouncing can get me over that last distance quicker and catch things by suprise, sneaking helps me get closer without things detecting me, etc) ... I am pretty sure they are not born with much more than the ability to eat, sh!t, and move around, so therefore complex behaviours are not magically passed on by genetics... they must be learned, and the learning begins the moment they are alive and conscious... a rampant sampling of data from the world around them to try and construct a set of rules by which they can evaluate their environment and themselves and predict their future. Stuff like this just messes my head up when you start reducing it to really basic behaviours [smile]... but it just feels wrong to draw some arbitrary line and say "everything simpler than x is just passed on somehow"... although I guess that must be the case at some cellular level, I feel genetic information has probably got more to do with setting up an organism so that it is biologically efficient and has the capacity to learn well...
  4. Language for 9-year old?

    Some of you are spruiking about C++, saying "its not that hard", and "don't start with some piss-weak language"... but are possibly failing to take into account that you are speaking with the benefit of years of programming familiarity... we are talking about a totally green little kid here. The peeps pimping something along the lines of LOGO, BASIC, or other languages with less hostile syntax rules are much closer to understanding the nature of what fits this situation best... you don't want to scare the poor little bugger off with what looks to be an alien mish-mash of symbols... at this stage, you want to teach the basic principals or data types, variables, and flow control. If the kid laps it up and wants to wade in deeper, fine... but small steps to build confidence ;) Quote: C macros - C++ templated functions C structs - C++ classes C inheritance - C++ inheritance (this I'm not so sure, but I managed to inherit a struct from struc, so most likely it works). C++ is just safer, with typesafety, rather than what macros use. And namespaces dont really make a difference, if you hate them you can just do using namespace foospace; Ferchrissakes!! Most 9-year-olds couldn't spell half of those features, let alone understand and use them. Quote: Actually, code is read a whole lot more than it is written. Readability beats "writability" any day. Amen, brother Arild :) All you whipper-snappers will appreciate this a bit more when you head out into the workforce and find yourself maintaining other peoples' code. Yes, readability is not solely dictated by syntax, but when you are only just learning to write software, tricky or terse syntax can be a hindrance when trying to grasp the true lessons and concepts behind the code. And I repeat... this is a 9 year-old... to my knowledge, "Spot Learns To Hack In C++" has not been released yet, and probably for a good reason ;)
  5. Um... I believe the Application.Run method blocks until Exit or ExitThread is called... so you are actually not getting past that line I would expect. Just totally shooting from the hip, but hows about something like this: Control c = new Control(); c.CreateControl(); device.SetCooperativeLevel(c, CooperativeLevel.Normal); sound.Play(0, BufferPlayFlags.Default); while(true) { Application.DoEvents(); // other game-loop stuff here... }
  6. Syncronizing the keyboard over the network

    Quote:I do not understand why it would help to abstract the information send to the server more. I mean, if a key (a relevant key) has changed, the server has all the information he needs for in Example accelerating the player. What difference would it make if I tell the server "Hey, I am accerlarating" instead of "Hey, the key, causing me to accelerate, has been pressed"? Well one thing is that you lose the ability to have the player remap their inputs (keys, mouse, gamepad, steering-wheel, etc) to different in-game actions. All I meant by abstraction was the decoupling of keypresses (and other input from control devices) from the actions/commands that they represent... that way multiple inputs may actually be aggregated into one "command" (or a change in one client state property) which may be less data to send to the server, and less processing/deciphering once it gets there as well. I guess you can look at it as you are sending key-state information, but keys themselves don't have any meaning... the actions that they trigger is what the server needs to know, so why not make the interpretation at the client end and give the server less to think about [smile] hplus0603: not sure if the first bit of your reply was directed to me, but I certainly don't advocate sending all the client's state in an update message... just the stuff that has changed since the last acknowledged message to the server.
  7. Sorry, should have been a bit more specific, but as the AP has indicated, these events are not going to catch circumstances where the process is being aggressively killed (such as hitting "Stop" while debugging, or hitting "End Process" in Task Manager). They should, however, work in cases where the app/service is being closed/stopped in a more civil manner. I don't think the original poster is trying to keep the app alive, so a guardian process is not the solution needed. Rather he wants to ensure cleanup code is always run and resources always released even if the user fails to invoke the correct shutdown commands before quitting (which would be quite a PITA from outside the actual process, if it is even possible). BTW, another event that may be important for you to handle is the UnhandledException event, so that you can at least cover yourself for failures internal to the app.
  8. Try the DomainUnload or ProcessExit events of the AppDomain that your program is executing within. Link
  9. Syncronizing the keyboard over the network

    Um... yeah... based on the information you have provided (i.e. no really good reason) I don't think that is what you really want to be doing. I think you will find it creates a much nicer experience for the players, and reduces bandwidth usage quite a bit, if you send more abstract state information concerning the player (e.g. multiple key presses may lead to a change in the players velocity... it is this property rather than the keypresses that the server is interested in), and only send messages when these properties change. See this recent thread for a bit more info. Hope that helps [smile]
  10. [.net] C# vs Vb.NET

    Pardon me if my tone seems offensive (that is not my intent), but how the hell did you arrive at the idea VB.NET is any less suitable than C#? You state it as if you are resigned to the fact that it can't be done (or that someone with a fair degree of authority told you as much, but didn't deem necessary to explain)... Of course you can make perfectly fine and dandy games with VB.NET... it has all the language constructs and class libraries you could ever need to make a game. It is a different syntax on top of the same framework and common language as C#, so ignore the BS, get stuck in, and code that sucka in VB.NET if thats what you know! :) I'm sure someone else will be along shortly to point you at some good examples. As for myself, I prefer the minimalistic syntax of languages like C/C++/C#... hey, its less typing than VB for the most part ;)
  11. I have to agree with where frob is coming from here... there has to be a better way to address this. I would suggest looking over the way your app is designed and look for opportunities where frequently created transient objects can be pooled (such as "action", "transaction", or "message" type objects), so as to reduce overhead for allocation and finalization/collection. By drawing these frequently used objects from a pool (and just adding another if all objects in the pool are currently in use), and returning/releasing them for re-use, I'll bet that you can maintain a very steady level of memory usage (once the pool has ramped up to size on startup), and minimize the amount of memory that the garbage collector has to reclaim. (note: This approach should also cut down on fragmentation if you pre-allocate your pools at startup, and possibly save on free-space compacting time as well) I am happy to be corrected if I am wrong, but I recall reading an interview or a blog or a .plan or something waaaay back where Tim Sweeney of Epic suggesting this approach when using Managed DirectX (and I wouldn't be suprised if it happens behind the scenes in many instances) to stave off hiccups caused by the garbage collector, so the idea must have some merit :) The other suggestion I have is a little less elegant (and makes me cringe a bit), but is there the possibility that throwing hardware at the problem (more processors or faster processors) would reduce it to an acceptable level? Better hardware is often cheaper than reworking an entire software system, even though its a solution that turns the stomach of a developer who takes any pride in what they do :)
  12. For a start, I think you may need to abstract your client input away from the messages you are sending to the server (if indeed you are sending individual key presses and mouse clicks/movements). And I don't think time-based updates are quite what you want either... I think what would be advisable is an event-driven approach. The main point is that you really only want to send a message to the server when something changes. What I would suggest is polling client input each time around around the game loop, and using this to calculate changes in key properties such as velocity (i.e. speed and direction of the client's vessel), weapon fire state, etc. These changes are the events that the server really cares about (not actual keystate and the like). Stuff information about these events into a queue. Then, on the networking side of things, just dequeue these events and send them to the server until the queue is empty. Process incoming messages from the server as usual. If you don't receive a ack/response before another event occurs, stick a number of them together (in order) in order to send a more efficient (read: closer to MTU) packet. I suspect a number of action games employ an approach something along these lines (correct me if I am way off anyone). Obviously, you will need to do some sanity checking on the server (so that hacking bastards don't go from 0 to a bazillion metres per second in the blink of an eye). You have to be mindful of what you send... position is generally not a good idea (let the server run the simulation and notify the client where it has moved to). I apologise if I misunderstood how you are currently doing things, but hopefully you get the gist of what I am saying anyway :)
  13. [.net] Seperation Of Game Elements

    I agree with Anonymous here... custom attributes rock the cazbah when it comes to this type of plugin architecture and dynamic discovery of features. And just to add a little more, although probing sub-directories is nice, it may be nicer to allow a manifest/config to specify directories to probe (in case they are not below the directory of the laucher app) as well as allowing for a specific assembly to be nominated (to save probing and loading a crapload of assemblies that you may not even need for the current game). [edit] - seems the grammar fairy went on holidays
  14. XML Problem

    Your XPath query can be changed to simplify this to a single loop, and casting each "game" element as an XmlElement in the foreach loop allows you to call the GetAttribute method to retrieve "name"... i.e. XmlDocument xmldoc = new XmlDocument(); xmldoc.Load("C:\\Games.xml"); XmlNodeList games = xmldoc.SelectNodes("//supported/games/game"); foreach (XmlElement game in games) { MessageBox.Show( game.GetAttribute("name") ); } Not necessarily the most defensive way to code that, but does it achieve what you are trying to do? The reason your code does not work is because the indexer (ie [] operator) for XmlNode only applies to child nodes that are elements, of which your "game" element has none.
  15. Quote:Original post by Holy Fuzz This is true. What I like to do is provide a custom, overloaded MyType.Equals(MyType obj) method, which is called by both the overriden Equals(object obj) method and the == operator. That way, there aren't any unboxing issues, and my personal preference is to not put any "meat" inside of operator methods, but instead to merely provide them as syntactic shortcuts to the methods that do the real work. Good call... this is a wise way to do it in order to make your structs/classes CLS-compliant (as operator overloads are only available in C# for .NET 1.x, while both C# and VB.NET get the feature in 2.0), just in case some twisted individual wants to use your code from COBOL.NET or something equally freaky and wrong ;)