Game framework architecture - view components or MVC? - model-view-controller

I'm trying to build a very light re-usable framework for my games, rather than starting from scratch each time I start a game. I have a component driven architecture - e.g. Entity composes a Position component and a Health component and Ai component etc.
My big question is whether my model composes view components to allow for more than one view of the model, or whether to use a truer MVC where the model does not know about its views, and they are managed externally.
I have tried both methods but if anyone knows the pros and cons of each approach and which is the industry standard, it would be great to know.

depends on your audience, game devs, myself included aren't very used to the MVC model, although most know it, it's not as easy to keep it clean cut, because of development casualties (not any serious technical reasons). So from experience, I've seen dozens of game frameworks start as MVC, but only a pair were able to maintain it until the end. My theory is MVC adds too much complexity and little benefits for small throwaway games (with normally a few devs), and it's to hard to keep really cleanly separate most game objects into these layers for large/complex games. And since games have a release date, they many times sacrifice code clarity and reusability for performance and quick adhoc solutions (that will get rewritten if necessarry in the sequel (if there is one)).
However, with the caveat above, it's better to aim high, because if you succeed it's better :) and if you fail, well to bad. So you should probably try the MVC, but don't worry if it fails, profesional game devs have all failed at the task many times :)

I’d certainly vote for the model to know nothing about its views. Loose coupling is good: Simpler model code, easier testing, more choices.

I know this question might be outdated, but I need to reply on it.
Actually, I started programming a game in Lua (with LÖVE) and I started programming a MVC - Framework for it.
At first, to use MVC really depends on what you want.
I know my problems with game programming, when the program becomes bigger, and mostly the structure becoms too complex to maintain.
Next thing is, I know that I will change all the graphics when I find an artist who is willing to work for it. But until then, I'm gonna use my own dummy graphics.
I want the artist to feel free to do what ever he wants, without beeing dependend on any resolution or color restriction.
That means, I might have to change the whole (!) presentation code. Maybe even the way objects interact (collision detection, f.e.).
The game logic is captured in the models, so I can concentrate on that. And I think game logic is the most important part of making a game. Isn't it?
Hope you see my point.
But, if you have everything together: all the graphics, sounds, the whole thing; then you can code straight forward.
My MVC is a configuration-over-convention-ass, that slows down prototyping a bit.
BUT(!) iterations of development can be made much more easily. Testing, especially Unit-Tests are done much more faster.
I would say MVC turns you development-speed-curve (which is normally an anti-exponential curve) into an exponential curve. Slow at the beginning, but more and more fast at the end.

MVC works really well for games, at least for my games which are designed for cross-platform.
It really depends on how you implement it in order to get the benefit.

Related

User Interface Design Package

I am working on designing a user interface and want to convey my design to my peers. Typically, I'd use a mock-up of the UI and UML, but given the complexity, size, and multiple asynchronous interactions I'm not sure that this makes the most sense. It doesn't seem to allow to efficiently describe the process.
Does anyone have experience in designing large User Interface's? How would a company that designs UI's go about modeling their process/ design? This seems to be a question for the 'front-end' engineers.
well let's go for an answer even if your question is very large. I'll give you my experience and hope it will help you to decide.
To my mind, using UML in a project is very useful if you use it right, it's often clear, quite easy to understand. On the other side, when working on huge project, it's sometimes costly because it takes time to create your diagrams and nowadays, you have to be as fast as possible !
These last months I have worked on a project with a GUI and to well define it, I have first draw some screen on paper and quickly ask for some drawbacks near the coffee machine.
I have created some activity diagrams and then, created a mock-up.
How to choose now ?
First of all, if your GUI should have a beautiful design, I don't think you can avoid a mock-up, but I'm don't know if it's your goal.
My main tip would be, try to simplify your complexity in your program. If you have multiple asynchronous that could arise everytime/everywhere, you'll encounter a lot a problem.
In my project, let's say my tablet could be preempted by an external computer whenever/wherever. I just have created a class beforehand to manage this asynchronous call but my sub-activity-diagrams stayed intact.
Draw specific diagram for specific functionalities and leave useless diagrams which are not relevant/too simple.
Hard to explain you more than this without giving you any example. Hope it will help a bit.

