Jump to content
  • Advertisement

lucem

Member
  • Content Count

    57
  • Joined

  • Last visited

Everything posted by lucem

  1. lucem

    GameEngine Design

    First notice: Why should a GameState know that something like a GameStateManager even exists? The Manager should query the State if it is finished. Second notice: Static stuff is usually meant as Singletons. Singletons really are bad, so one should avoid them at all cost. (Explanations etc. are to be found in this subforum en masse, so I won't go into detail here) You say you have two games at hand that will use the engine... I would strongly advise you to design the games first, then go the step back and determine what common basic functionality both of them need, and implement that. Then write your games; after that, you can dive into it a bit more and will see more clearly what will belong to your engine, and what not. Don't start with an "engine" that has no clear specs on what it should do and what it's responsibilities are.
  2. lucem

    Suspending a goal

    <unintentional double post>
  3. lucem

    Suspending a goal

    Have a stack where you push on all goal in reverse order; when you interrupt a goal, push it back on the stack, and push the new (interrupting) goal afterwards. Your agent should work something like this to work: Update() if curGoal.IsFinished() curGoal = goalStack.Pop() ... (process environment update) ... (execute code for goal) You will have to have an "idle" goal on the bottom of the stack though. If the environment update generates a new goal, the current goal is pushed, then the new goal and the current Goal is made invalid. The next frame, the new goal will be popped and executed, and once it's finished, the postponed one will be popped and resumed.
  4. Well, basically what is done in DI has been done as a "best practice" since the starting days of OOP. It just got a new, fancy name tag :) DI is simply the old rule to program against interfaces, not implementations. All that DI does is adding the injection part of it - so moving the creation of concrete objects outside of your business objects. This way, the objects are assembled outside of your business classes and are injected at program start, or call preparation. Of course, this enables you to do fancy things like Mock Objects in TDD, but it's nothing new. Just like component based designs are nothing new - at least since "Design Patterns" everyone should know the old rule of preferring composition over inheritance. But it took more than ten years since that book and the general adoption of that behaviour - component based designs became fancy around the mid if this decade in the wide public. My advice would be to do proper designing by sticking to the plain old rules that have been around for years and not run after trendy buzzwords - 'cause you're already doing what they propagate then, they just give it a new name. Btw: Data encapsulation is crucial. There is nothing good in breaking encapsulation and making class data public, as was proposed somewhere up the list. Encapsulation is not "small scale design". Abstration isn't "small scale design" either. The trick is to define interactions between objects through interfaces (unless there is close coupling by necessity). If data is made available by an interface, it's fine. If it's done by a class, it's not. Program to interfaces, not implementations. Mr Neverdone is really wrong at that point (with everything else, I ack totally) - or I just read him very wrong ;) Anyway, all I can encourage people to do is get their reading of the good old standards done. And that particular books is very well one of them :)
  5. I don't believe there is an even closely perfect answer to all the questions and problems depicted in this thread, First problem is, "self taught" programmers seldomly ever scratched the surface of formal methods and software engineering. It's like trying to fly a plane without knowing where the manual is, or even wanting to read it before takeoff. Second one is, changing requirements. That's what design documents should be for - formal specification of everthing that shall be in a piece of software, what i shall do and what not. In customer driven designs, the design documents are the contract; it needs to be treated like that. Thus, if a customer comes and demands requirements changes, you throw the design docs on the table, open up the page related to that topic and say "Well, in our contract it reads this. This is how it will be done, unless you want to pay for the extra work needed to change everything". And that's the way game designers shall be treated, too - sticking to the plan and only changing it when it's needed, not when someone comes up with something new and totally cool - it's called "feature creep", and that's the beginning of the end. Third problem is leadership. If you have people working on your project that refuse to adopt a corporate working process, that refuse to document what they're doing and deny planning ahead (which is the essence of the engineering part in SE), then their project leader, manager or whoever is in charge should go and kick their nuts. They're getting paid for doing what they're told to do, basta. And implementing formal methods and good working processes to make a project controllable and plannable (to a software project's extend of plannability at least) is good leadership; allowing people to work wildly and uncontrolled is "lessez faire", which is considered bad leadership. Foruth problem is, time constraints and problems that pop up down the road, so even a good design shows it's flaws. Hitting reality can destroy any good plan, nevertheless without a plan, it's pointless. So, proper design means planning ahead and detailing on the go, always refining and questioning decisions made earlier - but in a way that improves already done work, not to destroy it. If you stick to a general plan, an outlined blueprint of some sorts, it doesn't need to adress every screw in the ship - nevertheless, even if you move a screw, in the end what will come out is still a ship. People in software tend to forget that planning is their friend, thinking about problems ahead will prevent them becoming problems later. Projects that follow a dynamic plan will work in the end - and if you've stuck to the plan until crunch time, you will notice that problems tendentially won't be as heavy in the last minutes, as you've already adressed most of them ahead of time, just by thinking about your design five minuts longer when you started. Unit tests for example might seem tedious, but in the end of the day you will be glad if you have them. If a test fails, it tells you exactly where something broke, so you don't have to search for it. You will know why it broke, because it must be something you did on that day, and that's easier to track than patches from three months or longer. This way, unit tests, if used properly, will save you debugging time. Plus, by writing the test before the code to test, you will always have a reference inside you code that will tell you what that thing is supposed to do. In the first fie minutes it's more work, in the end of the day it saves you lots of time. But it takes good leadership to enforce use of such techniques. So, to sum it up, no perfect solution in sight, and there won't be any until everyone on the project is going to play by the rules.
  6. lucem

    Strategy game formations

    Complexity of this depends on how you implement it. Re-computations don't have to be done every frame, and mimicking real command structures can be very efficient - in this case, AI decisions fall down the tree automatically, and get concretized on the go. Inside the various stages, existing technology like state machines etc. can be used, and as orders usually stay valid for longer periods than a couple of frames, it can be both elegant and efficient.
  7. lucem

    3D Space Game AI Ideas?

    I'm not really sure if neural nets are applicable in pointing out directions for movement in combat - for the most part, movement decisioning is based on knowledge, not training. So, neural nets can deliver decision parts based on training, but you'll have to consider knowledge (which can change rapidly, this is why neural nets alone won't cut it) as well. Randomizing neural nets is dangerous here, too - it can, under bad circumstances, result in absolutely random and unpredictable steering behaivour, odd things like "Oh, I must attack, let's move away from the enemy, as my brain tells me to do so". That's something to avoid!
  8. lucem

    Strategy game formations

    Attack formations and movement formations can be done by implementing a simulated command chain, meaning organizing your military "units" in military units. (See the quotes?) Military units get orders to operate in certain space restrictions and in a certain way (offensive, defensive, hit-and-run etc.). By graining your military down to heterogenous units formed by homogenous "individuals", and imposing a chain of responsibility, you can apply rules of engagement which in the end will result in your military units organizing themselves autonomously inside the formation - by obeying their space restrictions, and rules of engagement. (Space restrictions can be absolute, like "position x,y,z", and relative like "left to unit 2./34 in a distance of d", always applying to space volumes, not points only; this way, the units will always try to stay at their ordered position, and you only need to do the pathfinding and movement calculations for one unit, which will be either one random "flag ship" or the abstract higher-order unit, like a wing, squadron, flotille, fleet or whatever)
  9. For me this question fortunately didn't arise, as in my studies of "applied computer science" both 'worlds' merge pretty well. It all started off as computer science, mixed with some basic programming courses (C,C++,Java) and some courses covering specific APIs (Qt4, OpenGL). Later, I had two semesters of courses in software engineering, resulting in a compulsory 1.5-semester long project, which I'm currently doing right now. The diploma thesis (German degree "Diplom-Informatiker", somewhere between a Bachelor and a Master) will be a software project again, so in the end I'll have at least those two demos for my portfolio, not counting my own programming work outside of school. I also did some electives like "Mathematical methods in computer graphics", plus a second, more in-detail course in OpenGL (didn't need it, but what you've got on paper...), and last, but not least some basic courses in Operating Systems and web technology. I don't count the usual stuff, like basic electrical engineering, physics and math, everyone has to do those. I'm not too far away from graduation, and looking back I'm quite happy with the curriculum and the choices I made. What's really important for me in that is, I'm not solely in the gamedev thing, though I do consider working in the gamedev field later, but if it doesn't happen, I have a lot of alternatives where I can head to. I really believe, and that's quite important, that one should not specialize too deep and too early, especially not into game development. Having alternatives and other fields of interest as a backup-plan is crucial, IMO. What's your take on that?
  10. I use them quite extensively in a lot of places. Patterns provide proven solutions to common problems, but they do have a downside - sometimes things can be done more elegantly in another fashion, and in some rare cases one can read from the code that at a place patterns have been used just to use patterns, not to solve a problem. The GoF (Design Patterns - Elements of re-usable, object-oriented software; Gamma et al.) is a must-read though for aspiring developers, IMO. Dealing with the subject not only broadens your problem-analyzing and -solution skills, but it makes you think about object oriented design and really changes the way you think about designing software. The result is usually a much sleaker and cleaner design. The only mistake that you shouldn't make is designing your problems around patterns - a lot of peoply do so when they get in contact with the material for the first time ;)
  11. lucem

    Where to start

    Well, certainly not posting the question in "Game Programming". Besides, a good start point is knowing what you want to achieve (what's the game about, how should it feel to play the game, how shall it work in a general sense).
  12. That's exactly what it is - private. Note the difference in standard behaviour to Java! Just wanted to stress that ;)
  13. Quote:Having version control integrated with the IDE isn't that important... If your VC system already integrates with windows explorer (e.g. TortoiseSVN) then there is really no need. I'd rather disagree with that, but for sure, if you can do version control in the explorer, it's better than nothing. TortoiseSVN/TortoiseCVS et al. are great tools, no argue on that ;) The thing is, having version control integrated into the IDE saves you a lot of time, it's less error-prone (you don't forget checkout/checkin when it's automated) and your workflow isn't interrupted by manually triggering version control operations. This way, it's reduced to a transparent no-brainer, which is exactly what it's supposed to be - easy to use, "just there" and not requiring manual attention. (At least once it's set up to work) Another note on that, since I started using Team Foundation in VS, I'd never want to come back to the (mostly) lousy freeware plug-ins like ankhSVN and whatever there else is - I never got it to work in the first place with these. Gladly, TortoiseSVN worked better than that. A good example of SVN and CVS integration itno the IDE is Eclipse - once you've set it up (which is easy), it handles all the operations on it's own, so you don't have to manually trigger checkins and checkouts. I mentioned that as an example everyone, even people not having access to the commercial editions of VS (which support TFS), can look at and see how it can work. The bad thing about Eclipse is, that it sure as hell eats up your memory and CPU power faster than any Windows flavour ever could. Code::Blocks is actually one of the IDEs I never touched, but what I can read from the info I got, it seems to be a nice alternative, especially as a multi-platform IDE. Other options one might consider (on the freeware/OSS market) are Eclipse/CDT, NetBeans 5+ and KDevelop (so far Linux only, but with the latest release getting more closer to actually being useful). Working with emacs and vim is PITA IMHO, since they have a steep learning curve and you really have to invest a lot of time before they actually get useful and save you time. I was forced to work with those during some university courses, though, and it worked after some time, but I never really liked it that way. I have the uttermost respect for people who voluntarily use these editors! I personally use VS2k5 Standard a lot on Windows (obviously), and KDevelop and Eclipse on Linux (and OS X). On OS X, I never got the time to try XCode, which is rather awkward when you're coming from VS ;) But I'm sure it's got it's advantages. At the moment, I have VS2k8 Professional installed parallel to VS2k5 Standard, but haven't found the time yet to evaluate it properly - additionally, the German version isn't out yet, so I'll be waiting for that before I seriously start using that. Oh, and I'm running all of those on XP SP2, I got Vista in parallel, but only for testing, I pretty much dislike it all the way. ( Yes, I got all these licences from my university, so these are all legal; thanks for asking )
  14. - Version control (not only with TFS) possible - Solutions using more than one programming language - Expansibility (plugins etc.) ... need more? Version control alone makes life a hell of a lot easier.
  15. lucem

    Class diagram feedback

    Sorry to say so, but you design has some flaws. You're modelling collisions as associations between classes. You rely on inheritance. And you mix several concepts that should be separated. So, what to do with that? First of all, from your model it reads that the Player class is associated with the Terain class, which in this case means that the Players interact with the Terrain directly. Please work on that, this will run you into trouble. First of all, usually the terrain is split up into several objects, with these objects attached to the scene graph. Having a monolithic "Terrain" object in this case would only make sense as an adapto-like thing for accessing the terrain as a whole, but not for in-game interaction. Secondly, as I read it, all these thing in your model are classes. That's fine, ut some of the functionality should be defined by interfaces, such as the collision reaction. The objects themselves should define their behaviour on collisions. Collision detection is doen by the scene graph, using the spatial information each node contains. Third, there is no need for "Player1" and "CPU" classes, the Player class is sufficient to do the job. It should have a component that controls it, and that component should make he difference between human and CPU. Otherwise, you'd be directly handling input inside a game class, which is a bad idea, obviously.
  16. lucem

    agents data

    Well, that's a broad question... With what I get from your post, it seems you're implementing the registry pattern in your engine, at least somehow. With the registry, every object bears a unique identifier, for which you can query the registry, which in turn delivers a reference to the object. So, for transmitting information from object to object, in your case it would be the simplest way to query the info from the registry mechanism, where you get a reference you can use to query the actual object for the info you need. Since this can lead to heavy performance hits, I would recommend you to redesign your object system; object management based on quadtrees can simplify a lot of your object interactions, and for 2D, quadtrees are just right. Plus, you get O(log n) behaviour instead of O(n) behaviour when using a list, like you do at the moment.
  17. lucem

    How to structure a game engine.

    Exactly. Most game engines suffer from the fact that they put everything into a "game object/ entity" class which more or less resembles the anti-pattern "blob". This results in fairly ugly code, where you run into serious problems once you're trying to bring in new features (which usually you shouldn't) or alter existing functionality. You shoot yourself in the foot. Dividing up the data into smaller pieces which are handled by several classes (that have distinct responsibility) makes it much easier to cope with such problems. Plus, the resulting classes that arise from this design approach don't get so bloated, so it's a lot easier to grasp for someone reading the code that uses them. I wish game programmers would simply stop thinking of their programming work as different to any other programming work, where good design is established and enforced right from the start. The thing is, easy to read and use code tends to be more performant as well. Plus, if you talk to people in the (game) industry, on a professional level all these things are done - but some hobbyists seem not to be willing to accept that, so I guess trying to reach those people is like fighting windmills.
  18. lucem

    How to structure a game engine.

    This is going to be my last post for now, I need to get some sleep... it's past 3 am and at 10:30 I need to write an exam. You could mail me at sebastian.porstendorfer@web.de if there are any further questions, and I'll try to answer them. The reason for separating the data is actually two reasons. First, game objects ( as in model ) do not have to know implementations details like what texture they use, or their position on the screen. Second, if for whatever reason you decide to change your renderer, you would have to change your "tank" class as well. ( Like, switching from SDL to SDL+OpenGL, you would suddenly have to have normal vectors inside your game model... ) Thus, data is split up by responsibility of the objects that use it. It just allows for greater modularity and flexibility (what if you decide to support multiple renderers? dx9, opengl, software rendering...). Plus, if you've got everything in one class, and you derive from that class, everything is derived, even the things that are general enough to not have to be derived from - a sprite is a sprite, you adapt it to your needs by using its data, but you hardly ever subclass from it.
  19. lucem

    How to structure a game engine.

    Actually, you'd have different sets of data. For convenience, you'd have a factory of some form which you tell to build a new tank. This would create the game object "tank", attach it to some owner (AI, human player, whatever) and tell the renderer to create a new sprite for a tank, along with the initial data (position etc.). How this creation of objects is done would be up to you. You could create everything in there and "inject" it to the subsystems, or you could delegate object creation to factories inside the subsystems which will do locally (and transparently). After that, all three subsystems would have their own "tank" object, having the data they need. So, one monolithic "tank" is split up in 3+ smaller objects that only contain the data that's needed for the specific subsystem. iDirect3D9 is not an interface, but an adaptor class (see the adaptor pattern) - it presents you with some of the functionality Direct3D provides, and gathers them in one place. So, it is an interface, but on a larger scale. It's an interface for a lot of other classes, not only one. iDirect3D9 itself would talk to a lot of other classes inside the D3D library, which you do not have to know, so it hides this information from you and presents you only the things you need to know. In a smaller scale, the MVP works the same. For your game, you might implement all your game code in "model", and use renderer and controller (or presenter) as adaptors to the underlying subsystems. The Unreal Tournament thing: Yeah, believe it or not, that's how things work. Every good programmer and system architect out there has read the GoF "Design Patterns", and knows how to use them. You come across patterns everywhere today - even inside programming languages and their runtime environments (Java and .Net are prominent examples of that).
  20. Hm... Weapons of Mass Destruction don't really cut it, I'm afraid - once you've used them, there's nothing to dominate anymore. Dildo's won't cut it either - what to do with the remaining 49% of earth population? So, the only real option: Be Bill Gates. Really - after building up a company that uses evil tactics to control basically alle of modern economy, you just back out, keep up your percentage of shares, just in case ;), and start playing Mr. Nice-Guy who donates to everyone, so everybody really freaks out and wants you world leader. Then, keep it all up until you've got enough resources to build a death star ;)
  21. lucem

    How to structure a game engine.

    Oh, thanks, I always get those two wrong :) MVC is mainly used in GUI, half of Windows consists of that pattern - but, the problem is, MVC makes it hard to correctly identify the responsibilities, as ravyne pointed out. MVP makes that a lot clearer, IMO (though both are related, it does make a huge difference after all). By the way, you shouldn't worry too much, write your game. Just put some thought in advance on how you can deal with different responsibilities of different "components" of your engine. In the end, there are only two rules: - Make it fun. If it's not fun, it's not a game. - Keep it simple. Anything else is subject to discussion, and there is no clear wrong and right. It all depends...
  22. lucem

    How to structure a game engine.

    Didn't mean to insult you ;) Using your example of render data, maybe this makes it a bit clearer: Think of the system as data which is held in parallel, suited to the needs of each subsystem (render, control, model) and is linked by some common denominator (like an ID or whatever). So, the renderer has it's own list of data (sprite, spatial etc.), the view has it's own data (which object is controlled by which controller), and the model has its own data (the objects). Everything is tied together by a high-level object containing the game loop, which knows all the subsystems and talks to them directly (by using interfaces rather than classes). So, there would be three Interfaces for the three subsystems: IRenderer, IController, IModel (or, IPresenter, IView, IModel) The controller would know the model (by using the IModel interface) and the renderer, the renderer would know the controller. The model would need to know the controller, too. On this level, the three subsystems would be able to communicate changes without knowing the classes of the other systems - as long as they implement their respective interfaces, everyone's fine. So, if a tank was destroyed while it was visible, the model would notify the controller of the fact that that tank was destroyed. The controller would notify the owner of that object (let's make it an AI player) that is was destroyed, which will delete it from it's list of inventory. The controller would also notify the renderer about the destruction of that tank, causing the renderer to remove the corresponding sprite from its own data. As you can see, all subsystems keep their own data, and synchronisation between them is done via messaging (method calls, events, whatever). The systems can interact with one another, but do not have to know about the other systems' data or implementation details. In the end, you'll have a robust system, that is easily understandable and is less error-prone. Plus, you can easily modify your renderer without it affecting the game model representation of a tank!
  23. lucem

    How to structure a game engine.

    Singletons: Simple - use them never. When you run in a situation where you need them, you'll see for yourself. In all other circumstances, when something's crying for Singleton, ignore it. Singletons are more of an anti-pattern today, with good reason. After reading what you wrote about your experience with interfaces, it's obvoius to me that you haven't understood object oriented programming at all. There should be no direct interaction of a game object with the renderer. A game object is responsible for managing it's own data, such as it's world position (not screen position!), and the way it behaves. It's not responsible for drawing itself, it's not responsible for updating its screen coordinates, if visible, it shouldn't even know about the fact that it's a renderable object at all. The renderer is responsible for drawing everything, finding the right sprite to draw, and all stuff graphics. So, how to do that? Well, there comes in an architectural pattern that's called MVP. Model View Presenter is about a three-tier design where there is (in this case) game data (model), a renderer (presenter) and someone in the middle that intermediates between them (view). So, in your case, the view is the center of all attention, and it interacts with the model data, and is interacted with by the presenter. The presenter doesn't talk to any game object in the model tier. It gets all that there is to know using a defined interface that is implemented either by view alone (using delegation of certain request to model) or by view and model. So, each system is responsible for one task only, and using interfaces here provides you with the possibility of e.g. re-using the renderer in the next game, while the view and the model change.
  24. lucem

    How to structure a game engine.

    Maybe it's a good idea to differentiate a bit on that... It's always a good idea to put some thought on what you need and how it's going to work before you start coding, and laying out an "engine" is just one way to do it. The thing is, for one-man-projects, the word "engine" should not have the same meaning as in large-scale development teams. An engine can well be some sort of abstraction from the libraries used, with some glue code attached. That's just fine, and it helps you keep your focus on the game. You should not, however, start thinking about how to organize your game data in an engine, or about game code in general, in terms of an engine. So, you can design some classes which do the painting of sprites for you, and add the capability of playing some sound. You also can design a class that takes input device data and translates it into a more generalized form. Something like that, with a bot of experience, is what you can call your "engine", and build on top of that - but, do your self a favour and keep things simple. No one ever completed a program once he started writing frameworks....
  25. lucem

    How to structure a game engine.

    It seems to me that you focus too much on classes while programming. It's never a good idea to rely on implementation, so no code of yours _ever_ should use a certain class directly. The trick is to stick to the rule "program to interfaces, not implementations". Interfaces define the outer receptance of a group of classes, a single class or a complex sub-system. The thing is, you don't know what's behind an interface, and you don't have to - you simply stick to using what the interface offers, period. Why this imperative for abstraction? It keeps your code clean. It keeps your design clean. And, if done properly, it reduces coupling between classes. Let me give an example... Imagine you have your scene graph update all the items in it. If you stick to just classes, you'd have to differentiate between huge amounts of classes to do so, but if every class requiring updates implemented an IUpdatable interface with a public update() method, you could treat all kinds of objects the same way, and could be presented with all kinds of objects without even knowing their implementation at all - they could be even outside of your own assembly unit, so e.g. plugins written by some users or whatever you could possibly think of. All of these classes would simply just follow one rule - implement a method called update(), specified by an interface IUpdatable. I hope you get the idea ;) Another thing you mentioned is design patterns - especially Singleton. Use them with caution - they tend to bloat your code when you don't fully understand them, as in the saying "When all you know is nails, everything looks like a hammer". Design patterns are great in many places - but, in many places they aren't, because you're not using the right pattern at the right place. And using the _wrong_ tool to do the job just complicates things. Finally you spoke about events. Events and event-driven programming are a complete paradigm of their own, which is the right tool for some applications, and for some it simply isn't. The problem is, events are ideally suited for asynchronous operations, as they are non-deterministic by nature. For use in a game engine, at _some_ places events are just fine and have their advantages, but at a greater scale, they make things worse. Events can be used to locally communicate changes in state between objects, but they do at a cost (event handler execution, instantiation of event objects, destruction of event objects, and possibly raising other events, too). This cost is it which has to be taken into account when using them. For example, updating an entire engine with events, where each and every object receives the same event, may seem thrilling - but, updating objects with method calls may be more efficient. This may seem a bit negative, but there is no super-remedy for everything in software design. All these things are a bit generalized, though, maybe it would help you more if you could give some insight into your engine as it is right now, so one could point out possible solutions. [Edited by - lucem on January 30, 2008 5:21:18 PM]
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!