Can TDD Handle Complex Projects without an upfront design?

The idea of TDD is great, but i'm trying to wrap my head around how to implement a complex system if a design is not proposed upfront.
For example, let's say I have multiple services for an payment processing application. I'm not sure I understand how development would/can proceed across multiple developers if there is not a somewhat solid design upfront.
It would be great if someone can provide an example and high level steps to putting together a system in this manner. I can see how TDD can lead to simpler and more robust code, I'm just not sure how it can bring together 1) different developers to a common architectural vision and 2) result in a system that can abstract out behavior in order to prevent having to refactor large chunks of code (e.g. accept different payment methods or pricing models based on a long term development roadmap).
I see the refactoring as a huge overhead in a production system where data model changes increase risks for customers and the company.
Clearly i'm probably missing something that TDD gurus have discovered....
IMHO, It depends on the the team's composition and appetite for risk.
If the team consists of several experienced and good designers, you need a less formal 'architecture' phase. It could be just a back of the napkin doodle or a a couple of hours on the whiteboard followed by furious coding to prove the idea. If the team is distributed and/or contains lots of less skilled designers, you'd need to put more time/effort (thinking and documenting) in the design phase before everyone goes off on their own path
The next item that I can think of is to be risk first. Continually assess what are the risks to your project, calculate your exposure/impact and have mitigation plans. Focus on risky and difficult to reverse decisions first. If the decision is easily reversible, spend less time on it.
Skilled designers are able to evolve the architecture in tiny steps... if you have them, you can tone down the rigor in an explicit design phase
TDD can necessitate some upfront design but definitely not big design upfront. because no matter how perfect you think your design is before you start writing code, most of the time it won't pass the reality check TDD forces on it and will blow up to pieces halfway through your TDD session (or your code will blow up if you absolutely want to bend it to your original plan).
The great force of TDD is precisely that it lets your design emerge and refine as you write tests and refactor. Therefore you should start small and simple, making the least assumptions possible about the details beforehand.
Practically, what you can do is sketch out a couple of UML diagrams with your pair (or the whole team if you really need a consensus on the big picture of what you're going to write) and use these diagrams as a starting point for your tests. But get rid of these models as soon as you've written your first few tests, because they would do more harm than good, misleading you to stick to a vision that is no longer true.
First of all, I don't claim to be a TDD guru, but here are some thoughts based on the information in your question.
My thoughts on #1 above: As you have mentioned, you need to have an architectural design up-front - I can't think of a methodology that can be successful without this. The architecture provides your team with the cohesion and vision. You may want to do just-enough-design up front, but that depends on how agile you want to be. The team of developers needs to know how they are going to put together the various components of the system before they start coding, otherwise it will just be one big hackfest.
It would be great if someone can provide an example and high level
steps to putting together a system in this manner
If you are putting together a system that is composed of services, then I would start by defining the service interfaces and any messages that they will exchange. This defines how the various components of your system will interact (this would be an example of your up-front design). Once you have this, you can allocate various development resources to build the services in parallel.
As for #2; one of the advantages of TDD is that it presents you with a "safety net" during refactoring. Since your code is covered with unit tests, when you come to change some code, you will know pretty soon if you have broken something, especially if you are running continuous integration (which most people do with a TDD approach). In this case you either need to adapt your unit tests to cover the new behavior OR fix your code so that your unit tests pass.
result in a system that can abstract out behavior in order to prevent
having to refactor large chunks of code
This is just down to your design, using e.g. a strategy pattern to allow you to abstract and replace behavior. TDD does not prescribe that your design has to suffer. It just asks that you only do what is required to satisfy some functional requirement. If the requirement is that the system must be able to adapt to new payment methods or pricing models, then that is then a point of your design. TDD, if done correctly, will make sure that you are satisfying your requirements and that your design is on the right lines.
I see the refactoring as a huge overhead in a production system where
data model changes increase risks for customers and the company.
One of the problems of software design is that it is a wicked problem which means that refactoring is pretty much inevitable. Yes, refactoring is risky in production systems, but you can mitigate that risk and TDD will help you. You also need to have a supple design and a system with low coupling. TDD will help reduce your coupling since you are designing your code to be testable. And one of the by-products of writing testable code is that you reduce your dependencies on other parts of the system; you tend to code to interfaces which allows you to replace an implementation with a mock or stub. A good example of this is replacing a call to a database with a mock/stub that returns some known data - you don't want to hit a database in your unit tests. I guess I can mention here that a good mocking framework is invaluable with a TDD approach (Rhino mocks and Moq are both open source).
I am sure there are some real TDD gurus out there who can give you some pearls of wisdom...Personally, I wouldn't consider starting a new project with out a TDD approach.

How to write reusable business logic in MVC models?

my problem is that we try to use a MVC (PHP) framework. After discussing a lot think that MVC is very good, but I'm missing the possibility to write reusable model-(application)logic. So, I'm not sure if we have the right approach to implement our software in a MVC framework.
First I´ll describe the non-MVC, oo-approach which we use at the moment.
For example - we are working on some browser games (yes that's our profession). Imagine we have an player object. We use this player object very often. We have some different pages where you can buy thinks, so you need to make "money" transactions on the players "bank-account" or imagine you can do fights against other players. We have several fight-scripts, and these scripts take 2 or more player objects (it depends on the type of battle ie. clan battle, player vs. player battle...).
So, we have several pages (and controllers) with different battle-logic. But each of this controllers use the player-object to calculate all the attributes and items a player has and which damage and defence a player will do.
so, how can we reuse the logic in the player object in case of a MVC Model? it would be bad to duplicate all the necessary logic in the different fight-controllers and -models.
I think the "gold-transaction"-logic would be a good example to give you some more detail information. you need the transact-function in case of a fight, if you win against an other player and loot some of his gold, you need the transaction function in case of buying some stuff and you need the transact-function in case of spending some gold to the players guild...
So, I would say it would be a bad approach to define all these functions in one player model! I can say you these player model would be very big (actually we have the problem that our player-class is really huge - its a god class)
do you think there is a MVC-style solution for this problem?
I would say you put the code where it makes the most sense, and where you would not need to duplicate it someplace else.
If there is some operation that always needs a Player object, but might be used across different Controllers, the Player class would be the logical place to put it. On the other hand, if a bit of logic only needs to be done in the context of a certain Controller, and involves potentially other classes, it perhaps should be in the controller - or perhaps in some other class, too.
If you are having trouble figuring out where the logic should go, perhaps it's because your functions are not granular and reusable enough as they are. There are certainly aspects of MVC that force you to think a little bit more about the separation of concerns and keeping things DRY more than a 'plain' OOP approach... so you might end up breaking up currently coded operations that are in a single function now into multiple functions on different classes to get the right code in the right places.
For example - and these are not at all specific suggestions, but just a random possible thought process - maybe the process of transferring 'gold' between players needs to be broken down into more granular processes. The player class may do the basic task of changing the balance, but then the controller(s) may do specific parts of the process, such as verifying to/from whom gold is being transferred and why.

Refactor or Rewrite UI Layer from Scratch

In most cases it is better to refactor than rewrite a full codebase. We have quite interesting situation. In our application business layer is pretty good. With unit tests, separation of concerns, etc. It does have some problems, but it can be refactored.
However UI layer is outdated. It is ASP.NET + some AJAX, but we want to migrate to pure AJAX application (ExtJS + REST). The application is quite large and has about 100 separate screens. What would you advise?
I'm very familiar with your app Michael. I've also been in that exact situation twice in the past few years. There is ENORMOUS benefit in rewriting from scratch. You can't incrementally improve where you are. See this from Kathy Sierra.
Bite the bullet and redesign from the ground up. You have an opportunity to blow away the competition, but it's never going to happen with incremental improvements.
I don't see prospect of a truly helpful, generic, answer. Given complete freedom I'd agree with Glen and bit the bullet and go for the whole thing. However commercial realities may prevent that, if the application is big enough then the up front investment may just be too big. Then question is whether you can possibly get to where you need to be in increments.
For example, suppose that your app follows a common pattern, there are selection screens where the items to be worked on are picked by a user and they lead to data entry screens. Then, can you rework the selection screen with nice ajax stuff but retain the data entry screens. Address those on the next iteration.

Is test-driven development a normal approach in game development?

I am just curious since all TDD examples I have seen is web programming related. And if it's not a normal approach, why is it not?
TDD has become a favored approach by software developers who are serious about their profession. [IEEE:TDD] The benefits of the approach are significant, and the costs are low by comparison. [The Three Laws of TDD]
There are no software domains for which TDD is inappropriate, or ineffective. However, there are domains in which it is challenging. Gaming happens to be one of these.
Actually, the challenge is not so much gaming as it is UI. The reason UI is a challenge is that you often don't know what you want the UI to look like until you've seen it. UI is one of those things that you have to fiddle with. Getting it right is a deeply iterative process that is full of twists and turns and dead ends and back alleys. Writing tests first for UI is likely to be both difficult and wasteful.
Now before everybody roars off and says: "Uncle Bob says: 'Don't do TDD for UI'" let me say this. The fact that it's hard to do pure TDD for UI does not mean you can't do pure TDD for almost everything else. Much of gaming is about algorithm, and you can use TDD with those algorithms to your heart's delight. It's true, especially in gaming, that some of those algorithms are the kind of code you have to fiddle with, just like UI, and so are probably not amenable to being tested first. But there is a lot of other algorithmic code that can and should be written test first.
The trick here is to follow the single responsibility principle (SRP) and separate those kinds of code that you have to fiddle with, from those kinds that are deterministic. Don't put easy-to-test algorithms in with your UI. Don't mix your speculative code with your non-speculative code. Keep the things that change for reason A separate from the things that change for reason B.
Also, keep this in mind: The fact that some code is hard to test first, does not mean that this code is hard to test second. Once you have fiddled and tweaked and gotten the code to work just the way you like, then you can write the tests demonstrate that the code works the way you think. (You'll be surprised at how many times you find bugs while doing this.)
The problem with writing tests "after the fact" is that often the code is so coupled that it is hard to write the kinds of surgical tests that are most helpful. So if you are writing the kind of code that is hard to test first, you should take care to follow the dependency inversion principle (DIP), and the open/closed principle (OCP) in order to keep the code decoupled enough to test after the fact.
The simple answer is "no", TDD is not a normal approach in game development. Some people will point at Highmoon and Neil Llopis as counter-examples, but it's a big industry and they are the only people I know of who have fully embraced TDD. I'm sure there are others, but they are the only ones I know of (and I've been in the industry for 5 years).
I think a lot of us have dabbled in unit testing at some point, but for one reason or another it hasn't taken hold. Speaking from personal experience it is hard for a games studio to switch to TDD. Usually a codebase is kept from project to project, and applying TDD to a large existing codebase is both tedious and largely thankless. I'm sure that eventually it would prove fruitful, but getting games coders to buy into it is difficult.
I have had some success in writing unit tests for low-level game engine code, because this code tends to have very few dependencies and is easily encapsulated. This has always been testing after the fact though and not TDD. The higher-level game code is usually harder to write tests for because it has far more dependencies and often is associated with complex data and state. Taking AI as an example, to test AI require some kind of context, meaning a navigation mesh and other objects in the world. Setting up that kind of test in isolation can be non-trivial, especially if the systems involved weren't designed for it.
What is more common in game development, and I've had more personal success with, is smoke testing. You'll often see smoke testing used in conjunction with continuous integration to provide various kinds of feedback on the behaviour of the code. Smoke testing is easier because it can be done by just feeding data into the game and reading back information, without having to compartmentalize your code into tiny testable pieces. Taking AI as the example again, you can tell the game to load up a level and provide a script that loads an AI agent and gives it commands. Then you simply determine if the agent performs those commands. This is a smoke test rather than a unit test because you are running the game as a whole and not testing the AI system in isolation.
In my opinion it is possible to get decent test coverage by unit testing the low-level code while smoke testing the high level behaviours. I think (hope) that other studios are also taking a similar approach.
If my opinion of TDD sounds somewhat ambiguous that's because it is. I'm still somewhat on the fence about it. While I see some benefits (regression testing, emphasis on design before code), applying it and enforcing it while working with a pre-existing codebase seems like a recipe for headaches.
Games from Within has an article discussing their use of unit testing, the limitations of unit testing with regards to games in particular, and an automated functional testing server that they set up to help with this.
If you are referring to the practice of writing and maintaining unit tests for every bit of code, I'd venture a guess and state that this is not in widespread use in the gaming industry. There are many reasons for this, but I can think of 3 obvious ones:
Cultural. Programmers are conservative, game programmers doubly so.
Practical. TDD does not fit very well to the problem domain (too many moving parts).
Crunchological. There's never enough time.
The TDD paradigm works best in application domains which are not very stateful, or at least where the moving parts are not all moving at the same time, to put it colloquially.
TDD is applicable to parts of the game development process (foundation libraries and such) but "testing" in this line of work usually means running automated fly-through, random key testing, timing io loads, tracking fps spikes, making sure the player can't wriggle his way into causing visual instabilities, stuff like that. The automaton is also very often a humanoid.
TDD can be a useful tool, but its status as a silver bullet that must-be-ubiquitous-when-making-a-system is rather questionable. Development should not be driven by tests, but by reason. RDD is a crappy acronym though - it won't catch on. ;)
Probably the main reason is that TDD is preferred by those with languages more conducive to it. But apart from that, games themselves are a poor match for the paradigm anyway.
Generally speaking (and yes, I do mean generally speaking, so please don't swamp me with counterexamples), test-driven design works best for event-driven systems and not so well for simulation-style systems. You can still use tests on your low-level components in games, whether test-driven or just plain unit testing, but for more higher level tasks there is rarely any sort of discrete event that you can simulate with deterministic results.
For example, a web application typically has very distinct inputs (an HTTP request), changes a very small amount of state (for example, records in the database), and generates a largely deterministic output (for example, HTML page). These can be easily checked for validity, and since generating the input is simple it's trivial to create tests.
However with games the input may be hard to simulate (especially if it needs to occur at a certain point... think of getting past loading screens, menu screens, etc.), the amount of state you change may be large (for example, if you have a physics system, or complex reactive AI) and the output is rarely deterministic (random number use is the main culprit here, though things like floating point precision loss is another, as might be hardware specifications, or available CPU time, or the performance of a background thread, etc.).
To do TDD you need to know exactly what you expect to see in a certain event and to have an accurate way of measuring it, and both of these are difficult problems with simulations that avoid discrete events, deliberately include random factors, act differently on different machines, and have analogue outputs such as graphics and audio.
Additionally, there's one massive practical issue which is process startup time. Many of the things you will want to test require the loading of large quantities of data, and if you mock up the data you're not truly testing the algorithm. With this in mind it quickly becomes impractical to have any sort of test scaffolding that just performs individual tasks. You can run tests against a web server without having to take the webserver down each time - that's rarely possible with games unless you do the testing from an embedded scripting language (which is reasonable, and does indeed take place in the industry).
For example, you want to add volumetric shadow rendering to your in-game buildings. So you'd need to write a test that starts up all the necessary subsystems (for example, renderer, game, resource loaders), load in buildings (incl. mesh, materials/textures), load in a camera, position that camera to point at the building, enable the shadows, render a scene, and then somehow decide whether the shadows actually appear in the frame buffer. It's less than practical. In reality you'd have all this scaffolding already there in the form of your game, and you'd just fire it up to conduct a visual test in addition to any assertions within the code itself.
Most game developers aren't exactly with it in terms of modern development practices. Thankfully.
But a test-driven development model emphasizes concentrating on how something would be used first, then fleshing out what it does. That in general is good to do since it forces you to concentrate on how a particular feature will actually fit into whatever you're doing (say, a game).
So good game developers do this naturally. Just not explicitly.
#Rune Once again, please emphasise the 'D' rather than the 'T'. At a unit level, the tests are a thinking tool to help you understand what you want and to drive the design of the code. Certainly at the unit level, I find I end up with cleaner, more robust code. The better the quality of the pieces I put into the system, the better they fit together with fewer (but not no) bugs.
That's not the same thing at all as the sort of serious testing that games need.
TDD isn't really a 'normal' approach anywhere yet as it's still relatively new and not universally understood or accepted yet. That isn't to say that some shops don't work that way now but I'm still surprised to hear anyone using it at all at this point.

Resources